diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2025-03-12 13:25:08 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2025-03-14 12:54:33 +0000 |
commit | 097d68ac2fd9bd40d0b6a3b3992c86a1f79d7187 (patch) | |
tree | e707b1246d72a92d8e599197b49a0827ee469b51 /target | |
parent | 44ab8c248dee2d899dfe858ce1962fedcd3398a1 (diff) | |
download | qemu-097d68ac2fd9bd40d0b6a3b3992c86a1f79d7187.zip qemu-097d68ac2fd9bd40d0b6a3b3992c86a1f79d7187.tar.gz qemu-097d68ac2fd9bd40d0b6a3b3992c86a1f79d7187.tar.bz2 |
target/arm: Forbid return to AArch32 when CPU is AArch64-only
In the Arm ARM, rule R_TYTWB states that returning to AArch32
is an illegal exception return if:
* AArch32 is not supported at any exception level
* the target EL is configured for AArch64 via SCR_EL3.RW
or HCR_EL2.RW or via CPU state at reset
We check the second of these, but not the first (which can only be
relevant for the case of a return to EL0, because if AArch32 is not
supported at one of the higher ELs then the RW bits will have an
effective value of 1 and the the "configured for AArch64" condition
will hold also).
Add the missing condition. Although this is technically a bug
(because we have one AArch64-only CPU: a64fx) it isn't worth
backporting to stable because no sensible guest code will
deliberately try to return to a nonexistent execution state
to check that it gets an illegal exception return.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/tcg/helper-a64.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c index e2bdf07..9244848 100644 --- a/target/arm/tcg/helper-a64.c +++ b/target/arm/tcg/helper-a64.c @@ -678,6 +678,11 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) goto illegal_return; } + if (!return_to_aa64 && !cpu_isar_feature(aa64_aa32, cpu)) { + /* Return to AArch32 when CPU is AArch64-only */ + goto illegal_return; + } + if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) { goto illegal_return; } |