Note that we have been passing the incorrect code for most
exception codes: uncategorized (do_el0_undef),
systemregistertrap (do_el0_sys), smetrap (do_sme_acc),
btitrap (do_el0_bti) and illegalstate (bad_el0_sync).
Only pacfail uses ILL_ILLOPN (do_el0_fpac).
Note that EC_MOP (do_el0_mops) ought not signal at all.
For now, preserve existing behavior signalling ILL_ILLOPN.
List all other exception codes and document why they do
not apply to user-only.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 66 ++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 85d455d018..098578978e 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -65,6 +65,70 @@ static void signal_for_exception(CPUARMState *env, vaddr addr)
si_code = TARGET_BUS_ADRALN;
break;
+ case EC_UNCATEGORIZED: /* E.g. undefined instruction */
+ case EC_SYSTEMREGISTERTRAP: /* E.g. inaccessible register */
+ case EC_SMETRAP: /* E.g. invalid insn in streaming state */
+ case EC_BTITRAP: /* E.g. invalid guarded branch target */
+ case EC_ILLEGALSTATE:
+ /*
+ * Illegal state happens via an ERET from a privileged mode,
+ * so is not normally possible from user-only. However, gdbstub
+ * is not prevented from writing CPSR_IL, aka PSTATE.IL, which
+ * would generate a trap from the next translated block.
+ * In the kernel, default case -> el0_inv -> bad_el0_sync.
+ */
+ si_signo = TARGET_SIGILL;
+ si_code = TARGET_ILL_ILLOPC;
+ break;
+
+ case EC_PACFAIL:
+ si_signo = TARGET_SIGILL;
+ si_code = TARGET_ILL_ILLOPN;
+ break;
+
+ case EC_MOP:
+ /*
+ * FIXME: The kernel fixes up wrong-option exceptions.
+ * In the meantime, preserve previous qemu behavior.
+ */
+ si_signo = TARGET_SIGILL;
+ si_code = TARGET_ILL_ILLOPN;
+ break;
+
+ case EC_WFX_TRAP: /* user-only WFI implemented as NOP */
+ case EC_CP15RTTRAP: /* AArch32 */
+ case EC_CP15RRTTRAP: /* AArch32 */
+ case EC_CP14RTTRAP: /* AArch32 */
+ case EC_CP14DTTRAP: /* AArch32 */
+ case EC_ADVSIMDFPACCESSTRAP: /* user-only does not disable fpu */
+ case EC_FPIDTRAP: /* AArch32 */
+ case EC_PACTRAP: /* user-only does not disable pac regs */
+ case EC_BXJTRAP: /* AArch32 */
+ case EC_CP14RRTTRAP: /* AArch32 */
+ case EC_AA32_SVC: /* AArch32 */
+ case EC_AA32_HVC: /* AArch32 */
+ case EC_AA32_SMC: /* AArch32 */
+ case EC_AA64_SVC: /* generates EXCP_SWI */
+ case EC_AA64_HVC: /* user-only generates EC_UNCATEGORIZED */
+ case EC_AA64_SMC: /* user-only generates EC_UNCATEGORIZED */
+ case EC_SVEACCESSTRAP: /* user-only does not disable sve */
+ case EC_ERETTRAP: /* user-only generates EC_UNCATEGORIZED */
+ case EC_GPC: /* user-only has no EL3 gpc tables */
+ case EC_INSNABORT_SAME_EL: /* el0 cannot trap to el0 */
+ case EC_DATAABORT_SAME_EL: /* el0 cannot trap to el0 */
+ case EC_SPALIGNMENT: /* sp alignment checks not implemented */
+ case EC_AA32_FPTRAP: /* fp exceptions not implemented */
+ case EC_AA64_FPTRAP: /* fp exceptions not implemented */
+ case EC_SERROR: /* user-only does not have hw faults */
+ case EC_BREAKPOINT: /* user-only does not have hw debug */
+ case EC_BREAKPOINT_SAME_EL: /* user-only does not have hw debug */
+ case EC_SOFTWARESTEP: /* user-only does not have hw debug */
+ case EC_SOFTWARESTEP_SAME_EL: /* user-only does not have hw debug */
+ case EC_WATCHPOINT: /* user-only does not have hw debug */
+ case EC_WATCHPOINT_SAME_EL: /* user-only does not have hw debug */
+ case EC_AA32_BKPT: /* AArch32 */
+ case EC_VECTORCATCH: /* AArch32 */
+ case EC_AA64_BKPT: /* generates EXCP_BKPT */
default:
g_assert_not_reached();
}
@@ -108,7 +172,7 @@ void cpu_loop(CPUARMState *env)
/* just indicate that signals should be handled asap */
break;
case EXCP_UDEF:
- force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->pc);
+ signal_for_exception(env, env->pc);
break;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
--
2.43.0
On Sat, 26 Jul 2025 at 00:09, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Note that we have been passing the incorrect code for most
> exception codes: uncategorized (do_el0_undef),
> systemregistertrap (do_el0_sys), smetrap (do_sme_acc),
> btitrap (do_el0_bti) and illegalstate (bad_el0_sync).
> Only pacfail uses ILL_ILLOPN (do_el0_fpac).
>
> Note that EC_MOP (do_el0_mops) ought not signal at all.
> For now, preserve existing behavior signalling ILL_ILLOPN.
True, but you'll only get an EC_MOP exception in linux-user
if you're playing silly games (like manually setting the
carry flag and then executing a CPYE or CPYM). Still, it's
not particularly complicated to do the fixup so we might
as well implement it at some point.
I'm OK with leaving this as a FIXME with a comment like
/*
* FIXME: The kernel fixes up wrong-option exceptions.
* For QEMU linux-user mode, you can only get these if
* the process is doing something silly (not executing
* the MOPS instructions in the required P/M/E sequence),
* so it is not a problem in practice that we do not.
*
* We ought ideally to implement the same "rewind to the
* start of the sequence" logic that the kernel does in
* arm64_mops_reset_regs(). In the meantime, deliver
* the guest a SIGILL, with the same ILLOPN si_code
* we've always used for this.
*/
-- PMM
On 8/4/25 20:25, Peter Maydell wrote: > I'm OK with leaving this as a FIXME with a comment like > > /* > * FIXME: The kernel fixes up wrong-option exceptions. > * For QEMU linux-user mode, you can only get these if > * the process is doing something silly (not executing > * the MOPS instructions in the required P/M/E sequence), > * so it is not a problem in practice that we do not. > * > * We ought ideally to implement the same "rewind to the > * start of the sequence" logic that the kernel does in > * arm64_mops_reset_regs(). In the meantime, deliver > * the guest a SIGILL, with the same ILLOPN si_code > * we've always used for this. > */ Thanks. I've used this verbatim. r~
On 7/25/25 4:08 PM, Richard Henderson wrote: > Note that we have been passing the incorrect code for most > exception codes: uncategorized (do_el0_undef), > systemregistertrap (do_el0_sys), smetrap (do_sme_acc), > btitrap (do_el0_bti) and illegalstate (bad_el0_sync). > Only pacfail uses ILL_ILLOPN (do_el0_fpac). > > Note that EC_MOP (do_el0_mops) ought not signal at all. > For now, preserve existing behavior signalling ILL_ILLOPN. > > List all other exception codes and document why they do > not apply to user-only. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/aarch64/cpu_loop.c | 66 ++++++++++++++++++++++++++++++++++- > 1 file changed, 65 insertions(+), 1 deletion(-) Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
© 2016 - 2025 Red Hat, Inc.