Message ID | 20211015041053.2769193-45-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | user-only: Cleanup SIGSEGV and SIGBUS handling | expand |
On Thu, Oct 14, 2021 at 10:14 PM Richard Henderson < richard.henderson@linaro.org> wrote: > This is a new interface to be provided by the os emulator for > raising SIGBUS on fault. Use the new record_sigbus target hook. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > include/exec/exec-all.h | 14 ++++++++++++++ > linux-user/signal.c | 14 ++++++++++++++ > 2 files changed, 28 insertions(+) > Reviewed-by: Warner Losh <imp@bsdimp.com> > diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h > index f74578500c..6bb2a0f7ec 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 9d60abc038..df2c8678d0 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) > { > -- > 2.25.1 > >
On 10/15/21 06:10, Richard Henderson wrote: > This is a new interface to be provided by the os emulator for > raising SIGBUS on fault. Use the new record_sigbus target hook. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > include/exec/exec-all.h | 14 ++++++++++++++ This header deserves a system/user split. > linux-user/signal.c | 14 ++++++++++++++ > 2 files changed, 28 insertions(+) Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index f74578500c..6bb2a0f7ec 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 9d60abc038..df2c8678d0 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) {
This is a new interface to be provided by the os emulator for raising SIGBUS on fault. Use the new record_sigbus target hook. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- include/exec/exec-all.h | 14 ++++++++++++++ linux-user/signal.c | 14 ++++++++++++++ 2 files changed, 28 insertions(+)