diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index bbe902c2..039b14fd 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -6169,12 +6169,19 @@ static void do_v7m_exception_exit(ARMCPU *cpu) bool exc_secure = false; bool return_to_secure; - /* We can only get here from an EXCP_EXCEPTION_EXIT, and - * gen_bx_excret() enforces the architectural rule - * that jumps to magic addresses don't have magic behaviour unless - * we're in Handler mode (compare pseudocode BXWritePC()). + /* If we're not in Handler mode then jumps to magic exception-exit + * addresses don't have magic behaviour. However for the v8M + * security extensions the magic secure-function-return has to + * work in thread mode too, so to avoid doing an extra check in + * the generated code we allow exception-exit magic to also cause the + * internal exception and bring us here in thread mode. Correct code + * will never try to do this (the following insn fetch will always + * fault) so we the overhead of having taken an unnecessary exception + * doesn't matter. */ - assert(arm_v7m_is_handler_mode(env)); + if (!arm_v7m_is_handler_mode(env)) { + return; + } /* In the spec pseudocode ExceptionReturn() is called directly * from BXWritePC() and gets the full target PC value including