linux-user/aarch64: Generate ESR signal records
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250830054128.448363-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
5fe3151c5e
commit
e1b31ba94d
2 changed files with 36 additions and 1 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue