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

Reply via email to