diff options
author | Richard Henderson | 2021-07-24 00:22:54 +0200 |
---|---|---|
committer | Richard Henderson | 2021-11-02 12:00:52 +0100 |
commit | 39a099ca25670b9fed838a09887fe8a1fdd803d3 (patch) | |
tree | 9a19867b4dacfbe6a11662bf75557dd72d18af7f /linux-user/aarch64 | |
parent | target/alpha: Implement alpha_cpu_record_sigbus (diff) | |
download | qemu-39a099ca25670b9fed838a09887fe8a1fdd803d3.tar.gz qemu-39a099ca25670b9fed838a09887fe8a1fdd803d3.tar.xz qemu-39a099ca25670b9fed838a09887fe8a1fdd803d3.zip |
target/arm: Implement arm_cpu_record_sigbus
Because of the complexity of setting ESR, re-use the existing
arm_cpu_do_unaligned_access function. This means we have to
handle the exception ourselves in cpu_loop, transforming it
to the appropriate signal.
Reviewed-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/aarch64')
-rw-r--r-- | linux-user/aarch64/cpu_loop.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c index 034b737435..97e0728b67 100644 --- a/linux-user/aarch64/cpu_loop.c +++ b/linux-user/aarch64/cpu_loop.c @@ -79,7 +79,7 @@ void cpu_loop(CPUARMState *env) { CPUState *cs = env_cpu(env); - int trapnr, ec, fsc, si_code; + int trapnr, ec, fsc, si_code, si_signo; abi_long ret; for (;;) { @@ -121,20 +121,26 @@ void cpu_loop(CPUARMState *env) 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(); } - - force_sig_fault(TARGET_SIGSEGV, si_code, env->exception.vaddress); + force_sig_fault(si_signo, si_code, env->exception.vaddress); break; case EXCP_DEBUG: case EXCP_BKPT: |