The starting security state comes with the translation regime, not the current state of arm_is_secure_below_el3().
More use of the local variable, ipa_secure, which does not need to be written back to result->attrs.secure -- we compute that value later, after the S2 walk is complete. Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/ptw.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 1a946f3757..b78658161f 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -2304,6 +2304,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx); + bool is_secure = regime_is_secure(env, mmu_idx); if (mmu_idx != s1_mmu_idx) { /* @@ -2328,18 +2329,16 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, } ipa = result->phys; - ipa_secure = result->attrs.secure; - if (arm_is_secure_below_el3(env)) { - result->attrs.secure = - (ipa_secure - ? !(env->cp15.vstcr_el2.raw_tcr & VSTCR_SW) - : !(env->cp15.vtcr_el2.raw_tcr & VTCR_NSW)); + if (is_secure) { + /* Select TCR based on the NS bit from the S1 walk. */ + ipa_secure = !(result->attrs.secure + ? env->cp15.vstcr_el2.raw_tcr & VSTCR_SW + : env->cp15.vtcr_el2.raw_tcr & VTCR_NSW); } else { - assert(!ipa_secure); + ipa_secure = false; } - s2_mmu_idx = (result->attrs.secure - ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2); + s2_mmu_idx = (ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2); is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0; /* @@ -2383,7 +2382,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, result->cacheattrs); /* Check if IPA translates to secure or non-secure PA space. */ - if (arm_is_secure_below_el3(env)) { + if (is_secure) { if (ipa_secure) { result->attrs.secure = !(env->cp15.vstcr_el2.raw_tcr & (VSTCR_SA | VSTCR_SW)); @@ -2407,7 +2406,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, * cannot upgrade an non-secure translation regime's attributes * to secure. */ - result->attrs.secure = regime_is_secure(env, mmu_idx); + result->attrs.secure = is_secure; result->attrs.user = regime_is_user(env, mmu_idx); /* -- 2.34.1