All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] s390x/mmu: DAT translation rewrite
@ 2019-09-25 12:52 David Hildenbrand
  2019-09-25 12:52 ` [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code David Hildenbrand
                   ` (6 more replies)
  0 siblings, 7 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

This is a split-up of:
    [PATCH-for-4.2 v1 3/9] s390x/mmu: DAT translation rewrite
Rebased on latest upstream changes. Hopefully, this makes it easier to
review.

v1 -> v2:
- Cleanup old code first, before switching to non-recursive handling
- Fix EDAT1 translation: I was missing the vaddr offset within the 1MB
  page.

David Hildenbrand (7):
  s390x/mmu: Drop debug logging from MMU code
  s390x/mmu: Move DAT protection handling out of mmu_translate_asce()
  s390x/mmu: Inject DAT exceptions from a single place
  s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses
  s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte()
  s390x/mmu: DAT table definition overhaul
  s390x/mmu: Convert to non-recursive page table walk

 target/s390x/cpu.h        |  77 +++++---
 target/s390x/mem_helper.c |  12 +-
 target/s390x/mmu_helper.c | 368 ++++++++++++++++----------------------
 3 files changed, 221 insertions(+), 236 deletions(-)

-- 
2.21.0



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  2019-09-25 13:28   ` Thomas Huth
  2019-09-25 19:11   ` Richard Henderson
  2019-09-25 12:52 ` [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce() David Hildenbrand
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

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 issue, 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.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 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:
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce()
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
  2019-09-25 12:52 ` [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  2019-09-25 17:01   ` Thomas Huth
  2019-09-25 19:14   ` Richard Henderson
  2019-09-25 12:52 ` [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place David Hildenbrand
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

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.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 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);
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
  2019-09-25 12:52 ` [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code David Hildenbrand
  2019-09-25 12:52 ` [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce() David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  2019-09-25 17:05   ` Thomas Huth
  2019-09-25 19:14   ` Richard Henderson
  2019-09-25 12:52 ` [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses David Hildenbrand
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

Let's return the PGM from the translation functions on error and inject
based on that.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 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 */
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
                   ` (2 preceding siblings ...)
  2019-09-25 12:52 ` [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  2019-09-25 17:12   ` Thomas Huth
  2019-09-25 19:25   ` Richard Henderson
  2019-09-25 12:52 ` [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte() David Hildenbrand
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

Let's document how it works and inject PGM_ADDRESSING if reading of
table entries fails.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/mmu_helper.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index f6ae444655..c9fde78614 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -93,6 +93,24 @@ target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr)
     return raddr;
 }
 
+static inline int read_table_entry(hwaddr gaddr, uint64_t *entry)
+{
+    /*
+     * 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(&address_space_memory, gaddr,
+                 MEMTXATTRS_UNSPECIFIED, (uint8_t *)entry, sizeof(*entry)) !=
+                 MEMTX_OK)) {
+        return -EFAULT;
+    }
+    *entry = be64_to_cpu(*entry);
+    return 0;
+}
+
 /* 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 +136,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 +151,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(origin + offs, &pt_entry)) {
+        return PGM_ADDRESSING;
+    }
     return mmu_translate_pte(env, vaddr, asc, pt_entry, raddr, flags, rw, exc);
 }
 
@@ -144,7 +163,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 +172,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(origin + offs, &new_entry)) {
+        return PGM_ADDRESSING;
+    }
 
     if ((new_entry & REGION_ENTRY_INV) != 0) {
         return pchks[level / 4];
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte()
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
                   ` (3 preceding siblings ...)
  2019-09-25 12:52 ` [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  2019-09-25 17:15   ` Thomas Huth
  2019-09-25 19:26   ` Richard Henderson
  2019-09-25 12:52 ` [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul David Hildenbrand
  2019-09-25 12:52 ` [PATCH v2 7/7] s390x/mmu: Convert to non-recursive page table walk David Hildenbrand
  6 siblings, 2 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

While ASCE_ORIGIN is not wrong, it is certainly confusing. We want a
page frame address.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 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 c9fde78614..20e9c13202 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -126,7 +126,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;
 }
 
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
                   ` (4 preceding siblings ...)
  2019-09-25 12:52 ` [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte() David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  2019-09-26  7:35   ` Thomas Huth
  2019-09-25 12:52 ` [PATCH v2 7/7] s390x/mmu: Convert to non-recursive page table walk David Hildenbrand
  6 siblings, 1 reply; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

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 televant bits are actually
called.

Introduce defines for all bits declared in the PoP. This will come in
handy in follow-up patches.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/cpu.h        | 77 +++++++++++++++++++++++++++++----------
 target/s390x/mem_helper.c | 12 +++---
 target/s390x/mmu_helper.c | 37 ++++++++++---------
 3 files changed, 83 insertions(+), 43 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 163dae13d7..e74a809257 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -558,26 +558,63 @@ 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          0xfffffffffff80000ULL
+#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_REGION1    0x000000000000000cULL
+#define SEGMENT_ENTRY_TT_REGION2    0x0000000000000008ULL
+#define SEGMENT_ENTRY_TT_REGION3    0x0000000000000004ULL
+#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 20e9c13202..9243f04312 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -116,13 +116,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;
     }
 
@@ -138,19 +138,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(origin + offs, &pt_entry)) {
         return PGM_ADDRESSING;
     }
@@ -176,11 +177,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;
     }
 
@@ -192,11 +193,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;
     }
 
@@ -209,6 +210,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) {
@@ -220,31 +222,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;
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 7/7] s390x/mmu: Convert to non-recursive page table walk
  2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
                   ` (5 preceding siblings ...)
  2019-09-25 12:52 ` [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul David Hildenbrand
@ 2019-09-25 12:52 ` David Hildenbrand
  6 siblings, 0 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 12:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Janosch Frank, David Hildenbrand, Cornelia Huck,
	Halil Pasic, Christian Borntraeger, qemu-s390x,
	Richard Henderson

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().

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/mmu_helper.c | 212 ++++++++++++++++++++------------------
 1 file changed, 112 insertions(+), 100 deletions(-)

diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 9243f04312..3ef40a37a7 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -111,107 +111,16 @@ static inline int read_table_entry(hwaddr gaddr, uint64_t *entry)
     return 0;
 }
 
-/* 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(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(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 */
@@ -219,12 +128,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)) {
@@ -233,6 +142,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)) {
@@ -241,6 +151,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) ||
@@ -250,11 +161,112 @@ 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;
+    default:
+        g_assert_not_reached();
+    }
+
+    switch (asce & ASCE_TYPE_MASK) {
+    case ASCE_TYPE_REGION1:
+        if (read_table_entry(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(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(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 (edat1 && (entry & REGION_ENTRY_P)) {
+            *flags &= ~PAGE_WRITE;
+        }
+        if (VADDR_SEGMENT_TL(vaddr) < (entry & REGION_ENTRY_TF) >> 6 ||
+            VADDR_SEGMENT_TL(vaddr) > (entry & REGION_ENTRY_TL)) {
+            return PGM_SEGMENT_TRANS;
+        }
+        gaddr = (entry & REGION_ENTRY_ORIGIN) + VADDR_SEGMENT_TX(vaddr) * 8;
+        /* fall through */
+    case ASCE_TYPE_SEGMENT:
+        if (read_table_entry(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;
+    default:
+        g_assert_not_reached();
+    }
+
+    if (read_table_entry(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;
     }
 
-    return mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw,
-                                exc);
+    *raddr = entry & TARGET_PAGE_MASK;
+    return 0;
 }
 
 static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code
  2019-09-25 12:52 ` [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code David Hildenbrand
@ 2019-09-25 13:28   ` Thomas Huth
  2019-09-25 19:11   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Thomas Huth @ 2019-09-25 13:28 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 25/09/2019 14.52, David Hildenbrand wrote:
> 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 issue, 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.

... and code that is disabled by default tends to bitrot anyway. Thus
this sounds like a good idea to me.

Reviewed-by: Thomas Huth <thuth@redhat.com>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce()
  2019-09-25 12:52 ` [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce() David Hildenbrand
@ 2019-09-25 17:01   ` Thomas Huth
  2019-09-25 19:14   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Thomas Huth @ 2019-09-25 17:01 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 25/09/2019 14.52, David Hildenbrand wrote:
> 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.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  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);
> 

Reviewed-by: Thomas Huth <thuth@redhat.com>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place
  2019-09-25 12:52 ` [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place David Hildenbrand
@ 2019-09-25 17:05   ` Thomas Huth
  2019-09-25 19:14   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Thomas Huth @ 2019-09-25 17:05 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 25/09/2019 14.52, David Hildenbrand wrote:
> Let's return the PGM from the translation functions on error and inject
> based on that.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/mmu_helper.c | 63 +++++++++++----------------------------
>  1 file changed, 17 insertions(+), 46 deletions(-)

Reviewed-by: Thomas Huth <thuth@redhat.com>




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses
  2019-09-25 12:52 ` [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses David Hildenbrand
@ 2019-09-25 17:12   ` Thomas Huth
  2019-09-25 19:25   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Thomas Huth @ 2019-09-25 17:12 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 25/09/2019 14.52, David Hildenbrand wrote:
> Let's document how it works and inject PGM_ADDRESSING if reading of
> table entries fails.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/mmu_helper.c | 28 ++++++++++++++++++++++++----
>  1 file changed, 24 insertions(+), 4 deletions(-)

Reviewed-by: Thomas Huth <thuth@redhat.com>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte()
  2019-09-25 12:52 ` [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte() David Hildenbrand
@ 2019-09-25 17:15   ` Thomas Huth
  2019-09-25 19:26   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Thomas Huth @ 2019-09-25 17:15 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 25/09/2019 14.52, David Hildenbrand wrote:
> While ASCE_ORIGIN is not wrong, it is certainly confusing. We want a
> page frame address.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  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 c9fde78614..20e9c13202 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -126,7 +126,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;
>  }

Reviewed-by: Thomas Huth <thuth@redhat.com>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code
  2019-09-25 12:52 ` [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code David Hildenbrand
  2019-09-25 13:28   ` Thomas Huth
@ 2019-09-25 19:11   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2019-09-25 19:11 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Thomas Huth, Janosch Frank, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, qemu-s390x, Richard Henderson

On 9/25/19 5:52 AM, David Hildenbrand wrote:
> 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 issue, 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.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/mmu_helper.c | 51 ---------------------------------------
>  1 file changed, 51 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce()
  2019-09-25 12:52 ` [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce() David Hildenbrand
  2019-09-25 17:01   ` Thomas Huth
@ 2019-09-25 19:14   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2019-09-25 19:14 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Thomas Huth, Janosch Frank, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, qemu-s390x, Richard Henderson

On 9/25/19 5:52 AM, David Hildenbrand wrote:
> 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.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/mmu_helper.c | 39 ++++++++++++++++-----------------------
>  1 file changed, 16 insertions(+), 23 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place
  2019-09-25 12:52 ` [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place David Hildenbrand
  2019-09-25 17:05   ` Thomas Huth
@ 2019-09-25 19:14   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2019-09-25 19:14 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Thomas Huth, Janosch Frank, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, qemu-s390x, Richard Henderson

On 9/25/19 5:52 AM, David Hildenbrand wrote:
> Let's return the PGM from the translation functions on error and inject
> based on that.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/mmu_helper.c | 63 +++++++++++----------------------------
>  1 file changed, 17 insertions(+), 46 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses
  2019-09-25 12:52 ` [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses David Hildenbrand
  2019-09-25 17:12   ` Thomas Huth
@ 2019-09-25 19:25   ` Richard Henderson
  2019-09-25 19:36     ` David Hildenbrand
  1 sibling, 1 reply; 24+ messages in thread
From: Richard Henderson @ 2019-09-25 19:25 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Thomas Huth, Janosch Frank, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, qemu-s390x, Richard Henderson

On 9/25/19 5:52 AM, David Hildenbrand wrote:
> +static inline int read_table_entry(hwaddr gaddr, uint64_t *entry)
> +{
> +    /*
> +     * 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(&address_space_memory, gaddr,
> +                 MEMTXATTRS_UNSPECIFIED, (uint8_t *)entry, sizeof(*entry)) !=
> +                 MEMTX_OK)) {
> +        return -EFAULT;
> +    }
> +    *entry = be64_to_cpu(*entry);
> +    return 0;
> +}

Maybe I've been away from the kernel too long, but I don't find returning
-EFAULT helpful.  I would return true/false for success/failure so that...


> +    if (read_table_entry(origin + offs, &pt_entry)) {
> +        return PGM_ADDRESSING;
> +    }

... this gets written

    if (!read_table_entry(...)) {
        return PGM_ADDRESSING;
    }

This statement, to me, reads "If we did not read_table_entry, return an
addressing exception."

If you *really* want to return non-zero on failure, I would prefer returning
PGM_ADDRESSING instead of the out-of-context -EFAULT.

> -    new_entry = ldq_phys(cs->as, origin + offs);
> +    if (read_table_entry(origin + offs, &new_entry)) {

Do you really want to replace cs->as with address_space_memory?


r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte()
  2019-09-25 12:52 ` [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte() David Hildenbrand
  2019-09-25 17:15   ` Thomas Huth
@ 2019-09-25 19:26   ` Richard Henderson
  1 sibling, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2019-09-25 19:26 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Thomas Huth, Janosch Frank, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, qemu-s390x, Richard Henderson

On 9/25/19 5:52 AM, David Hildenbrand wrote:
> While ASCE_ORIGIN is not wrong, it is certainly confusing. We want a
> page frame address.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/mmu_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses
  2019-09-25 19:25   ` Richard Henderson
@ 2019-09-25 19:36     ` David Hildenbrand
  0 siblings, 0 replies; 24+ messages in thread
From: David Hildenbrand @ 2019-09-25 19:36 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Thomas Huth, Janosch Frank, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, qemu-s390x, Richard Henderson

On 25.09.19 21:25, Richard Henderson wrote:
> On 9/25/19 5:52 AM, David Hildenbrand wrote:
>> +static inline int read_table_entry(hwaddr gaddr, uint64_t *entry)
>> +{
>> +    /*
>> +     * 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(&address_space_memory, gaddr,
>> +                 MEMTXATTRS_UNSPECIFIED, (uint8_t *)entry, sizeof(*entry)) !=
>> +                 MEMTX_OK)) {
>> +        return -EFAULT;
>> +    }
>> +    *entry = be64_to_cpu(*entry);
>> +    return 0;
>> +}
> 
> Maybe I've been away from the kernel too long, but I don't find returning
> -EFAULT helpful.  I would return true/false for success/failure so that...
> 
> 
>> +    if (read_table_entry(origin + offs, &pt_entry)) {
>> +        return PGM_ADDRESSING;
>> +    }
> 
> ... this gets written
> 
>     if (!read_table_entry(...)) {
>         return PGM_ADDRESSING;
>     }
> 
> This statement, to me, reads "If we did not read_table_entry, return an
> addressing exception."
> 
> If you *really* want to return non-zero on failure, I would prefer returning
> PGM_ADDRESSING instead of the out-of-context -EFAULT.

I'll go for your suggestion with a bool!

> 
>> -    new_entry = ldq_phys(cs->as, origin + offs);
>> +    if (read_table_entry(origin + offs, &new_entry)) {
> 
> Do you really want to replace cs->as with address_space_memory?
> 

I guess it shouldn't make a difference (unless I am missing something),
but I can just keep using cs->as.

Thanks!

> 
> r~
> 


-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
  2019-09-25 12:52 ` [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul David Hildenbrand
@ 2019-09-26  7:35   ` Thomas Huth
  2019-09-26  7:38     ` David Hildenbrand
  0 siblings, 1 reply; 24+ messages in thread
From: Thomas Huth @ 2019-09-26  7:35 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 25/09/2019 14.52, David Hildenbrand wrote:
> 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 televant bits are actually

s/televant/relevant/

> called.
> 
> Introduce defines for all bits declared in the PoP. This will come in
> handy in follow-up patches.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/cpu.h        | 77 +++++++++++++++++++++++++++++----------
>  target/s390x/mem_helper.c | 12 +++---
>  target/s390x/mmu_helper.c | 37 ++++++++++---------
>  3 files changed, 83 insertions(+), 43 deletions(-)
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index 163dae13d7..e74a809257 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -558,26 +558,63 @@ 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

Any chance that you could keep the comments after the definitions? I
think they are useful for people who are not 100% familiar with the DAT
on s390x.

Anyway, thanks for splitting this up into a separate patch, it really
gets much more readable this way.

 Thomas


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
  2019-09-26  7:35   ` Thomas Huth
@ 2019-09-26  7:38     ` David Hildenbrand
  2019-09-26  7:52       ` Thomas Huth
  0 siblings, 1 reply; 24+ messages in thread
From: David Hildenbrand @ 2019-09-26  7:38 UTC (permalink / raw)
  To: Thomas Huth, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 26.09.19 09:35, Thomas Huth wrote:
> On 25/09/2019 14.52, David Hildenbrand wrote:
>> 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 televant bits are actually
> 
> s/televant/relevant/
> 
>> called.
>>
>> Introduce defines for all bits declared in the PoP. This will come in
>> handy in follow-up patches.
>>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
>>  target/s390x/cpu.h        | 77 +++++++++++++++++++++++++++++----------
>>  target/s390x/mem_helper.c | 12 +++---
>>  target/s390x/mmu_helper.c | 37 ++++++++++---------
>>  3 files changed, 83 insertions(+), 43 deletions(-)
>>
>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>> index 163dae13d7..e74a809257 100644
>> --- a/target/s390x/cpu.h
>> +++ b/target/s390x/cpu.h
>> @@ -558,26 +558,63 @@ 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
> 
> Any chance that you could keep the comments after the definitions? I
> think they are useful for people who are not 100% familiar with the DAT
> on s390x.

I thought about that, but do we expect people that don't have a clue
about s390x DAT and don't compare the code against the PoP to understand
our DAT translation just by comments on defines?

> 
> Anyway, thanks for splitting this up into a separate patch, it really
> gets much more readable this way.

Yeah, it certainly was worth it, thanks!

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
  2019-09-26  7:38     ` David Hildenbrand
@ 2019-09-26  7:52       ` Thomas Huth
  2019-09-26  7:59         ` David Hildenbrand
  0 siblings, 1 reply; 24+ messages in thread
From: Thomas Huth @ 2019-09-26  7:52 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 26/09/2019 09.38, David Hildenbrand wrote:
> On 26.09.19 09:35, Thomas Huth wrote:
>> On 25/09/2019 14.52, David Hildenbrand wrote:
>>> 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 televant bits are actually
>>
>> s/televant/relevant/
>>
>>> called.
>>>
>>> Introduce defines for all bits declared in the PoP. This will come in
>>> handy in follow-up patches.
>>>
>>> Signed-off-by: David Hildenbrand <david@redhat.com>
>>> ---
>>>  target/s390x/cpu.h        | 77 +++++++++++++++++++++++++++++----------
>>>  target/s390x/mem_helper.c | 12 +++---
>>>  target/s390x/mmu_helper.c | 37 ++++++++++---------
>>>  3 files changed, 83 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>> index 163dae13d7..e74a809257 100644
>>> --- a/target/s390x/cpu.h
>>> +++ b/target/s390x/cpu.h
>>> @@ -558,26 +558,63 @@ 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
>>
>> Any chance that you could keep the comments after the definitions? I
>> think they are useful for people who are not 100% familiar with the DAT
>> on s390x.
> 
> I thought about that, but do we expect people that don't have a clue
> about s390x DAT and don't compare the code against the PoP to understand
> our DAT translation just by comments on defines?

I'm not sure that everybody is aware of the PoP ... maybe you could just
put a comment in front of the block a la:

/*
 * For details on the following definitions, see the "Dynamic Address
 * Translation" section in chapter 3 of the "z/Architecture Principles
 * of Operations - SA22-7832-11"
 */

?

 Thomas


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
  2019-09-26  7:52       ` Thomas Huth
@ 2019-09-26  7:59         ` David Hildenbrand
  2019-09-26  8:07           ` Thomas Huth
  0 siblings, 1 reply; 24+ messages in thread
From: David Hildenbrand @ 2019-09-26  7:59 UTC (permalink / raw)
  To: Thomas Huth, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 26.09.19 09:52, Thomas Huth wrote:
> On 26/09/2019 09.38, David Hildenbrand wrote:
>> On 26.09.19 09:35, Thomas Huth wrote:
>>> On 25/09/2019 14.52, David Hildenbrand wrote:
>>>> 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 televant bits are actually
>>>
>>> s/televant/relevant/
>>>
>>>> called.
>>>>
>>>> Introduce defines for all bits declared in the PoP. This will come in
>>>> handy in follow-up patches.
>>>>
>>>> Signed-off-by: David Hildenbrand <david@redhat.com>
>>>> ---
>>>>  target/s390x/cpu.h        | 77 +++++++++++++++++++++++++++++----------
>>>>  target/s390x/mem_helper.c | 12 +++---
>>>>  target/s390x/mmu_helper.c | 37 ++++++++++---------
>>>>  3 files changed, 83 insertions(+), 43 deletions(-)
>>>>
>>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>>> index 163dae13d7..e74a809257 100644
>>>> --- a/target/s390x/cpu.h
>>>> +++ b/target/s390x/cpu.h
>>>> @@ -558,26 +558,63 @@ 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
>>>
>>> Any chance that you could keep the comments after the definitions? I
>>> think they are useful for people who are not 100% familiar with the DAT
>>> on s390x.
>>
>> I thought about that, but do we expect people that don't have a clue
>> about s390x DAT and don't compare the code against the PoP to understand
>> our DAT translation just by comments on defines?
> 
> I'm not sure that everybody is aware of the PoP ... maybe you could just
> put a comment in front of the block a la:
> 
> /*
>  * For details on the following definitions, see the "Dynamic Address
>  * Translation" section in chapter 3 of the "z/Architecture Principles
>  * of Operations - SA22-7832-11"
>  */
> 

We also have the PSW/PGM/PER definitions in there without such a note.
What about something generic as:

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index e74a809257..690b94c8ea 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
  *

-- 

Thanks,

David / dhildenb


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
  2019-09-26  7:59         ` David Hildenbrand
@ 2019-09-26  8:07           ` Thomas Huth
  0 siblings, 0 replies; 24+ messages in thread
From: Thomas Huth @ 2019-09-26  8:07 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Janosch Frank, Cornelia Huck, Halil Pasic, Christian Borntraeger,
	qemu-s390x, Richard Henderson

On 26/09/2019 09.59, David Hildenbrand wrote:
> On 26.09.19 09:52, Thomas Huth wrote:
>> On 26/09/2019 09.38, David Hildenbrand wrote:
>>> On 26.09.19 09:35, Thomas Huth wrote:
>>>> On 25/09/2019 14.52, David Hildenbrand wrote:
>>>>> 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 televant bits are actually
>>>>
>>>> s/televant/relevant/
>>>>
>>>>> called.
>>>>>
>>>>> Introduce defines for all bits declared in the PoP. This will come in
>>>>> handy in follow-up patches.
>>>>>
>>>>> Signed-off-by: David Hildenbrand <david@redhat.com>
>>>>> ---
>>>>>  target/s390x/cpu.h        | 77 +++++++++++++++++++++++++++++----------
>>>>>  target/s390x/mem_helper.c | 12 +++---
>>>>>  target/s390x/mmu_helper.c | 37 ++++++++++---------
>>>>>  3 files changed, 83 insertions(+), 43 deletions(-)
>>>>>
>>>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>>>> index 163dae13d7..e74a809257 100644
>>>>> --- a/target/s390x/cpu.h
>>>>> +++ b/target/s390x/cpu.h
>>>>> @@ -558,26 +558,63 @@ 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
>>>>
>>>> Any chance that you could keep the comments after the definitions? I
>>>> think they are useful for people who are not 100% familiar with the DAT
>>>> on s390x.
>>>
>>> I thought about that, but do we expect people that don't have a clue
>>> about s390x DAT and don't compare the code against the PoP to understand
>>> our DAT translation just by comments on defines?
>>
>> I'm not sure that everybody is aware of the PoP ... maybe you could just
>> put a comment in front of the block a la:
>>
>> /*
>>  * For details on the following definitions, see the "Dynamic Address
>>  * Translation" section in chapter 3 of the "z/Architecture Principles
>>  * of Operations - SA22-7832-11"
>>  */
>>
> 
> We also have the PSW/PGM/PER definitions in there without such a note.
> What about something generic as:
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index e74a809257..690b94c8ea 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.
> + *

Fine for me, too.

 Thomas



^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2019-09-26  8:08 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-25 12:52 [PATCH v2 0/7] s390x/mmu: DAT translation rewrite David Hildenbrand
2019-09-25 12:52 ` [PATCH v2 1/7] s390x/mmu: Drop debug logging from MMU code David Hildenbrand
2019-09-25 13:28   ` Thomas Huth
2019-09-25 19:11   ` Richard Henderson
2019-09-25 12:52 ` [PATCH v2 2/7] s390x/mmu: Move DAT protection handling out of mmu_translate_asce() David Hildenbrand
2019-09-25 17:01   ` Thomas Huth
2019-09-25 19:14   ` Richard Henderson
2019-09-25 12:52 ` [PATCH v2 3/7] s390x/mmu: Inject DAT exceptions from a single place David Hildenbrand
2019-09-25 17:05   ` Thomas Huth
2019-09-25 19:14   ` Richard Henderson
2019-09-25 12:52 ` [PATCH v2 4/7] s390x/mmu: Inject PGM_ADDRESSING on boguous table addresses David Hildenbrand
2019-09-25 17:12   ` Thomas Huth
2019-09-25 19:25   ` Richard Henderson
2019-09-25 19:36     ` David Hildenbrand
2019-09-25 12:52 ` [PATCH v2 5/7] s390x/mmu: Use TARGET_PAGE_MASK in mmu_translate_pte() David Hildenbrand
2019-09-25 17:15   ` Thomas Huth
2019-09-25 19:26   ` Richard Henderson
2019-09-25 12:52 ` [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul David Hildenbrand
2019-09-26  7:35   ` Thomas Huth
2019-09-26  7:38     ` David Hildenbrand
2019-09-26  7:52       ` Thomas Huth
2019-09-26  7:59         ` David Hildenbrand
2019-09-26  8:07           ` Thomas Huth
2019-09-25 12:52 ` [PATCH v2 7/7] s390x/mmu: Convert to non-recursive page table walk David Hildenbrand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.