On Thu, 6 Mar 2025 at 16:39, Peter Maydell <peter.mayd...@linaro.org> wrote: > > The definition of SCR_EL3.RW says that its effective value is 1 if: > - EL2 is implemented and does not support AArch32, and SCR_EL3.NS is 1 > - the effective value of SCR_EL3.{EEL2,NS} is {1,0} (i.e. we are > Secure and Secure EL2 is disabled) > > We implement the second of these in arm_el_is_aa64(), but forgot the > first (because currently all our CPUs with AArch64 support AArch32 at > all exception levels). > > Provide a new function arm_scr_rw_eff() to return the effective > value of SCR_EL3.RW, and use it in arm_el_is_aa64() and the other > places that currently look directly at the bit value. > > (scr_write() enforces that the RW bit is RAO/WI if neither EL1 nor > EL2 have AArch32 support, but if EL1 does but EL2 does not then the > bit must still be writeable.) > > This will mean that if code at EL3 attempts to perform an exception > return to AArch32 EL2 when EL2 is AArch64-only we will correctly > handle this as an illegal exception return: it will be caught by the > "return to an EL which is configured for a different register width" > check in HELPER(exception_return). > > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> > --- > target/arm/internals.h | 24 +++++++++++++++++++++--- > target/arm/helper.c | 4 ++-- > 2 files changed, 23 insertions(+), 5 deletions(-) > > diff --git a/target/arm/internals.h b/target/arm/internals.h > index b3f732233f4..82a0e1f785f 100644 > --- a/target/arm/internals.h > +++ b/target/arm/internals.h > @@ -392,6 +392,25 @@ static inline FloatRoundMode > arm_rmode_to_sf(ARMFPRounding rmode) > return arm_rmode_to_sf_map[rmode]; > } > > +/* Return the effective value of SCR_EL3.RW */ > +static inline bool arm_scr_rw_eff(CPUARMState *env) > +{ > + /* > + * SCR_EL3.RW has an effective value of 1 if: > + * - we are NS and EL2 is implemented but doesn't support AArch32 > + * - we are S and EL2 is enabled (in which case it must be AArch64) > + */ > + ARMCPU *cpu = env_archcpu(env); > + bool ns_and_no_aarch32_el2 = arm_feature(env, ARM_FEATURE_EL2) && > + (env->cp15.scr_el3 & SCR_NS) && > + !cpu_isar_feature(aa64_aa32_el1, cpu);
should be "aa64_aa32_el2"... > + bool s_and_el2_enabled = > + (env->cp15.scr_el3 & (SCR_NS | SCR_EEL2)) == SCR_EEL2; > + > + return ns_and_no_aarch32_el2 || s_and_el2_enabled || > + (env->cp15.scr_el3 & SCR_RW); > +} > -- PMM