From patchwork Fri Oct 4 10:50:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171751 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l7B12nPWz9sPd for ; Fri, 4 Oct 2019 21:36:24 +1000 (AEST) Received: from localhost ([::1]:46826 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLsj-0002dc-K1 for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:36:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44210) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLB2-0006i2-30 for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLB0-0004nV-LC for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36852) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLB0-0004nH-D7; Fri, 04 Oct 2019 06:51:10 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8AC3720F0; Fri, 4 Oct 2019 10:51:09 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id B4C7B5D6B2; Fri, 4 Oct 2019 10:51:07 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 1/7] s390x/mmu: Drop debug logging from MMU code Date: Fri, 4 Oct 2019 12:50:56 +0200 Message-Id: <20191004105102.15821-2-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.71]); Fri, 04 Oct 2019 10:51:09 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let's get it out of the way to make some further refactorings easier. Personally, I've never used these debug statements at all. And if I had to debug issues, I used plain GDB instead (debug prints are just way too much noise in the MMU). We might want to introduce tracing at some point instead, so we can able selected events on demand. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand --- target/s390x/mmu_helper.c | 51 --------------------------------------- 1 file changed, 51 deletions(-) diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 7e6b0d0508..6a7ad33c4d 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -28,31 +28,6 @@ #include "hw/hw.h" #include "hw/s390x/storage-keys.h" -/* #define DEBUG_S390 */ -/* #define DEBUG_S390_PTE */ -/* #define DEBUG_S390_STDOUT */ - -#ifdef DEBUG_S390 -#ifdef DEBUG_S390_STDOUT -#define DPRINTF(fmt, ...) \ - do { fprintf(stderr, fmt, ## __VA_ARGS__); \ - if (qemu_log_separate()) qemu_log(fmt, ##__VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) \ - do { qemu_log(fmt, ## __VA_ARGS__); } while (0) -#endif -#else -#define DPRINTF(fmt, ...) \ - do { } while (0) -#endif - -#ifdef DEBUG_S390_PTE -#define PTE_DPRINTF DPRINTF -#else -#define PTE_DPRINTF(fmt, ...) \ - do { } while (0) -#endif - /* Fetch/store bits in the translation exception code: */ #define FS_READ 0x800 #define FS_WRITE 0x400 @@ -80,8 +55,6 @@ static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr, tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | 4 | asc >> 46; - DPRINTF("%s: trans_exc_code=%016" PRIx64 "\n", __func__, tec); - if (!exc) { return; } @@ -97,8 +70,6 @@ static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | asc >> 46; - DPRINTF("%s: trans_exc_code=%016" PRIx64 "\n", __func__, tec); - if (!exc) { return; } @@ -162,7 +133,6 @@ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, target_ulong *raddr, int *flags, int rw, bool exc) { if (pt_entry & PAGE_INVALID) { - DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, pt_entry); trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw, exc); return -1; } @@ -175,9 +145,6 @@ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, } *raddr = pt_entry & ASCE_ORIGIN; - - PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, pt_entry); - return 0; } @@ -197,7 +164,6 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr, if ((st_entry & SEGMENT_ENTRY_FC) && (env->cregs[0] & CR0_EDAT)) { /* Decode EDAT1 segment frame absolute address (1MB page) */ *raddr = (st_entry & 0xfffffffffff00000ULL) | (vaddr & 0xfffff); - PTE_DPRINTF("%s: SEG=0x%" PRIx64 "\n", __func__, st_entry); return 0; } @@ -205,8 +171,6 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr, origin = st_entry & SEGMENT_ENTRY_ORIGIN; offs = (vaddr & VADDR_PX) >> 9; pt_entry = ldq_phys(cs->as, origin + offs); - PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n", - __func__, origin, offs, pt_entry); return mmu_translate_pte(env, vaddr, asc, pt_entry, raddr, flags, rw, exc); } @@ -223,17 +187,12 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS }; - PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, entry); - origin = entry & REGION_ENTRY_ORIGIN; offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8; new_entry = ldq_phys(cs->as, origin + offs); - PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n", - __func__, origin, offs, new_entry); if ((new_entry & REGION_ENTRY_INV) != 0) { - DPRINTF("%s: invalid region\n", __func__); trigger_page_fault(env, vaddr, pchks[level / 4], asc, rw, exc); return -1; } @@ -252,7 +211,6 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3; if (offs < ((new_entry & REGION_ENTRY_TF) >> 6) || offs > (new_entry & REGION_ENTRY_LENGTH)) { - DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry); trigger_page_fault(env, vaddr, pchks[level / 4 - 1], asc, rw, exc); return -1; } @@ -289,8 +247,6 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, break; case ASCE_TYPE_REGION2: if (vaddr & 0xffe0000000000000ULL) { - DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 - " 0xffe0000000000000ULL\n", __func__, vaddr); trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc); return -1; } @@ -301,8 +257,6 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, break; case ASCE_TYPE_REGION3: if (vaddr & 0xfffffc0000000000ULL) { - DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 - " 0xfffffc0000000000ULL\n", __func__, vaddr); trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc); return -1; } @@ -313,8 +267,6 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, break; case ASCE_TYPE_SEGMENT: if (vaddr & 0xffffffff80000000ULL) { - DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 - " 0xffffffff80000000ULL\n", __func__, vaddr); trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc); return -1; } @@ -449,15 +401,12 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, switch (asc) { case PSW_ASC_PRIMARY: - PTE_DPRINTF("%s: asc=primary\n", __func__); asce = env->cregs[1]; break; case PSW_ASC_HOME: - PTE_DPRINTF("%s: asc=home\n", __func__); asce = env->cregs[13]; break; case PSW_ASC_SECONDARY: - PTE_DPRINTF("%s: asc=secondary\n", __func__); asce = env->cregs[7]; break; case PSW_ASC_ACCREG: From patchwork Fri Oct 4 10:50:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171729 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l6TW0JR6z9sPd for ; Fri, 4 Oct 2019 21:04:47 +1000 (AEST) Received: from localhost ([::1]:46248 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLO7-0008RS-9w for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:04:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44241) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLB3-0006kD-Rp for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLB2-0004p9-Lf for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36862) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLB2-0004oC-Dv; Fri, 04 Oct 2019 06:51:12 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A489D7F747; Fri, 4 Oct 2019 10:51:11 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id D2AE75D6B2; Fri, 4 Oct 2019 10:51:09 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce() Date: Fri, 4 Oct 2019 12:50:57 +0200 Message-Id: <20191004105102.15821-3-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.71]); Fri, 04 Oct 2019 10:51:11 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We'll reuse the ilen and tec definitions in mmu_translate soon also for all other DAT exceptions we inject. Move it to the caller, where we can later pair it up with other protection checks, like IEP. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand --- target/s390x/mmu_helper.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 6a7ad33c4d..847fb240fb 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -48,20 +48,6 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type, } } -static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr, - uint64_t asc, int rw, bool exc) -{ - uint64_t tec; - - tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | 4 | asc >> 46; - - if (!exc) { - return; - } - - trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, tec); -} - static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, uint32_t type, uint64_t asc, int rw, bool exc) { @@ -229,7 +215,6 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, int *flags, int rw, bool exc) { int level; - int r; if (asce & ASCE_REAL_SPACE) { /* direct mapping */ @@ -277,14 +262,8 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, break; } - r = mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw, - exc); - if (!r && rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) { - trigger_prot_fault(env, vaddr, asc, rw, exc); - return -1; - } - - return r; + return mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw, + exc); } static void mmu_handle_skey(target_ulong addr, int rw, int *flags) @@ -369,6 +348,10 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags) int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, target_ulong *raddr, int *flags, bool exc) { + /* Code accesses have an undefined ilc, let's use 2 bytes. */ + const int ilen = (rw == MMU_INST_FETCH) ? 2 : ILEN_AUTO; + uint64_t tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) | + (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ); uint64_t asce; int r; @@ -421,6 +404,16 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, return r; } + /* check for DAT protection */ + if (unlikely(rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE))) { + if (exc) { + /* DAT sets bit 61 only */ + tec |= 0x4; + trigger_access_exception(env, PGM_PROTECTION, ilen, tec); + } + return -1; + } + nodat: /* Convert real address -> absolute address */ *raddr = mmu_real2abs(env, *raddr); From patchwork Fri Oct 4 10:50:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171733 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l6Zp0brgz9sPd for ; Fri, 4 Oct 2019 21:09:22 +1000 (AEST) Received: from localhost ([::1]:46296 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLSZ-00042x-21 for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:09:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44272) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLB7-0006oJ-3h for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLB5-0004qs-QX for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52164) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLB5-0004py-IE; Fri, 04 Oct 2019 06:51:15 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BF9EA3067319; Fri, 4 Oct 2019 10:51:13 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id EE7AE5D6B2; Fri, 4 Oct 2019 10:51:11 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 3/7] s390x/mmu: Inject DAT exceptions from a single place Date: Fri, 4 Oct 2019 12:50:58 +0200 Message-Id: <20191004105102.15821-4-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 04 Oct 2019 10:51:13 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let's return the PGM from the translation functions on error and inject based on that. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand --- target/s390x/mmu_helper.c | 63 +++++++++++---------------------------- 1 file changed, 17 insertions(+), 46 deletions(-) diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 847fb240fb..f6ae444655 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -48,26 +48,6 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type, } } -static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, - uint32_t type, uint64_t asc, int rw, bool exc) -{ - int ilen = ILEN_AUTO; - uint64_t tec; - - tec = vaddr | (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ) | asc >> 46; - - if (!exc) { - return; - } - - /* Code accesses have an undefined ilc. */ - if (rw == MMU_INST_FETCH) { - ilen = 2; - } - - trigger_access_exception(env, type, ilen, tec); -} - /* check whether the address would be proteted by Low-Address Protection */ static bool is_low_address(uint64_t addr) { @@ -119,12 +99,10 @@ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, target_ulong *raddr, int *flags, int rw, bool exc) { if (pt_entry & PAGE_INVALID) { - trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw, exc); - return -1; + return PGM_PAGE_TRANS; } if (pt_entry & PAGE_RES0) { - trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc); - return -1; + return PGM_TRANS_SPEC; } if (pt_entry & PAGE_RO) { *flags &= ~PAGE_WRITE; @@ -179,13 +157,11 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, new_entry = ldq_phys(cs->as, origin + offs); if ((new_entry & REGION_ENTRY_INV) != 0) { - trigger_page_fault(env, vaddr, pchks[level / 4], asc, rw, exc); - return -1; + return pchks[level / 4]; } if ((new_entry & REGION_ENTRY_TYPE_MASK) != level) { - trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc); - return -1; + return PGM_TRANS_SPEC; } if (level == ASCE_TYPE_SEGMENT) { @@ -197,8 +173,7 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3; if (offs < ((new_entry & REGION_ENTRY_TF) >> 6) || offs > (new_entry & REGION_ENTRY_LENGTH)) { - trigger_page_fault(env, vaddr, pchks[level / 4 - 1], asc, rw, exc); - return -1; + return pchks[level / 4 - 1]; } if ((env->cregs[0] & CR0_EDAT) && (new_entry & REGION_ENTRY_RO)) { @@ -226,38 +201,31 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, switch (level) { case ASCE_TYPE_REGION1: if ((vaddr >> 62) > (asce & ASCE_TABLE_LENGTH)) { - trigger_page_fault(env, vaddr, PGM_REG_FIRST_TRANS, asc, rw, exc); - return -1; + return PGM_REG_FIRST_TRANS; } break; case ASCE_TYPE_REGION2: if (vaddr & 0xffe0000000000000ULL) { - trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc); - return -1; + return PGM_ASCE_TYPE; } if ((vaddr >> 51 & 3) > (asce & ASCE_TABLE_LENGTH)) { - trigger_page_fault(env, vaddr, PGM_REG_SEC_TRANS, asc, rw, exc); - return -1; + return PGM_REG_SEC_TRANS; } break; case ASCE_TYPE_REGION3: if (vaddr & 0xfffffc0000000000ULL) { - trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc); - return -1; + return PGM_ASCE_TYPE; } if ((vaddr >> 40 & 3) > (asce & ASCE_TABLE_LENGTH)) { - trigger_page_fault(env, vaddr, PGM_REG_THIRD_TRANS, asc, rw, exc); - return -1; + return PGM_REG_THIRD_TRANS; } break; case ASCE_TYPE_SEGMENT: if (vaddr & 0xffffffff80000000ULL) { - trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc); - return -1; + return PGM_ASCE_TYPE; } if ((vaddr >> 29 & 3) > (asce & ASCE_TABLE_LENGTH)) { - trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw, exc); - return -1; + return PGM_SEGMENT_TRANS; } break; } @@ -400,8 +368,11 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, /* perform the DAT translation */ r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw, exc); - if (r) { - return r; + if (unlikely(r)) { + if (exc) { + trigger_access_exception(env, r, ilen, tec); + } + return -1; } /* check for DAT protection */ From patchwork Fri Oct 4 10:50:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171750 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l76V5ByJz9sPv for ; Fri, 4 Oct 2019 21:33:22 +1000 (AEST) Received: from localhost ([::1]:46784 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLpn-0008EC-LF for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:33:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44321) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLBC-0006vZ-5w for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLBB-0004tb-08 for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:6200) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLBA-0004tH-Of; Fri, 04 Oct 2019 06:51:20 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D19E110CC1EE; Fri, 4 Oct 2019 10:51:19 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id 16C135D6B2; Fri, 4 Oct 2019 10:51:13 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 4/7] s390x/mmu: Inject PGM_ADDRESSING on bogus table addresses Date: Fri, 4 Oct 2019 12:50:59 +0200 Message-Id: <20191004105102.15821-5-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.65]); Fri, 04 Oct 2019 10:51:20 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let's document how it works and inject PGM_ADDRESSING if reading of table entries fails. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand --- target/s390x/mmu_helper.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index f6ae444655..71dee0a5d9 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -93,6 +93,27 @@ target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr) return raddr; } +static inline bool read_table_entry(CPUS390XState *env, hwaddr gaddr, + uint64_t *entry) +{ + CPUState *cs = env_cpu(env); + + /* + * According to the PoP, these table addresses are "unpredictably real + * or absolute". Also, "it is unpredictable whether the address wraps + * or an addressing exception is recognized". + * + * We treat them as absolute addresses and don't wrap them. + */ + if (unlikely(address_space_read(cs->as, gaddr, MEMTXATTRS_UNSPECIFIED, + (uint8_t *)entry, sizeof(*entry)) != + MEMTX_OK)) { + return false; + } + *entry = be64_to_cpu(*entry); + return true; +} + /* Decode page table entry (normal 4KB page) */ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t pt_entry, @@ -118,7 +139,6 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr, target_ulong *raddr, int *flags, int rw, bool exc) { - CPUState *cs = env_cpu(env); uint64_t origin, offs, pt_entry; if (st_entry & SEGMENT_ENTRY_RO) { @@ -134,7 +154,9 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr, /* Look up 4KB page entry */ origin = st_entry & SEGMENT_ENTRY_ORIGIN; offs = (vaddr & VADDR_PX) >> 9; - pt_entry = ldq_phys(cs->as, origin + offs); + if (!read_table_entry(env, origin + offs, &pt_entry)) { + return PGM_ADDRESSING; + } return mmu_translate_pte(env, vaddr, asc, pt_entry, raddr, flags, rw, exc); } @@ -144,7 +166,6 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, target_ulong *raddr, int *flags, int rw, bool exc) { - CPUState *cs = env_cpu(env); uint64_t origin, offs, new_entry; const int pchks[4] = { PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS, @@ -154,7 +175,9 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, origin = entry & REGION_ENTRY_ORIGIN; offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8; - new_entry = ldq_phys(cs->as, origin + offs); + if (!read_table_entry(env, origin + offs, &new_entry)) { + return PGM_ADDRESSING; + } if ((new_entry & REGION_ENTRY_INV) != 0) { return pchks[level / 4]; From patchwork Fri Oct 4 10:51:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171736 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l6gG4tkxz9sPl for ; Fri, 4 Oct 2019 21:13:14 +1000 (AEST) Received: from localhost ([::1]:46360 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLWK-00084B-4h for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:13:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44381) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLBL-0006z7-El for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLBK-0004yf-8C for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44024) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLBK-0004y5-0g; Fri, 04 Oct 2019 06:51:30 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3CB53302C080; Fri, 4 Oct 2019 10:51:29 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id 263F65D6B2; Fri, 4 Oct 2019 10:51:19 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte() Date: Fri, 4 Oct 2019 12:51:00 +0200 Message-Id: <20191004105102.15821-6-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 04 Oct 2019 10:51:29 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" While ASCE_ORIGIN is not wrong, it is certainly confusing. We want a page frame address. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand --- target/s390x/mmu_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 71dee0a5d9..aaf5b23513 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -129,7 +129,7 @@ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, *flags &= ~PAGE_WRITE; } - *raddr = pt_entry & ASCE_ORIGIN; + *raddr = pt_entry & TARGET_PAGE_MASK; return 0; } From patchwork Fri Oct 4 10:51:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171753 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l7H70tYLz9sPd for ; Fri, 4 Oct 2019 21:40:51 +1000 (AEST) Received: from localhost ([::1]:46922 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLx1-00060E-L1 for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:40:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44429) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLBO-000707-JP for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLBM-00050G-J1 for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43820) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLBM-0004zO-9d; Fri, 04 Oct 2019 06:51:32 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5B1C218CB903; Fri, 4 Oct 2019 10:51:31 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8703E5D6B2; Fri, 4 Oct 2019 10:51:29 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 6/7] s390x/mmu: DAT table definition overhaul Date: Fri, 4 Oct 2019 12:51:01 +0200 Message-Id: <20191004105102.15821-7-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.63]); Fri, 04 Oct 2019 10:51:31 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let's use consitent names for the region/section/page table entries and for the macros to extract relevant parts from virtual address. Make them match the definitions in the PoP - e.g., how the relevant bits are actually called. Introduce defines for all bits declared in the PoP. This will come in handy in follow-up patches. Add a note where additional information about s390x and the used definitions can be found. Acked-by: Richard Henderson Signed-off-by: David Hildenbrand Reviewed-by: Thomas Huth --- target/s390x/cpu.h | 78 +++++++++++++++++++++++++++++---------- target/s390x/mem_helper.c | 12 +++--- target/s390x/mmu_helper.c | 37 ++++++++++--------- 3 files changed, 84 insertions(+), 43 deletions(-) diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 163dae13d7..2db54884b8 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -1,6 +1,10 @@ /* * S/390 virtual CPU header * + * For details on the s390x architecture and used definitions (e.g., + * PSW, PER and DAT (Dynamic Address Translation)), please refer to + * the "z/Architecture Principles of Operations" - a.k.a. PoP. + * * Copyright (c) 2009 Ulrich Hecht * Copyright IBM Corp. 2012, 2018 * @@ -558,26 +562,60 @@ QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096); #define ASCE_TYPE_SEGMENT 0x00 /* segment table type */ #define ASCE_TABLE_LENGTH 0x03 /* region table length */ -#define REGION_ENTRY_ORIGIN (~0xfffULL) /* region/segment table origin */ -#define REGION_ENTRY_RO 0x200 /* region/segment protection bit */ -#define REGION_ENTRY_TF 0xc0 /* region/segment table offset */ -#define REGION_ENTRY_INV 0x20 /* invalid region table entry */ -#define REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ -#define REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ -#define REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ -#define REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ -#define REGION_ENTRY_LENGTH 0x03 /* region third length */ - -#define SEGMENT_ENTRY_ORIGIN (~0x7ffULL) /* segment table origin */ -#define SEGMENT_ENTRY_FC 0x400 /* format control */ -#define SEGMENT_ENTRY_RO 0x200 /* page protection bit */ -#define SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ - -#define VADDR_PX 0xff000 /* page index bits */ - -#define PAGE_RO 0x200 /* HW read-only bit */ -#define PAGE_INVALID 0x400 /* HW invalid bit */ -#define PAGE_RES0 0x800 /* bit must be zero */ +#define REGION_ENTRY_ORIGIN 0xfffffffffffff000ULL +#define REGION_ENTRY_P 0x0000000000000200ULL +#define REGION_ENTRY_TF 0x00000000000000c0ULL +#define REGION_ENTRY_I 0x0000000000000020ULL +#define REGION_ENTRY_TT 0x000000000000000cULL +#define REGION_ENTRY_TL 0x0000000000000003ULL + +#define REGION_ENTRY_TT_REGION1 0x000000000000000cULL +#define REGION_ENTRY_TT_REGION2 0x0000000000000008ULL +#define REGION_ENTRY_TT_REGION3 0x0000000000000004ULL + +#define REGION3_ENTRY_RFAA 0xffffffff80000000ULL +#define REGION3_ENTRY_AV 0x0000000000010000ULL +#define REGION3_ENTRY_ACC 0x000000000000f000ULL +#define REGION3_ENTRY_F 0x0000000000000800ULL +#define REGION3_ENTRY_FC 0x0000000000000400ULL +#define REGION3_ENTRY_IEP 0x0000000000000100ULL +#define REGION3_ENTRY_CR 0x0000000000000010ULL + +#define SEGMENT_ENTRY_ORIGIN 0xfffffffffffff800ULL +#define SEGMENT_ENTRY_SFAA 0xfffffffffff00000ULL +#define SEGMENT_ENTRY_AV 0x0000000000010000ULL +#define SEGMENT_ENTRY_ACC 0x000000000000f000ULL +#define SEGMENT_ENTRY_F 0x0000000000000800ULL +#define SEGMENT_ENTRY_FC 0x0000000000000400ULL +#define SEGMENT_ENTRY_P 0x0000000000000200ULL +#define SEGMENT_ENTRY_IEP 0x0000000000000100ULL +#define SEGMENT_ENTRY_I 0x0000000000000020ULL +#define SEGMENT_ENTRY_CS 0x0000000000000010ULL +#define SEGMENT_ENTRY_TT 0x000000000000000cULL + +#define SEGMENT_ENTRY_TT_SEGMENT 0x0000000000000000ULL + +#define PAGE_ENTRY_0 0x0000000000000800ULL +#define PAGE_ENTRY_I 0x0000000000000400ULL +#define PAGE_ENTRY_P 0x0000000000000200ULL +#define PAGE_ENTRY_IEP 0x0000000000000100ULL + +#define VADDR_REGION1_TX_MASK 0xffe0000000000000ULL +#define VADDR_REGION2_TX_MASK 0x001ffc0000000000ULL +#define VADDR_REGION3_TX_MASK 0x000003ff80000000ULL +#define VADDR_SEGMENT_TX_MASK 0x000000007ff00000ULL +#define VADDR_PAGE_TX_MASK 0x00000000000ff000ULL + +#define VADDR_REGION1_TX(vaddr) (((vaddr) & VADDR_REGION1_TX_MASK) >> 53) +#define VADDR_REGION2_TX(vaddr) (((vaddr) & VADDR_REGION2_TX_MASK) >> 42) +#define VADDR_REGION3_TX(vaddr) (((vaddr) & VADDR_REGION3_TX_MASK) >> 31) +#define VADDR_SEGMENT_TX(vaddr) (((vaddr) & VADDR_SEGMENT_TX_MASK) >> 20) +#define VADDR_PAGE_TX(vaddr) (((vaddr) & VADDR_PAGE_TX_MASK) >> 12) + +#define VADDR_REGION1_TL(vaddr) (((vaddr) & 0xc000000000000000ULL) >> 62) +#define VADDR_REGION2_TL(vaddr) (((vaddr) & 0x0018000000000000ULL) >> 51) +#define VADDR_REGION3_TL(vaddr) (((vaddr) & 0x0000030000000000ULL) >> 40) +#define VADDR_SEGMENT_TL(vaddr) (((vaddr) & 0x0000000060000000ULL) >> 29) #define SK_C (0x1 << 1) #define SK_R (0x1 << 2) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 44e535856d..08c5cc6a99 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -2252,9 +2252,9 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4) /* addresses are not wrapped in 24/31bit mode but table index is */ raddr = table + ((index + i) & 0x7ff) * sizeof(entry); entry = cpu_ldq_real_ra(env, raddr, ra); - if (!(entry & REGION_ENTRY_INV)) { + if (!(entry & REGION_ENTRY_I)) { /* we are allowed to not store if already invalid */ - entry |= REGION_ENTRY_INV; + entry |= REGION_ENTRY_I; cpu_stq_real_ra(env, raddr, entry, ra); } } @@ -2279,17 +2279,17 @@ void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr, /* Compute the page table entry address */ pte_addr = (pto & SEGMENT_ENTRY_ORIGIN); - pte_addr += (vaddr & VADDR_PX) >> 9; + pte_addr += VADDR_PAGE_TX(vaddr) * 8; /* Mark the page table entry as invalid */ pte = cpu_ldq_real_ra(env, pte_addr, ra); - pte |= PAGE_INVALID; + pte |= PAGE_ENTRY_I; cpu_stq_real_ra(env, pte_addr, pte, ra); /* XXX we exploit the fact that Linux passes the exact virtual address here - it's not obliged to! */ if (m4 & 1) { - if (vaddr & ~VADDR_PX) { + if (vaddr & ~VADDR_PAGE_TX_MASK) { tlb_flush_page(cs, page); /* XXX 31-bit hack */ tlb_flush_page(cs, page ^ 0x80000000); @@ -2298,7 +2298,7 @@ void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr, tlb_flush(cs); } } else { - if (vaddr & ~VADDR_PX) { + if (vaddr & ~VADDR_PAGE_TX_MASK) { tlb_flush_page_all_cpus_synced(cs, page); /* XXX 31-bit hack */ tlb_flush_page_all_cpus_synced(cs, page ^ 0x80000000); diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index aaf5b23513..a114fb1628 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -119,13 +119,13 @@ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t pt_entry, target_ulong *raddr, int *flags, int rw, bool exc) { - if (pt_entry & PAGE_INVALID) { + if (pt_entry & PAGE_ENTRY_I) { return PGM_PAGE_TRANS; } - if (pt_entry & PAGE_RES0) { + if (pt_entry & PAGE_ENTRY_0) { return PGM_TRANS_SPEC; } - if (pt_entry & PAGE_RO) { + if (pt_entry & PAGE_ENTRY_P) { *flags &= ~PAGE_WRITE; } @@ -141,19 +141,20 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr, { uint64_t origin, offs, pt_entry; - if (st_entry & SEGMENT_ENTRY_RO) { + if (st_entry & SEGMENT_ENTRY_P) { *flags &= ~PAGE_WRITE; } if ((st_entry & SEGMENT_ENTRY_FC) && (env->cregs[0] & CR0_EDAT)) { /* Decode EDAT1 segment frame absolute address (1MB page) */ - *raddr = (st_entry & 0xfffffffffff00000ULL) | (vaddr & 0xfffff); + *raddr = (st_entry & SEGMENT_ENTRY_SFAA) | + (vaddr & ~SEGMENT_ENTRY_SFAA); return 0; } /* Look up 4KB page entry */ origin = st_entry & SEGMENT_ENTRY_ORIGIN; - offs = (vaddr & VADDR_PX) >> 9; + offs = VADDR_PAGE_TX(vaddr) * 8; if (!read_table_entry(env, origin + offs, &pt_entry)) { return PGM_ADDRESSING; } @@ -179,11 +180,11 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, return PGM_ADDRESSING; } - if ((new_entry & REGION_ENTRY_INV) != 0) { + if (new_entry & REGION_ENTRY_I) { return pchks[level / 4]; } - if ((new_entry & REGION_ENTRY_TYPE_MASK) != level) { + if ((new_entry & REGION_ENTRY_TT) != level) { return PGM_TRANS_SPEC; } @@ -195,11 +196,11 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, /* Check region table offset and length */ offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3; if (offs < ((new_entry & REGION_ENTRY_TF) >> 6) - || offs > (new_entry & REGION_ENTRY_LENGTH)) { + || offs > (new_entry & REGION_ENTRY_TL)) { return pchks[level / 4 - 1]; } - if ((env->cregs[0] & CR0_EDAT) && (new_entry & REGION_ENTRY_RO)) { + if ((env->cregs[0] & CR0_EDAT) && (new_entry & REGION_ENTRY_P)) { *flags &= ~PAGE_WRITE; } @@ -212,6 +213,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t asce, target_ulong *raddr, int *flags, int rw, bool exc) { + const int asce_tl = asce & ASCE_TABLE_LENGTH; int level; if (asce & ASCE_REAL_SPACE) { @@ -223,31 +225,32 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, level = asce & ASCE_TYPE_MASK; switch (level) { case ASCE_TYPE_REGION1: - if ((vaddr >> 62) > (asce & ASCE_TABLE_LENGTH)) { + if (VADDR_REGION1_TL(vaddr) > asce_tl) { return PGM_REG_FIRST_TRANS; } break; case ASCE_TYPE_REGION2: - if (vaddr & 0xffe0000000000000ULL) { + if (VADDR_REGION1_TX(vaddr)) { return PGM_ASCE_TYPE; } - if ((vaddr >> 51 & 3) > (asce & ASCE_TABLE_LENGTH)) { + if (VADDR_REGION2_TL(vaddr) > asce_tl) { return PGM_REG_SEC_TRANS; } break; case ASCE_TYPE_REGION3: - if (vaddr & 0xfffffc0000000000ULL) { + if (VADDR_REGION1_TX(vaddr) || VADDR_REGION2_TX(vaddr)) { return PGM_ASCE_TYPE; } - if ((vaddr >> 40 & 3) > (asce & ASCE_TABLE_LENGTH)) { + if (VADDR_REGION3_TL(vaddr) > asce_tl) { return PGM_REG_THIRD_TRANS; } break; case ASCE_TYPE_SEGMENT: - if (vaddr & 0xffffffff80000000ULL) { + if (VADDR_REGION1_TX(vaddr) || VADDR_REGION2_TX(vaddr) || + VADDR_REGION3_TX(vaddr)) { return PGM_ASCE_TYPE; } - if ((vaddr >> 29 & 3) > (asce & ASCE_TABLE_LENGTH)) { + if (VADDR_SEGMENT_TL(vaddr) > asce_tl) { return PGM_SEGMENT_TRANS; } break; From patchwork Fri Oct 4 10:51:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1171752 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46l7Cl5ZxKz9sPd for ; Fri, 4 Oct 2019 21:37:55 +1000 (AEST) Received: from localhost ([::1]:46838 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLuB-0003C3-In for incoming@patchwork.ozlabs.org; Fri, 04 Oct 2019 07:37:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44528) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGLBb-00073S-9X for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGLBW-00056o-LB for qemu-devel@nongnu.org; Fri, 04 Oct 2019 06:51:45 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43856) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iGLBR-00052r-JB; Fri, 04 Oct 2019 06:51:39 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4838E18CB906; Fri, 4 Oct 2019 10:51:35 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id A416C5D6B2; Fri, 4 Oct 2019 10:51:31 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 7/7] s390x/mmu: Convert to non-recursive page table walk Date: Fri, 4 Oct 2019 12:51:02 +0200 Message-Id: <20191004105102.15821-8-david@redhat.com> In-Reply-To: <20191004105102.15821-1-david@redhat.com> References: <20191004105102.15821-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.63]); Fri, 04 Oct 2019 10:51:35 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Janosch Frank , David Hildenbrand , Cornelia Huck , Richard Henderson , Halil Pasic , Christian Borntraeger , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A non-recursive implementation allows to make better use of the branch predictor, avoids function calls, and makes the implementation of new features only for a subset of region table levels easier. We can now directly compare our implementation to the KVM gaccess implementation in arch/s390/kvm/gaccess.c:guest_translate(). Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand Reviewed-by: Thomas Huth --- target/s390x/mmu_helper.c | 208 ++++++++++++++++++++------------------ 1 file changed, 108 insertions(+), 100 deletions(-) diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index a114fb1628..dc33c63b1d 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -114,107 +114,16 @@ static inline bool read_table_entry(CPUS390XState *env, hwaddr gaddr, return true; } -/* Decode page table entry (normal 4KB page) */ -static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, - uint64_t asc, uint64_t pt_entry, - target_ulong *raddr, int *flags, int rw, bool exc) -{ - if (pt_entry & PAGE_ENTRY_I) { - return PGM_PAGE_TRANS; - } - if (pt_entry & PAGE_ENTRY_0) { - return PGM_TRANS_SPEC; - } - if (pt_entry & PAGE_ENTRY_P) { - *flags &= ~PAGE_WRITE; - } - - *raddr = pt_entry & TARGET_PAGE_MASK; - return 0; -} - -/* Decode segment table entry */ -static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr, - uint64_t asc, uint64_t st_entry, - target_ulong *raddr, int *flags, int rw, - bool exc) -{ - uint64_t origin, offs, pt_entry; - - if (st_entry & SEGMENT_ENTRY_P) { - *flags &= ~PAGE_WRITE; - } - - if ((st_entry & SEGMENT_ENTRY_FC) && (env->cregs[0] & CR0_EDAT)) { - /* Decode EDAT1 segment frame absolute address (1MB page) */ - *raddr = (st_entry & SEGMENT_ENTRY_SFAA) | - (vaddr & ~SEGMENT_ENTRY_SFAA); - return 0; - } - - /* Look up 4KB page entry */ - origin = st_entry & SEGMENT_ENTRY_ORIGIN; - offs = VADDR_PAGE_TX(vaddr) * 8; - if (!read_table_entry(env, origin + offs, &pt_entry)) { - return PGM_ADDRESSING; - } - return mmu_translate_pte(env, vaddr, asc, pt_entry, raddr, flags, rw, exc); -} - -/* Decode region table entries */ -static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, - uint64_t asc, uint64_t entry, int level, - target_ulong *raddr, int *flags, int rw, - bool exc) -{ - uint64_t origin, offs, new_entry; - const int pchks[4] = { - PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS, - PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS - }; - - origin = entry & REGION_ENTRY_ORIGIN; - offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8; - - if (!read_table_entry(env, origin + offs, &new_entry)) { - return PGM_ADDRESSING; - } - - if (new_entry & REGION_ENTRY_I) { - return pchks[level / 4]; - } - - if ((new_entry & REGION_ENTRY_TT) != level) { - return PGM_TRANS_SPEC; - } - - if (level == ASCE_TYPE_SEGMENT) { - return mmu_translate_segment(env, vaddr, asc, new_entry, raddr, flags, - rw, exc); - } - - /* Check region table offset and length */ - offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3; - if (offs < ((new_entry & REGION_ENTRY_TF) >> 6) - || offs > (new_entry & REGION_ENTRY_TL)) { - return pchks[level / 4 - 1]; - } - - if ((env->cregs[0] & CR0_EDAT) && (new_entry & REGION_ENTRY_P)) { - *flags &= ~PAGE_WRITE; - } - - /* yet another region */ - return mmu_translate_region(env, vaddr, asc, new_entry, level - 4, - raddr, flags, rw, exc); -} - static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t asce, target_ulong *raddr, int *flags, int rw, bool exc) { + const bool edat1 = (env->cregs[0] & CR0_EDAT) && + s390_has_feat(S390_FEAT_EDAT); const int asce_tl = asce & ASCE_TABLE_LENGTH; - int level; + const int asce_p = asce & ASCE_PRIVATE_SPACE; + hwaddr gaddr = asce & ASCE_ORIGIN; + uint64_t entry; if (asce & ASCE_REAL_SPACE) { /* direct mapping */ @@ -222,12 +131,12 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, return 0; } - level = asce & ASCE_TYPE_MASK; - switch (level) { + switch (asce & ASCE_TYPE_MASK) { case ASCE_TYPE_REGION1: if (VADDR_REGION1_TL(vaddr) > asce_tl) { return PGM_REG_FIRST_TRANS; } + gaddr += VADDR_REGION1_TX(vaddr) * 8; break; case ASCE_TYPE_REGION2: if (VADDR_REGION1_TX(vaddr)) { @@ -236,6 +145,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, if (VADDR_REGION2_TL(vaddr) > asce_tl) { return PGM_REG_SEC_TRANS; } + gaddr += VADDR_REGION2_TX(vaddr) * 8; break; case ASCE_TYPE_REGION3: if (VADDR_REGION1_TX(vaddr) || VADDR_REGION2_TX(vaddr)) { @@ -244,6 +154,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, if (VADDR_REGION3_TL(vaddr) > asce_tl) { return PGM_REG_THIRD_TRANS; } + gaddr += VADDR_REGION3_TX(vaddr) * 8; break; case ASCE_TYPE_SEGMENT: if (VADDR_REGION1_TX(vaddr) || VADDR_REGION2_TX(vaddr) || @@ -253,11 +164,108 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, if (VADDR_SEGMENT_TL(vaddr) > asce_tl) { return PGM_SEGMENT_TRANS; } + gaddr += VADDR_SEGMENT_TX(vaddr) * 8; + break; + } + + switch (asce & ASCE_TYPE_MASK) { + case ASCE_TYPE_REGION1: + if (!read_table_entry(env, gaddr, &entry)) { + return PGM_ADDRESSING; + } + if (entry & REGION_ENTRY_I) { + return PGM_REG_FIRST_TRANS; + } + if ((entry & REGION_ENTRY_TT) != REGION_ENTRY_TT_REGION1) { + return PGM_TRANS_SPEC; + } + if (VADDR_REGION2_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 || + VADDR_REGION2_TL(vaddr) > (entry & REGION_ENTRY_TL)) { + return PGM_REG_SEC_TRANS; + } + if (edat1 && (entry & REGION_ENTRY_P)) { + *flags &= ~PAGE_WRITE; + } + gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_REGION2_TX(vaddr) * 8; + /* fall through */ + case ASCE_TYPE_REGION2: + if (!read_table_entry(env, gaddr, &entry)) { + return PGM_ADDRESSING; + } + if (entry & REGION_ENTRY_I) { + return PGM_REG_SEC_TRANS; + } + if ((entry & REGION_ENTRY_TT) != REGION_ENTRY_TT_REGION2) { + return PGM_TRANS_SPEC; + } + if (VADDR_REGION3_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 || + VADDR_REGION3_TL(vaddr) > (entry & REGION_ENTRY_TL)) { + return PGM_REG_THIRD_TRANS; + } + if (edat1 && (entry & REGION_ENTRY_P)) { + *flags &= ~PAGE_WRITE; + } + gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_REGION3_TX(vaddr) * 8; + /* fall through */ + case ASCE_TYPE_REGION3: + if (!read_table_entry(env, gaddr, &entry)) { + return PGM_ADDRESSING; + } + if (entry & REGION_ENTRY_I) { + return PGM_REG_THIRD_TRANS; + } + if ((entry & REGION_ENTRY_TT) != REGION_ENTRY_TT_REGION3) { + return PGM_TRANS_SPEC; + } + if (VADDR_SEGMENT_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 || + VADDR_SEGMENT_TL(vaddr) > (entry & REGION_ENTRY_TL)) { + return PGM_SEGMENT_TRANS; + } + if (edat1 && (entry & REGION_ENTRY_P)) { + *flags &= ~PAGE_WRITE; + } + gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_SEGMENT_TX(vaddr) * 8; + /* fall through */ + case ASCE_TYPE_SEGMENT: + if (!read_table_entry(env, gaddr, &entry)) { + return PGM_ADDRESSING; + } + if (entry & SEGMENT_ENTRY_I) { + return PGM_SEGMENT_TRANS; + } + if ((entry & SEGMENT_ENTRY_TT) != SEGMENT_ENTRY_TT_SEGMENT) { + return PGM_TRANS_SPEC; + } + if ((entry & SEGMENT_ENTRY_CS) && asce_p) { + return PGM_TRANS_SPEC; + } + if (entry & SEGMENT_ENTRY_P) { + *flags &= ~PAGE_WRITE; + } + if (edat1 && (entry & SEGMENT_ENTRY_FC)) { + *raddr = (entry & SEGMENT_ENTRY_SFAA) | + (vaddr & ~SEGMENT_ENTRY_SFAA); + return 0; + } + gaddr = (entry & SEGMENT_ENTRY_ORIGIN) + VADDR_PAGE_TX(vaddr) * 8; break; } - return mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw, - exc); + if (!read_table_entry(env, gaddr, &entry)) { + return PGM_ADDRESSING; + } + if (entry & PAGE_ENTRY_I) { + return PGM_PAGE_TRANS; + } + if (entry & PAGE_ENTRY_0) { + return PGM_TRANS_SPEC; + } + if (entry & PAGE_ENTRY_P) { + *flags &= ~PAGE_WRITE; + } + + *raddr = entry & TARGET_PAGE_MASK; + return 0; } static void mmu_handle_skey(target_ulong addr, int rw, int *flags)