aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-08-22 17:31:05 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-08-22 17:31:05 +0100
commit4f51edd3cd1746c0eee66eebafdfb642f8dd7e87 (patch)
tree5c323500d24c9ab80e76d46642c46f1ebb428179
parentf6415660746fcf58d6baf8dd8da77cb08adb9970 (diff)
downloadqemu-4f51edd3cd1746c0eee66eebafdfb642f8dd7e87.zip
qemu-4f51edd3cd1746c0eee66eebafdfb642f8dd7e87.tar.gz
qemu-4f51edd3cd1746c0eee66eebafdfb642f8dd7e87.tar.bz2
target/arm/ptw: Set s1ns bit in fault info more consistently
The s1ns bit in ARMMMUFaultInfo is documented as "true if we faulted on a non-secure IPA while in secure state". Both the places which look at this bit only do so after having confirmed that this is a stage 2 fault and we're dealing with Secure EL2, which leaves the ptw.c code free to set the bit to any random value in the other cases. Instead of taking advantage of that freedom, consistently make the bit be set to false for the "not a stage 2 fault for Secure EL2" cases. This removes some cases where we were using an 'is_secure' boolean and leaving the reader guessing about whether that was the right thing for Realm and Root cases. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230807141514.19075-4-peter.maydell@linaro.org
-rw-r--r--target/arm/ptw.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index eb57ebd..67078ae 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -514,6 +514,17 @@ static ARMSecuritySpace S2_security_space(ARMSecuritySpace s1_space,
}
}
+static bool fault_s1ns(ARMSecuritySpace space, ARMMMUIdx s2_mmu_idx)
+{
+ /*
+ * For stage 2 faults in Secure EL22, S1NS indicates
+ * whether the faulting IPA is in the Secure or NonSecure
+ * IPA space. For all other kinds of fault, it is false.
+ */
+ return space == ARMSS_Secure && regime_is_stage2(s2_mmu_idx)
+ && s2_mmu_idx == ARMMMUIdx_Stage2_S;
+}
+
/* Translate a S1 pagetable walk through S2 if needed. */
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
hwaddr addr, ARMMMUFaultInfo *fi)
@@ -586,7 +597,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
fi->s2addr = addr;
fi->stage2 = true;
fi->s1ptw = true;
- fi->s1ns = !is_secure;
+ fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx);
return false;
}
}
@@ -602,7 +613,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
fi->s2addr = addr;
fi->stage2 = regime_is_stage2(s2_mmu_idx);
fi->s1ptw = fi->stage2;
- fi->s1ns = !is_secure;
+ fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx);
return false;
}
@@ -729,7 +740,7 @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
fi->s2addr = ptw->out_virt;
fi->stage2 = true;
fi->s1ptw = true;
- fi->s1ns = !ptw->in_secure;
+ fi->s1ns = fault_s1ns(ptw->in_space, ptw->in_ptw_idx);
return 0;
}
@@ -2030,7 +2041,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
fi->level = level;
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
- fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
+ fi->s1ns = fault_s1ns(ptw->in_space, mmu_idx);
return true;
}