diff mbox series

[08/17] target/arm: return the stage 2 index for stage 1

Message ID 20201109141020.27234-8-remi.denis.courmont@huawei.com (mailing list archive)
State New, archived
Headers show
Series ARM Secure EL2 extension | expand

Commit Message

Rémi Denis-Courmont Nov. 9, 2020, 2:10 p.m. UTC
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>

This makes arm_mmu_idx_is_stage1_of_2() optionally return the stage 2
MMU index. With Secure EL2, there are more than one stage 2 regimes, so
we can no longer hard-code a constant index for it.

Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c    | 13 +++++++------
 target/arm/internals.h | 16 +++++++++++-----
 2 files changed, 18 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5c6b22c757..14eb0b4719 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3424,7 +3424,7 @@  static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
         bool take_exc = false;
 
         if (fi.s1ptw && current_el == 1 && !arm_is_secure(env)
-            && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
+            && arm_mmu_idx_is_stage1_of_2(mmu_idx, NULL)) {
             /*
              * Synchronous stage 2 fault on an access made as part of the
              * translation table walk for AT S1E0* or AT S1E1* insn
@@ -10008,7 +10008,7 @@  static inline bool regime_translation_disabled(CPUARMState *env,
         }
     }
 
-    if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
+    if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx, NULL)) {
         /* HCR.DC means SCTLR_EL1.M behaves as 0 */
         return true;
     }
@@ -10340,16 +10340,17 @@  static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
                                hwaddr addr, MemTxAttrs txattrs,
                                ARMMMUFaultInfo *fi)
 {
-    if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
-        !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
+    ARMMMUIdx s2_mmu_idx;
+
+    if (arm_mmu_idx_is_stage1_of_2(mmu_idx, &s2_mmu_idx) &&
+        !regime_translation_disabled(env, s2_mmu_idx)) {
         target_ulong s2size;
         hwaddr s2pa;
         int s2prot;
         int ret;
         ARMCacheAttrs cacheattrs = {};
 
-        ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
-                                 false,
+        ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
                                  &s2pa, &txattrs, &s2prot, &s2size, fi,
                                  &cacheattrs);
         if (ret) {
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 5460678756..4e4798574b 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1146,17 +1146,23 @@  ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
 
 /**
  * arm_mmu_idx_is_stage1_of_2:
- * @mmu_idx: The ARMMMUIdx to test
+ * @s1_mmu_idx: The ARMMMUIdx to test
+ * @s2_mmu_idx: Storage space for the stage 2 ARMMMUIdx
  *
- * Return true if @mmu_idx is a NOTLB mmu_idx that is the
- * first stage of a two stage regime.
+ * Return true if @mmu_idx is a NOTLB mmu_idx that is the first stage
+ * of a two stage regime. The corresponding second stage will be
+ * stored in @s2_mmu_idx.
  */
-static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
+static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx s1_mmu_idx,
+                                              ARMMMUIdx *s2_mmu_idx)
 {
-    switch (mmu_idx) {
+    switch (s1_mmu_idx) {
     case ARMMMUIdx_Stage1_E0:
     case ARMMMUIdx_Stage1_E1:
     case ARMMMUIdx_Stage1_E1_PAN:
+        if (s2_mmu_idx != NULL) {
+            *s2_mmu_idx = ARMMMUIdx_Stage2;
+        }
         return true;
     default:
         return false;