All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org
Subject: [PATCH v3 30/42] target/arm: Add ptw_idx argument to S1_ptw_translate
Date: Sat,  1 Oct 2022 09:23:06 -0700	[thread overview]
Message-ID: <20221001162318.153420-31-richard.henderson@linaro.org> (raw)
In-Reply-To: <20221001162318.153420-1-richard.henderson@linaro.org>

Hoist the computation of the mmu_idx for the ptw up to
get_phys_addr_with_secure_debug and get_phys_addr_twostage.
This removes the duplicate check for stage2 disabled
from the middle of the walk, performing it only once.

Pass ptw_idx through get_phys_addr_{v5,v6,lpae} and arm_{ldl,ldq}_ptw.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/ptw.c | 104 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 71 insertions(+), 33 deletions(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 445382ab03..7a77bea2c7 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -17,7 +17,8 @@
 
 static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                               bool is_secure, bool s1_is_el0, bool debug,
+                               ARMMMUIdx ptw_idx, bool is_secure,
+                               bool s1_is_el0, bool debug,
                                GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
     __attribute__((nonnull));
 
@@ -220,21 +221,16 @@ static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
 }
 
 /* Translate a S1 pagetable walk through S2 if needed.  */
-static bool S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, hwaddr addr,
+static bool S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
+                             ARMMMUIdx s2_mmu_idx, hwaddr addr,
                              bool *is_secure_ptr, void **hphys, hwaddr *gphys,
                              bool debug, ARMMMUFaultInfo *fi)
 {
     bool is_secure = *is_secure_ptr;
-    ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
-    bool s2_phys = false;
     uint8_t pte_attrs;
-    bool pte_secure;
+    bool s2_phys, pte_secure;
 
-    if (!arm_mmu_idx_is_stage1_of_2(mmu_idx)
-        || regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
-        s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
-        s2_phys = true;
-    }
+    s2_phys = s2_mmu_idx == ARMMMUIdx_Phys_S || s2_mmu_idx == ARMMMUIdx_Phys_NS;
 
     if (unlikely(debug)) {
         /*
@@ -247,8 +243,12 @@ static bool S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, hwaddr addr,
             pte_secure = is_secure;
         } else {
             GetPhysAddrResult s2 = { };
+            ARMMMUIdx phys_idx = (is_secure ? ARMMMUIdx_Phys_S
+                                  : ARMMMUIdx_Phys_NS);
+
             if (!get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
-                                    is_secure, false, debug, &s2, fi)) {
+                                    phys_idx, is_secure, false, debug,
+                                    &s2, fi)) {
                 goto fail;
             }
             *gphys = s2.f.phys_addr;
@@ -310,7 +310,8 @@ static bool S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, hwaddr addr,
 
 /* All loads done in the course of a page table walk go through here. */
 static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
-                            ARMMMUIdx mmu_idx, bool debug, ARMMMUFaultInfo *fi)
+                            ARMMMUIdx mmu_idx, ARMMMUIdx ptw_idx,
+                            bool debug, ARMMMUFaultInfo *fi)
 {
     CPUState *cs = env_cpu(env);
     void *hphys;
@@ -318,7 +319,7 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
     uint32_t data;
     bool be;
 
-    if (!S1_ptw_translate(env, mmu_idx, addr, &is_secure,
+    if (!S1_ptw_translate(env, mmu_idx, ptw_idx, addr, &is_secure,
                           &hphys, &gphys, debug, fi)) {
         /* Failure. */
         assert(fi->s1ptw);
@@ -354,7 +355,8 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
 }
 
 static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
-                            ARMMMUIdx mmu_idx, bool debug, ARMMMUFaultInfo *fi)
+                            ARMMMUIdx mmu_idx, ARMMMUIdx ptw_idx,
+                            bool debug, ARMMMUFaultInfo *fi)
 {
     CPUState *cs = env_cpu(env);
     void *hphys;
@@ -362,7 +364,7 @@ static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
     uint64_t data;
     bool be;
 
-    if (!S1_ptw_translate(env, mmu_idx, addr, &is_secure,
+    if (!S1_ptw_translate(env, mmu_idx, ptw_idx, addr, &is_secure,
                           &hphys, &gphys, debug, fi)) {
         /* Failure. */
         assert(fi->s1ptw);
@@ -507,7 +509,7 @@ static int simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
 
 static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                             bool is_secure, bool debug,
+                             ARMMMUIdx ptw_idx, bool is_secure, bool debug,
                              GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
 {
     int level = 1;
@@ -527,7 +529,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
         fi->type = ARMFault_Translation;
         goto do_fault;
     }
-    desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, debug, fi);
+    desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi);
     if (fi->type != ARMFault_None) {
         goto do_fault;
     }
@@ -565,7 +567,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
             /* Fine pagetable.  */
             table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
         }
-        desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, debug, fi);
+        desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi);
         if (fi->type != ARMFault_None) {
             goto do_fault;
         }
@@ -626,7 +628,7 @@ do_fault:
 
 static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                             bool is_secure, bool debug,
+                             ARMMMUIdx ptw_idx, bool is_secure, bool debug,
                              GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
 {
     ARMCPU *cpu = env_archcpu(env);
@@ -650,7 +652,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
         fi->type = ARMFault_Translation;
         goto do_fault;
     }
-    desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, debug, fi);
+    desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi);
     if (fi->type != ARMFault_None) {
         goto do_fault;
     }
@@ -703,7 +705,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
         ns = extract32(desc, 3, 1);
         /* Lookup l2 entry.  */
         table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
-        desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, debug, fi);
+        desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi);
         if (fi->type != ARMFault_None) {
             goto do_fault;
         }
@@ -1058,7 +1060,8 @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
  */
 static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                               bool is_secure, bool s1_is_el0, bool debug,
+                               ARMMMUIdx ptw_idx, bool is_secure,
+                               bool s1_is_el0, bool debug,
                                GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
 {
     ARMCPU *cpu = env_archcpu(env);
@@ -1284,7 +1287,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
         descaddr |= (address >> (stride * (4 - level))) & indexmask;
         descaddr &= ~7ULL;
         nstable = extract32(tableattrs, 4, 1);
-        descriptor = arm_ldq_ptw(env, descaddr, !nstable, mmu_idx, debug, fi);
+        descriptor = arm_ldq_ptw(env, descaddr, !nstable, mmu_idx,
+                                 ptw_idx, debug, fi);
         if (fi->type != ARMFault_None) {
             goto do_fault;
         }
@@ -2446,7 +2450,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, target_ulong address,
     int s1_prot;
     bool ret, ipa_secure, s2walk_secure;
     ARMCacheAttrs cacheattrs1;
-    ARMMMUIdx s2_mmu_idx;
+    ARMMMUIdx s2_mmu_idx, s2_ptw_idx;
     bool is_el0;
     uint64_t hcr;
 
@@ -2471,7 +2475,13 @@ static bool get_phys_addr_twostage(CPUARMState *env, target_ulong address,
         s2walk_secure = false;
     }
 
-    s2_mmu_idx = (s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
+    if (s2walk_secure) {
+        s2_mmu_idx = ARMMMUIdx_Stage2_S;
+        s2_ptw_idx = ARMMMUIdx_Phys_S;
+    } else {
+        s2_mmu_idx = ARMMMUIdx_Stage2;
+        s2_ptw_idx = ARMMMUIdx_Phys_NS;
+    }
     is_el0 = s1_mmu_idx == ARMMMUIdx_Stage1_E0;
 
     /*
@@ -2482,7 +2492,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, target_ulong address,
     cacheattrs1 = result->cacheattrs;
     memset(result, 0, sizeof(*result));
 
-    ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
+    ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, s2_ptw_idx,
                              s2walk_secure, is_el0, debug, result, fi);
     fi->s2addr = ipa;
 
@@ -2534,9 +2544,32 @@ static bool get_phys_addr_with_secure_debug(CPUARMState *env,
                                             GetPhysAddrResult *result,
                                             ARMMMUFaultInfo *fi)
 {
-    ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
+    ARMMMUIdx s1_mmu_idx, ptw_idx;
 
-    if (mmu_idx != s1_mmu_idx) {
+    switch (mmu_idx) {
+    case ARMMMUIdx_Phys_S:
+    case ARMMMUIdx_Phys_NS:
+    do_disabled:
+        /* Checking Phys early avoids special casing later vs regime_el. */
+        return get_phys_addr_disabled(env, address, access_type, mmu_idx,
+                                      is_secure, result, fi);
+
+    case ARMMMUIdx_Stage1_E0:
+    case ARMMMUIdx_Stage1_E1:
+    case ARMMMUIdx_Stage1_E1_PAN:
+        /* First stage lookup uses second stage for ptw. */
+        ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
+        break;
+
+    case ARMMMUIdx_E10_0:
+        s1_mmu_idx = ARMMMUIdx_Stage1_E0;
+        goto do_twostage;
+    case ARMMMUIdx_E10_1:
+        s1_mmu_idx = ARMMMUIdx_Stage1_E1;
+        goto do_twostage;
+    case ARMMMUIdx_E10_1_PAN:
+        s1_mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
+    do_twostage:
         /*
          * Call ourselves recursively to do the stage 1 and then stage 2
          * translations if mmu_idx is a two-stage regime.
@@ -2548,6 +2581,12 @@ static bool get_phys_addr_with_secure_debug(CPUARMState *env,
         }
         /* For non-EL2 CPUs a stage1+stage2 translation is just stage 1. */
         mmu_idx = s1_mmu_idx;
+        /* fall through */
+
+    default:
+        /* Single stage and second stage uses physical for ptw. */
+        ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
+        break;
     }
 
     /*
@@ -2604,18 +2643,17 @@ static bool get_phys_addr_with_secure_debug(CPUARMState *env,
     /* Definitely a real MMU, not an MPU */
 
     if (regime_translation_disabled(env, mmu_idx, is_secure)) {
-        return get_phys_addr_disabled(env, address, access_type, mmu_idx,
-                                      is_secure, result, fi);
+        goto do_disabled;
     }
     if (regime_using_lpae_format(env, mmu_idx)) {
         return get_phys_addr_lpae(env, address, access_type, mmu_idx,
-                                  is_secure, false, debug, result, fi);
+                                  ptw_idx, is_secure, false, debug, result, fi);
     } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
         return get_phys_addr_v6(env, address, access_type, mmu_idx,
-                                is_secure, debug, result, fi);
+                                ptw_idx, is_secure, debug, result, fi);
     } else {
         return get_phys_addr_v5(env, address, access_type, mmu_idx,
-                                is_secure, debug, result, fi);
+                                ptw_idx, is_secure, debug, result, fi);
     }
 }
 
-- 
2.34.1



  parent reply	other threads:[~2022-10-01 16:59 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-01 16:22 [PATCH v3 00/42] target/arm: Implement FEAT_HAFDBS Richard Henderson
2022-10-01 16:22 ` [PATCH v3 01/42] target/arm: Split s2walk_secure from ipa_secure in get_phys_addr Richard Henderson
2022-10-06 14:27   ` Peter Maydell
2022-10-06 15:10     ` Richard Henderson
2022-10-06 15:22       ` Peter Maydell
2022-10-06 18:20         ` Richard Henderson
2022-10-06 18:55           ` Peter Maydell
2022-10-06 20:58             ` Richard Henderson
2022-10-07 13:50               ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 02/42] target/arm: Add is_secure parameter to get_phys_addr_lpae Richard Henderson
2022-10-01 16:22 ` [PATCH v3 03/42] target/arm: Fix S2 disabled check in S1_ptw_translate Richard Henderson
2022-10-06 14:28   ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 04/42] target/arm: Add is_secure parameter to regime_translation_disabled Richard Henderson
2022-10-01 16:22 ` [PATCH v3 05/42] target/arm: Split out get_phys_addr_with_secure Richard Henderson
2022-10-01 16:22 ` [PATCH v3 06/42] target/arm: Add is_secure parameter to v7m_read_half_insn Richard Henderson
2022-10-01 16:22 ` [PATCH v3 07/42] target/arm: Add TBFLAG_M32.SECURE Richard Henderson
2022-10-01 16:22 ` [PATCH v3 08/42] target/arm: Merge regime_is_secure into get_phys_addr Richard Henderson
2022-10-01 16:22 ` [PATCH v3 09/42] target/arm: Add is_secure parameter to do_ats_write Richard Henderson
2022-10-01 16:22 ` [PATCH v3 10/42] target/arm: Fold secure and non-secure a-profile mmu indexes Richard Henderson
2022-10-01 16:22 ` [PATCH v3 11/42] target/arm: Reorg regime_translation_disabled Richard Henderson
2022-10-01 16:22 ` [PATCH v3 12/42] target/arm: Drop secure check for HCR.TGE vs SCTLR_EL1.M Richard Henderson
2022-10-01 16:22 ` [PATCH v3 13/42] target/arm: Introduce arm_hcr_el2_eff_secstate Richard Henderson
2022-10-01 16:22 ` [PATCH v3 14/42] target/arm: Hoist read of *is_secure in S1_ptw_translate Richard Henderson
2022-10-01 16:22 ` [PATCH v3 15/42] target/arm: Remove env argument from combined_attrs_fwb Richard Henderson
2022-10-06 14:30   ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 16/42] target/arm: Pass HCR to attribute subroutines Richard Henderson
2022-10-01 16:22 ` [PATCH v3 17/42] target/arm: Fix ATS12NSO* from S PL1 Richard Henderson
2022-10-01 16:22 ` [PATCH v3 18/42] target/arm: Split out get_phys_addr_disabled Richard Henderson
2022-10-01 16:22 ` [PATCH v3 19/42] target/arm: Fix cacheattr in get_phys_addr_disabled Richard Henderson
2022-10-06 14:33   ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 20/42] target/arm: Use tlb_set_page_full Richard Henderson
2022-10-06 14:36   ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 21/42] target/arm: Enable TARGET_PAGE_ENTRY_EXTRA Richard Henderson
2022-10-06 14:44   ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 22/42] target/arm: Use probe_access_full for MTE Richard Henderson
2022-10-06 14:52   ` Peter Maydell
2022-10-01 16:22 ` [PATCH v3 23/42] target/arm: Use probe_access_full for BTI Richard Henderson
2022-10-06 14:57   ` Peter Maydell
2022-10-06 18:53     ` Richard Henderson
2022-10-01 16:23 ` [PATCH v3 24/42] target/arm: Add ARMMMUIdx_Phys_{S,NS} Richard Henderson
2022-10-06 15:29   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 25/42] target/arm: Move ARMMMUIdx_Stage2 to a real tlb mmu_idx Richard Henderson
2022-10-06 15:46   ` Peter Maydell
2022-10-06 19:21     ` Richard Henderson
2022-10-01 16:23 ` [PATCH v3 26/42] target/arm: Plumb debug into S1_ptw_translate Richard Henderson
2022-10-06 15:54   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 27/42] target/arm: Use softmmu tlbs for page table walking Richard Henderson
2022-10-07  9:01   ` Peter Maydell
2022-10-07 15:27     ` Richard Henderson
2022-10-07 16:08       ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 28/42] target/arm: Split out get_phys_addr_twostage Richard Henderson
2022-10-06 16:00   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 29/42] target/arm: Use bool consistently for get_phys_addr subroutines Richard Henderson
2022-10-06 16:01   ` Peter Maydell
2022-10-01 16:23 ` Richard Henderson [this message]
2022-10-07  9:19   ` [PATCH v3 30/42] target/arm: Add ptw_idx argument to S1_ptw_translate Peter Maydell
2022-10-07 15:34     ` Richard Henderson
2022-10-01 16:23 ` [PATCH v3 31/42] target/arm: Add isar predicates for FEAT_HAFDBS Richard Henderson
2022-10-07  9:21   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 32/42] target/arm: Extract HA and HD in aa64_va_parameters Richard Henderson
2022-10-07  9:24   ` Peter Maydell
2022-10-07 15:37     ` Richard Henderson
2022-10-07 16:11       ` Peter Maydell
2022-10-07 16:13         ` Richard Henderson
2022-10-07 16:23           ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 33/42] target/arm: Split out S1TranslateResult type Richard Henderson
2022-10-07  9:27   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 34/42] target/arm: Move be test for regime into S1TranslateResult Richard Henderson
2022-10-07  9:29   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 35/42] target/arm: Move S1_ptw_translate outside arm_ld[lq]_ptw Richard Henderson
2022-10-07  9:33   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 36/42] target/arm: Add ARMFault_UnsuppAtomicUpdate Richard Henderson
2022-10-07  9:36   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 37/42] target/arm: Remove loop from get_phys_addr_lpae Richard Henderson
2022-10-07 10:20   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 38/42] target/arm: Fix fault reporting in get_phys_addr_lpae Richard Henderson
2022-10-07 10:26   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 39/42] target/arm: Don't shift attrs " Richard Henderson
2022-10-07 10:35   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 40/42] target/arm: Consider GP an attribute " Richard Henderson
2022-10-07 10:40   ` Peter Maydell
2022-10-01 16:23 ` [PATCH v3 41/42] target/arm: Implement FEAT_HAFDBS Richard Henderson
2022-10-07 13:47   ` Peter Maydell
2022-10-07 16:04     ` Peter Maydell
2022-10-07 16:45     ` Richard Henderson
2022-10-07 16:50       ` Peter Maydell
2022-10-07 17:35         ` Richard Henderson
2022-10-01 16:23 ` [PATCH v3 42/42] target/arm: Use the max page size in a 2-stage ptw Richard Henderson
2022-10-07 10:42   ` Peter Maydell
2022-10-10 13:10 ` [PATCH v3 00/42] target/arm: Implement FEAT_HAFDBS Peter Maydell

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=20221001162318.153420-31-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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.