From: David Hildenbrand <david@redhat.com>
To: qemu-devel@nongnu.org
Cc: Thomas Huth <thuth@redhat.com>,
Janosch Frank <frankja@linux.ibm.com>,
David Hildenbrand <david@redhat.com>,
Cornelia Huck <cohuck@redhat.com>,
Halil Pasic <pasic@linux.ibm.com>,
Christian Borntraeger <borntraeger@de.ibm.com>,
qemu-s390x@nongnu.org, Richard Henderson <rth@twiddle.net>
Subject: [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul
Date: Wed, 25 Sep 2019 14:52:35 +0200 [thread overview]
Message-ID: <20190925125236.4043-7-david@redhat.com> (raw)
In-Reply-To: <20190925125236.4043-1-david@redhat.com>
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
next prev parent reply other threads:[~2019-09-25 13:20 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` David Hildenbrand [this message]
2019-09-26 7:35 ` [PATCH v2 6/7] s390x/mmu: DAT table definition overhaul 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190925125236.4043-7-david@redhat.com \
--to=david@redhat.com \
--cc=borntraeger@de.ibm.com \
--cc=cohuck@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=pasic@linux.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=rth@twiddle.net \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.