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: 35aa6715dd ("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
This commit is contained in:
parent
ae2086426d
commit
c563cd7e61
1 changed files with 11 additions and 9 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue