From: Richard Henderson Date: Mon, 4 Oct 2021 17:06:10 +0000 (-0700) Subject: linux-user: Add cpu_loop_exit_sigbus X-Git-Tag: v6.2.0-rc0~25^2~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12ed56407e60371d45ffa3b7f2fd00c4d7efa580;p=thirdparty%2Fqemu.git linux-user: Add cpu_loop_exit_sigbus This is a new interface to be provided by the os emulator for raising SIGBUS on fault. Use the new record_sigbus target hook. Reviewed-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index f74578500c9..6bb2a0f7ec2 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -700,6 +700,20 @@ void QEMU_NORETURN cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, MMUAccessType access_type, bool maperr, uintptr_t ra); +/** + * cpu_loop_exit_sigbus: + * @cpu: the cpu context + * @addr: the guest address of the alignment fault + * @access_type: access was read/write/execute + * @ra: host pc for unwinding + * + * Use the TCGCPUOps hook to record cpu state, do guest operating system + * specific things to raise SIGBUS, and jump to the main cpu loop. + */ +void QEMU_NORETURN cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, + MMUAccessType access_type, + uintptr_t ra); + #else static inline void mmap_lock(void) {} static inline void mmap_unlock(void) {} diff --git a/linux-user/signal.c b/linux-user/signal.c index 9d60abc0381..df2c8678d0e 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -706,6 +706,20 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, cpu_loop_exit_restore(cpu, ra); } +void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, + MMUAccessType access_type, uintptr_t ra) +{ + const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops; + + if (tcg_ops->record_sigbus) { + tcg_ops->record_sigbus(cpu, addr, access_type, ra); + } + + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, addr); + cpu->exception_index = EXCP_INTERRUPT; + cpu_loop_exit_restore(cpu, ra); +} + /* abort execution with signal */ static void QEMU_NORETURN dump_core_and_abort(int target_sig) {