diff options
author | Jean-Philippe Brucker <jean-philippe@linaro.org> | 2023-08-22 17:31:11 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-08-22 17:31:11 +0100 |
commit | da64251e9317b3937cad54f71f606f5f9b837c8e (patch) | |
tree | b3fde52a53929fa468d859240e4d84c8b9d9ffb5 | |
parent | b17d86eb5ef745f393f3387b15df2b9b2aaae793 (diff) |
target/arm/ptw: Load stage-2 tables from realm physical space
In realm state, stage-2 translation tables are fetched from the realm
physical address space (R_PGRQD).
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20230809123706.1842548-2-jean-philippe@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/arm/ptw.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 07832eb8f7..7a69968dd7 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -157,22 +157,32 @@ static ARMMMUIdx ptw_idx_for_stage_2(CPUARMState *env, ARMMMUIdx stage2idx) /* * We're OK to check the current state of the CPU here because - * (1) we always invalidate all TLBs when the SCR_EL3.NS bit changes + * (1) we always invalidate all TLBs when the SCR_EL3.NS or SCR_EL3.NSE bit + * changes. * (2) there's no way to do a lookup that cares about Stage 2 for a * different security state to the current one for AArch64, and AArch32 * never has a secure EL2. (AArch32 ATS12NSO[UP][RW] allow EL3 to do * an NS stage 1+2 lookup while the NS bit is 0.) */ - if (!arm_is_secure_below_el3(env) || !arm_el_is_aa64(env, 3)) { + if (!arm_el_is_aa64(env, 3)) { return ARMMMUIdx_Phys_NS; } - if (stage2idx == ARMMMUIdx_Stage2_S) { - s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW); - } else { - s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW); - } - return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS; + switch (arm_security_space_below_el3(env)) { + case ARMSS_NonSecure: + return ARMMMUIdx_Phys_NS; + case ARMSS_Realm: + return ARMMMUIdx_Phys_Realm; + case ARMSS_Secure: + if (stage2idx == ARMMMUIdx_Stage2_S) { + s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW); + } else { + s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW); + } + return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS; + default: + g_assert_not_reached(); + } } static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx) |