commit d107b74807 ("target/riscv: Generate access fault if sc comparison
fails") made a misaligned sc.w/sc.d raise RISCV_EXCP_STORE_AMO_ADDR_MIS
from helper_sc_probe_write(). The linux-user cpu_loop() has no case for
that exception, so qemu-riscv64 aborts the whole emulator with
"qemu: unhandled CPU exception 0x6 - aborting" instead of delivering a
signal to the guest process. A JALR to an address with bit 1 set while
the guest C extension is disabled similarly raises
RISCV_EXCP_INST_ADDR_MIS, which also falls through to the generic abort
path.
Native RISC-V Linux delivers SIGSEGV/SEGV_ACCERR for misaligned
lr/sc/AMO accesses and SIGBUS/BUS_ADRALN for instruction-address
misalignment. Add both cases to the user-mode loop and forward the
exceptions accordingly.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4152
Signed-off-by: wangyang <[email protected]>
---
linux-user/riscv/cpu_loop.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 6f27a06da49..2a6ebc92047 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -84,6 +84,13 @@ void cpu_loop(CPURISCVState *env)
do_common_semihosting(cs);
env->pc += 4;
break;
+ case RISCV_EXCP_STORE_AMO_ADDR_MIS:
+ force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_ACCERR,
+ env->badaddr);
+ break;
+ case RISCV_EXCP_INST_ADDR_MIS:
+ force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->pc);
+ break;
default:
EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
trapnr);
--
2.43.0