@samitouri / QOSamiQemu / commits / 653311eecd

target/arm: Handle NSACR.NSASEDIS in HCPTR accesses

In cptr_el2_read() and cptr_el2_write() we have code that implements the "HCPTR.{TCP10,TCP11} behave as RAO/WI from NonSecure when NSACR.cp10 is 0" behaviour. There is a similar requirement for HCPTR.TASE: if NSACR.NSASEDIS is 1 then CPACR.ASEDIS behaves as RAO/WI in NS. This doesn't matter to us yet because we don't currently implement ASEDIS or NSASEDIS. But we're about to do that, so add the handling to cptr_el2_read() and cptr_el2_write(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260817123838.1578060-3-peter.maydell@linaro.org

Peter Maydell committed Aug 17, 2026 at 13:38 UTC 653311eecdcbeae672bace9039b8c65745d1693c
1 file changed +18 -5
target/arm/helper.c
+18 -5
@@ -4117,11 +4117,18 @@ static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4117 /*
4118 * For A-profile AArch32 EL3, if NSACR.CP10
4119 * is 0 then HCPTR.{TCP11,TCP10} ignore writes and read as 1.
4120 + * Similarly, if NSACR.NSASEDIS is 1 then HCPTR.TASE behaves as RAO/WI.
4121 */
4122 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
4122 - !arm_is_secure(env) && !FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4123 - uint64_t mask = R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4124 - value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
4123 + !arm_is_secure(env)) {
4124 + if (!FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4125 + uint64_t mask = R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4126 + value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
4127 + }
4128 + if (FIELD_EX32(env->cp15.nsacr, NSACR, NSASEDIS)) {
4129 + uint64_t mask = R_HCPTR_TASE_MASK;
4130 + value = (value & ~mask) | (env->cp15.cptr_el[2] & mask);
4131 + }
4132 }
4133 env->cp15.cptr_el[2] = value;
4134 }
@@ -4131,12 +4138,18 @@ static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
4138 /*
4139 * For A-profile AArch32 EL3, if NSACR.CP10
4140 * is 0 then HCPTR.{TCP11,TCP10} ignore writes and read as 1.
4141 + * Similarly, if NSACR.NSASEDIS is 1 then HCPTR.TASE behaves as RAO/WI.
4142 */
4143 uint64_t value = env->cp15.cptr_el[2];
4144
4145 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
4138 - !arm_is_secure(env) && !FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4139 - value |= R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4146 + !arm_is_secure(env)) {
4147 + if (!FIELD_EX32(env->cp15.nsacr, NSACR, CP10)) {
4148 + value |= R_HCPTR_TCP11_MASK | R_HCPTR_TCP10_MASK;
4149 + }
4150 + if (!FIELD_EX32(env->cp15.nsacr, NSACR, NSASEDIS)) {
4151 + value |= R_HCPTR_TASE_MASK;
4152 + }
4153 }
4154 return value;
4155 }