* [PATCH for-10.1 1/2] linux-user/aarch64: Check syndrome for EXCP_UDEF
2025-07-25 16:51 [PATCH 0/2] linux-user/aarch64: Syndrome fixes and enhancements Richard Henderson
@ 2025-07-25 16:51 ` Richard Henderson
2025-07-25 17:11 ` Pierrick Bouvier
2025-07-25 16:51 ` [PATCH for-10.2? 2/2] linux-user/aarch64: Generate ESR signal records Richard Henderson
1 sibling, 1 reply; 5+ messages in thread
From: Richard Henderson @ 2025-07-25 16:51 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Note that we have been passing the incorrect code for
uncategorized and bti faults.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index fea43cefa6..43a471b535 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -32,6 +32,7 @@ void cpu_loop(CPUARMState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, ec, fsc, si_code, si_signo;
+ uint64_t addr;
abi_long ret;
for (;;) {
@@ -63,10 +64,12 @@ 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);
- break;
+ addr = env->pc;
+ goto do_syndrome;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
+ addr = env->exception.vaddress;
+ do_syndrome:
ec = syn_get_ec(env->exception.syndrome);
switch (ec) {
case EC_DATAABORT:
@@ -99,10 +102,19 @@ void cpu_loop(CPUARMState *env)
si_signo = TARGET_SIGBUS;
si_code = TARGET_BUS_ADRALN;
break;
+ case EC_UNCATEGORIZED:
+ case EC_BTITRAP:
+ si_signo = TARGET_SIGILL;
+ si_code = TARGET_ILL_ILLOPC;
+ break;
+ case EC_PACFAIL:
+ si_signo = TARGET_SIGILL;
+ si_code = TARGET_ILL_ILLOPN;
+ break;
default:
g_assert_not_reached();
}
- force_sig_fault(si_signo, si_code, env->exception.vaddress);
+ force_sig_fault(si_signo, si_code, addr);
break;
case EXCP_DEBUG:
case EXCP_BKPT:
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH for-10.2? 2/2] linux-user/aarch64: Generate ESR signal records
2025-07-25 16:51 [PATCH 0/2] linux-user/aarch64: Syndrome fixes and enhancements Richard Henderson
2025-07-25 16:51 ` [PATCH for-10.1 1/2] linux-user/aarch64: Check syndrome for EXCP_UDEF Richard Henderson
@ 2025-07-25 16:51 ` Richard Henderson
2025-07-25 17:13 ` Pierrick Bouvier
1 sibling, 1 reply; 5+ messages in thread
From: Richard Henderson @ 2025-07-25 16:51 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 2 ++
linux-user/aarch64/signal.c | 34 +++++++++++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 43a471b535..a290dda30c 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -70,6 +70,8 @@ void cpu_loop(CPUARMState *env)
case EXCP_DATA_ABORT:
addr = env->exception.vaddress;
do_syndrome:
+ /* Let signal delivery see that ESR is live. */
+ env->cp15.esr_el[1] = env->exception.syndrome;
ec = syn_get_ec(env->exception.syndrome);
switch (ec) {
case EC_DATAABORT:
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index d50cab78d8..ca46734e2d 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 {
@@ -177,6 +184,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)
{
@@ -444,6 +459,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;
@@ -568,7 +586,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
.total_size = offsetof(struct target_rt_sigframe,
uc.tuc_mcontext.__reserved),
};
- int fpsimd_ofs, fr_ofs, sve_ofs = 0, za_ofs = 0;
+ int fpsimd_ofs, fr_ofs, esr_ofs = 0, sve_ofs = 0, za_ofs = 0;
int sve_size = 0, za_size = 0;
struct target_rt_sigframe *frame;
struct target_rt_frame_record *fr;
@@ -578,6 +596,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))) {
@@ -631,6 +658,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] 5+ messages in thread