aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2025-07-04 17:56:36 +0100
committerPeter Maydell <peter.maydell@linaro.org>2025-07-10 09:23:24 +0100
commitc563cd7e61d074f58eef413322144461dd243716 (patch)
treea5526274f2ec6d62d9c82c4b3a17c81ae88ae25f
parentae2086426d3784cf66e5b0b7ac823c08e87b4c57 (diff)
downloadqemu-c563cd7e61d074f58eef413322144461dd243716.zip
qemu-c563cd7e61d074f58eef413322144461dd243716.tar.gz
qemu-c563cd7e61d074f58eef413322144461dd243716.tar.bz2
target/arm: Don't enforce NSE,NS check for EL3->EL3 returns
In the Arm ARM, rule R_TYTWB that defines illegal exception return cases includes the case: If FEAT_RME is implemented, then if SCR_EL3.{NSE, NS} is {1, 0}, an exception return from EL3 to a lower Exception level Our implementation of this check fails to check that the return is to a lower exception level, so it will incorrectly fire on EL3->EL3 exception returns. Fix the check condition. This requires us to move it further down in the function to a point where we know the new_el value. Fixes: 35aa6715ddcd9 ("target/arm: Catch illegal-exception-return from EL3 with bad NSE/NS") Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3016 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704165636.261888-1-peter.maydell@linaro.org
-rw-r--r--target/arm/tcg/helper-a64.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
index c66d521..71c6c44 100644
--- a/target/arm/tcg/helper-a64.c
+++ b/target/arm/tcg/helper-a64.c
@@ -658,15 +658,6 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
spsr &= ~PSTATE_SS;
}
- /*
- * FEAT_RME forbids return from EL3 with an invalid security state.
- * We don't need an explicit check for FEAT_RME here because we enforce
- * in scr_write() that you can't set the NSE bit without it.
- */
- if (cur_el == 3 && (env->cp15.scr_el3 & (SCR_NS | SCR_NSE)) == SCR_NSE) {
- goto illegal_return;
- }
-
new_el = el_from_spsr(spsr);
if (new_el == -1) {
goto illegal_return;
@@ -678,6 +669,17 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
goto illegal_return;
}
+ /*
+ * FEAT_RME forbids return from EL3 to a lower exception level
+ * with an invalid security state.
+ * We don't need an explicit check for FEAT_RME here because we enforce
+ * in scr_write() that you can't set the NSE bit without it.
+ */
+ if (cur_el == 3 && new_el < 3 &&
+ (env->cp15.scr_el3 & (SCR_NS | SCR_NSE)) == SCR_NSE) {
+ goto illegal_return;
+ }
+
if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
/* Return to an EL which is configured for a different register width */
goto illegal_return;