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

Reply via email to