* [PATCH for-10.2 v2 0/3] linux-user/aarch64: Syndrome fixes and enhancements
@ 2025-07-25 23:08 Richard Henderson
2025-07-25 23:08 ` [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception Richard Henderson
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Richard Henderson @ 2025-07-25 23:08 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm
Based-on: 20250725175510.3864231-1-peter.maydell@linaro.org
("[PATCH v2 for-10.1 0/3] linux-user/aarch64: Fix SME/SME2 signal frame handling")
Changes for v2:
- Split out syndrome handling from cpu_loop (pbo)
- Enumerate all exception codes and document them.
Include code for several cases missed by v1.
The FIXME in patch 2 suggests the whole patch set wait for 10.2.
r~
Richard Henderson (3):
linux-user/aarch64: Split out signal_for_exception
linux-user/aarch64: Check syndrome for EXCP_UDEF
linux-user/aarch64: Generate ESR signal records
linux-user/aarch64/cpu_loop.c | 153 +++++++++++++++++++++++++---------
linux-user/aarch64/signal.c | 34 +++++++-
2 files changed, 148 insertions(+), 39 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception
2025-07-25 23:08 [PATCH for-10.2 v2 0/3] linux-user/aarch64: Syndrome fixes and enhancements Richard Henderson
@ 2025-07-25 23:08 ` Richard Henderson
2025-07-30 17:41 ` Pierrick Bouvier
2025-07-25 23:08 ` [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
2025-07-25 23:08 ` [PATCH v2 3/3] linux-user/aarch64: Generate ESR signal records Richard Henderson
2 siblings, 1 reply; 8+ messages in thread
From: Richard Henderson @ 2025-07-25 23:08 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 84 ++++++++++++++++++++---------------
1 file changed, 47 insertions(+), 37 deletions(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index fea43cefa6..85d455d018 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -27,11 +27,56 @@
#include "target/arm/syndrome.h"
#include "target/arm/cpu-features.h"
+/* Use the exception syndrome to map a cpu exception to a signal. */
+static void signal_for_exception(CPUARMState *env, vaddr addr)
+{
+ uint32_t syn = env->exception.syndrome;
+ int si_code, si_signo;
+
+ switch (syn_get_ec(syn)) {
+ case EC_DATAABORT:
+ case EC_INSNABORT:
+ /* Both EC have the same format for FSC, or close enough. */
+ switch (extract32(syn, 0, 6)) {
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
+ si_signo = TARGET_SIGSEGV;
+ si_code = TARGET_SEGV_MAPERR;
+ break;
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
+ si_signo = TARGET_SIGSEGV;
+ si_code = TARGET_SEGV_ACCERR;
+ break;
+ case 0x11: /* Synchronous Tag Check Fault */
+ si_signo = TARGET_SIGSEGV;
+ si_code = TARGET_SEGV_MTESERR;
+ break;
+ case 0x21: /* Alignment fault */
+ si_signo = TARGET_SIGBUS;
+ si_code = TARGET_BUS_ADRALN;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
+
+ case EC_PCALIGNMENT:
+ si_signo = TARGET_SIGBUS;
+ si_code = TARGET_BUS_ADRALN;
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ force_sig_fault(si_signo, si_code, addr);
+}
+
/* AArch64 main loop */
void cpu_loop(CPUARMState *env)
{
CPUState *cs = env_cpu(env);
- int trapnr, ec, fsc, si_code, si_signo;
+ int trapnr;
abi_long ret;
for (;;) {
@@ -67,42 +112,7 @@ void cpu_loop(CPUARMState *env)
break;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
- ec = syn_get_ec(env->exception.syndrome);
- switch (ec) {
- case EC_DATAABORT:
- case EC_INSNABORT:
- /* Both EC have the same format for FSC, or close enough. */
- fsc = extract32(env->exception.syndrome, 0, 6);
- switch (fsc) {
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
- si_signo = TARGET_SIGSEGV;
- si_code = TARGET_SEGV_MAPERR;
- break;
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
- si_signo = TARGET_SIGSEGV;
- si_code = TARGET_SEGV_ACCERR;
- break;
- case 0x11: /* Synchronous Tag Check Fault */
- si_signo = TARGET_SIGSEGV;
- si_code = TARGET_SEGV_MTESERR;
- break;
- case 0x21: /* Alignment fault */
- si_signo = TARGET_SIGBUS;
- si_code = TARGET_BUS_ADRALN;
- break;
- default:
- g_assert_not_reached();
- }
- break;
- case EC_PCALIGNMENT:
- si_signo = TARGET_SIGBUS;
- si_code = TARGET_BUS_ADRALN;
- break;
- default:
- g_assert_not_reached();
- }
- force_sig_fault(si_signo, si_code, env->exception.vaddress);
+ signal_for_exception(env, env->exception.vaddress);
break;
case EXCP_DEBUG:
case EXCP_BKPT:
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF
2025-07-25 23:08 [PATCH for-10.2 v2 0/3] linux-user/aarch64: Syndrome fixes and enhancements Richard Henderson
2025-07-25 23:08 ` [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception Richard Henderson
@ 2025-07-25 23:08 ` Richard Henderson
2025-07-30 17:42 ` Pierrick Bouvier
2025-08-04 10:25 ` Peter Maydell
2025-07-25 23:08 ` [PATCH v2 3/3] linux-user/aarch64: Generate ESR signal records Richard Henderson
2 siblings, 2 replies; 8+ messages in thread
From: Richard Henderson @ 2025-07-25 23:08 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm
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
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] linux-user/aarch64: Generate ESR signal records
2025-07-25 23:08 [PATCH for-10.2 v2 0/3] linux-user/aarch64: Syndrome fixes and enhancements Richard Henderson
2025-07-25 23:08 ` [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception Richard Henderson
2025-07-25 23:08 ` [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
@ 2025-07-25 23:08 ` Richard Henderson
2 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2025-07-25 23:08 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm, Pierrick Bouvier
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 3 +++
linux-user/aarch64/signal.c | 34 +++++++++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 098578978e..7e9788abfb 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -33,6 +33,9 @@ static void signal_for_exception(CPUARMState *env, vaddr addr)
uint32_t syn = env->exception.syndrome;
int si_code, si_signo;
+ /* Let signal delivery see that ESR is live. */
+ env->cp15.esr_el[1] = syn;
+
switch (syn_get_ec(syn)) {
case EC_DATAABORT:
case EC_INSNABORT:
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 668353bbda..ef97be3ac7 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -65,6 +65,13 @@ struct target_fpsimd_context {
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
};
+#define TARGET_ESR_MAGIC 0x45535201
+
+struct target_esr_context {
+ struct target_aarch64_ctx head;
+ uint64_t esr;
+};
+
#define TARGET_EXTRA_MAGIC 0x45585401
struct target_extra_context {
@@ -201,6 +208,14 @@ static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
}
}
+static void target_setup_esr_record(struct target_esr_context *ctx,
+ CPUARMState *env)
+{
+ __put_user(TARGET_ESR_MAGIC, &ctx->head.magic);
+ __put_user(sizeof(*ctx), &ctx->head.size);
+ __put_user(env->cp15.esr_el[1], &ctx->esr);
+}
+
static void target_setup_extra_record(struct target_extra_context *extra,
uint64_t datap, uint32_t extra_size)
{
@@ -531,6 +546,9 @@ static int target_restore_sigframe(CPUARMState *env,
fpsimd = (struct target_fpsimd_context *)ctx;
break;
+ case TARGET_ESR_MAGIC:
+ break; /* ignore */
+
case TARGET_SVE_MAGIC:
if (sve || size < sizeof(struct target_sve_context)) {
goto err;
@@ -683,7 +701,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
uc.tuc_mcontext.__reserved),
};
int fpsimd_ofs, fr_ofs, sve_ofs = 0, za_ofs = 0, tpidr2_ofs = 0;
- int zt_ofs = 0;
+ int zt_ofs = 0, esr_ofs = 0;
int sve_size = 0, za_size = 0, tpidr2_size = 0, zt_size = 0;
struct target_rt_sigframe *frame;
struct target_rt_frame_record *fr;
@@ -693,6 +711,15 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
fpsimd_ofs = alloc_sigframe_space(sizeof(struct target_fpsimd_context),
&layout);
+ /*
+ * In user mode, ESR_EL1 is only set by cpu_loop while queueing the
+ * signal, and it's only valid for the one sync insn.
+ */
+ if (env->cp15.esr_el[1]) {
+ esr_ofs = alloc_sigframe_space(sizeof(struct target_esr_context),
+ &layout);
+ }
+
/* SVE state needs saving only if it exists. */
if (cpu_isar_feature(aa64_sve, env_archcpu(env)) ||
cpu_isar_feature(aa64_sme, env_archcpu(env))) {
@@ -754,6 +781,11 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
target_setup_general_frame(frame, env, set);
target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
+ if (esr_ofs) {
+ target_setup_esr_record((void *)frame + esr_ofs, env);
+ /* Leave ESR_EL1 clear while it's not relevant. */
+ env->cp15.esr_el[1] = 0;
+ }
target_setup_end_record((void *)frame + layout.std_end_ofs);
if (layout.extra_ofs) {
target_setup_extra_record((void *)frame + layout.extra_ofs,
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception
2025-07-25 23:08 ` [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception Richard Henderson
@ 2025-07-30 17:41 ` Pierrick Bouvier
0 siblings, 0 replies; 8+ messages in thread
From: Pierrick Bouvier @ 2025-07-30 17:41 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: qemu-arm
On 7/25/25 4:08 PM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> linux-user/aarch64/cpu_loop.c | 84 ++++++++++++++++++++---------------
> 1 file changed, 47 insertions(+), 37 deletions(-)
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF
2025-07-25 23:08 ` [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
@ 2025-07-30 17:42 ` Pierrick Bouvier
2025-08-04 10:25 ` Peter Maydell
1 sibling, 0 replies; 8+ messages in thread
From: Pierrick Bouvier @ 2025-07-30 17:42 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: qemu-arm
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>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF
2025-07-25 23:08 ` [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
2025-07-30 17:42 ` Pierrick Bouvier
@ 2025-08-04 10:25 ` Peter Maydell
2025-08-04 22:11 ` Richard Henderson
1 sibling, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2025-08-04 10:25 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, qemu-arm
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF
2025-08-04 10:25 ` Peter Maydell
@ 2025-08-04 22:11 ` Richard Henderson
0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2025-08-04 22:11 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, qemu-arm
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~
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-08-04 22:11 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-25 23:08 [PATCH for-10.2 v2 0/3] linux-user/aarch64: Syndrome fixes and enhancements Richard Henderson
2025-07-25 23:08 ` [PATCH v2 1/3] linux-user/aarch64: Split out signal_for_exception Richard Henderson
2025-07-30 17:41 ` Pierrick Bouvier
2025-07-25 23:08 ` [PATCH v2 2/3] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
2025-07-30 17:42 ` Pierrick Bouvier
2025-08-04 10:25 ` Peter Maydell
2025-08-04 22:11 ` Richard Henderson
2025-07-25 23:08 ` [PATCH v2 3/3] linux-user/aarch64: Generate ESR signal records Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).