From 0fdbb7d2c1ecb761b985b176b9bb159d483d9514 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 12 Sep 2021 19:25:22 -0700 Subject: accel/tcg: Split out adjust_signal_pc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out a function to adjust the raw signal pc into a value that could be passed to cpu_restore_state. Reviewed-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- v2: Adjust pc in place; return MMUAccessType. --- include/exec/exec-all.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 9d5987b..e54f8e5 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -664,6 +664,16 @@ static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, } /** + * adjust_signal_pc: + * @pc: raw pc from the host signal ucontext_t. + * @is_write: host memory operation was write, or read-modify-write. + * + * Alter @pc as required for unwinding. Return the type of the + * guest memory access -- host reads may be for guest execution. + */ +MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write); + +/** * cpu_signal_handler * @signum: host signal number * @pinfo: host siginfo_t -- cgit v1.1 From 5e38ba7dde963414dddc8a83848701b49d0bcb00 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 12 Sep 2021 19:47:29 -0700 Subject: accel/tcg: Split out handle_sigsegv_accerr_write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the major portion of handle_cpu_signal which is specific to tcg, handling the page protections for the translations. Most of the rest will migrate to linux-user/ shortly. Reviewed-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- v2: Pass guest address to handle_sigsegv_accerr_write. --- include/exec/exec-all.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index e54f8e5..5f94d79 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -674,6 +674,18 @@ static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write); /** + * handle_sigsegv_accerr_write: + * @cpu: the cpu context + * @old_set: the sigset_t from the signal ucontext_t + * @host_pc: the host pc, adjusted for the signal + * @host_addr: the host address of the fault + * + * Return true if the write fault has been handled, and should be re-tried. + */ +bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, + uintptr_t host_pc, abi_ptr guest_addr); + +/** * cpu_signal_handler * @signum: host signal number * @pinfo: host siginfo_t -- cgit v1.1 From 04de121aaf0c896812792eb8489ae614c7f6dade Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 17 Sep 2021 12:00:31 -0700 Subject: linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that all of the linux-user hosts have been converted to host-signal.h, drop the compatibility code. Reviewed by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/exec/exec-all.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include') diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 5f94d79..5dd663c 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -685,18 +685,6 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write); bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, uintptr_t host_pc, abi_ptr guest_addr); -/** - * cpu_signal_handler - * @signum: host signal number - * @pinfo: host siginfo_t - * @puc: host ucontext_t - * - * To be called from the SIGBUS and SIGSEGV signal handler to inform the - * virtual cpu of exceptions. Returns true if the signal was handled by - * the virtual CPU. - */ -int cpu_signal_handler(int signum, void *pinfo, void *puc); - #else static inline void mmap_lock(void) {} static inline void mmap_unlock(void) {} -- cgit v1.1 From 09e94676ade52708cbece8fd4bd255a25b6ee475 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 17 Sep 2021 17:31:33 -0700 Subject: hw/core: Add TCGCPUOps.record_sigsegv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new user-only interface for updating cpu state before raising a signal. This will replace tlb_fill for user-only and should result in less boilerplate for each guest. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include') diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h index 6cbe17f..41718b6 100644 --- a/include/hw/core/tcg-cpu-ops.h +++ b/include/hw/core/tcg-cpu-ops.h @@ -111,6 +111,32 @@ struct TCGCPUOps { */ bool (*io_recompile_replay_branch)(CPUState *cpu, const TranslationBlock *tb); +#else + /** + * record_sigsegv: + * @cpu: cpu context + * @addr: faulting guest address + * @access_type: access was read/write/execute + * @maperr: true for invalid page, false for permission fault + * @ra: host pc for unwinding + * + * We are about to raise SIGSEGV with si_code set for @maperr, + * and si_addr set for @addr. Record anything further needed + * for the signal ucontext_t. + * + * If the emulated kernel does not provide anything to the signal + * handler with anything besides the user context registers, and + * the siginfo_t, then this hook need do nothing and may be omitted. + * Otherwise, record the data and return; the caller will raise + * the signal, unwind the cpu state, and return to the main loop. + * + * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided + * so that a "normal" cpu exception can be raised. In this case, + * the signal must be raised by the architecture cpu_loop. + */ + void (*record_sigsegv)(CPUState *cpu, vaddr addr, + MMUAccessType access_type, + bool maperr, uintptr_t ra); #endif /* CONFIG_SOFTMMU */ #endif /* NEED_CPU_H */ -- cgit v1.1 From 72d2bbf9ff3e1edf5d57b53149eeaa36f19fb891 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 17 Sep 2021 17:32:56 -0700 Subject: linux-user: Add cpu_loop_exit_sigsegv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a new interface to be provided by the os emulator for raising SIGSEGV on fault. Use the new record_sigsegv target hook. Reviewed by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/exec/exec-all.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 5dd663c..f745785 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -685,6 +685,21 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write); bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, uintptr_t host_pc, abi_ptr guest_addr); +/** + * cpu_loop_exit_sigsegv: + * @cpu: the cpu context + * @addr: the guest address of the fault + * @access_type: access was read/write/execute + * @maperr: true for invalid page, false for permission fault + * @ra: host pc for unwinding + * + * Use the TCGCPUOps hook to record cpu state, do guest operating system + * specific things to raise SIGSEGV, and jump to the main cpu loop. + */ +void QEMU_NORETURN cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, + MMUAccessType access_type, + bool maperr, uintptr_t ra); + #else static inline void mmap_lock(void) {} static inline void mmap_unlock(void) {} -- cgit v1.1 From eeca7dc566076d6130d986e17508372bc7916281 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 15 Sep 2021 08:13:38 -0700 Subject: accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have replaced tlb_fill with record_sigsegv for user mode. Move the declaration to restrict it to system emulation. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/hw/core/tcg-cpu-ops.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h index 41718b6..8eadd40 100644 --- a/include/hw/core/tcg-cpu-ops.h +++ b/include/hw/core/tcg-cpu-ops.h @@ -35,18 +35,6 @@ struct TCGCPUOps { void (*cpu_exec_enter)(CPUState *cpu); /** @cpu_exec_exit: Callback for cpu_exec cleanup */ void (*cpu_exec_exit)(CPUState *cpu); - /** - * @tlb_fill: Handle a softmmu tlb miss or user-only address fault - * - * For system mode, if the access is valid, call tlb_set_page - * and return true; if the access is invalid, and probe is - * true, return false; otherwise raise an exception and do - * not return. For user-only mode, always raise an exception - * and do not return. - */ - bool (*tlb_fill)(CPUState *cpu, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); /** @debug_excp_handler: Callback for handling debug exceptions */ void (*debug_excp_handler)(CPUState *cpu); @@ -69,6 +57,16 @@ struct TCGCPUOps { /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */ bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); /** + * @tlb_fill: Handle a softmmu tlb miss + * + * If the access is valid, call tlb_set_page and return true; + * if the access is invalid and probe is true, return false; + * otherwise raise an exception and do not return. + */ + bool (*tlb_fill)(CPUState *cpu, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr); + /** * @do_transaction_failed: Callback for handling failed memory transactions * (ie bus faults or external aborts; not MMU faults) */ -- cgit v1.1 From 644a9fece426d52cf8fb51e24e003dd4c590c5cc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 4 Oct 2021 10:05:20 -0700 Subject: hw/core: Add TCGCPUOps.record_sigbus Add a new user-only interface for updating cpu state before raising a signal. This will take the place of do_unaligned_access for user-only and should result in less boilerplate for each guest. Reviewed-by: Warner Losh Signed-off-by: Richard Henderson --- include/hw/core/tcg-cpu-ops.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include') diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h index 8eadd40..e138985 100644 --- a/include/hw/core/tcg-cpu-ops.h +++ b/include/hw/core/tcg-cpu-ops.h @@ -135,6 +135,29 @@ struct TCGCPUOps { void (*record_sigsegv)(CPUState *cpu, vaddr addr, MMUAccessType access_type, bool maperr, uintptr_t ra); + /** + * record_sigbus: + * @cpu: cpu context + * @addr: misaligned guest address + * @access_type: access was read/write/execute + * @ra: host pc for unwinding + * + * We are about to raise SIGBUS with si_code BUS_ADRALN, + * and si_addr set for @addr. Record anything further needed + * for the signal ucontext_t. + * + * If the emulated kernel does not provide the signal handler with + * anything besides the user context registers, and the siginfo_t, + * then this hook need do nothing and may be omitted. + * Otherwise, record the data and return; the caller will raise + * the signal, unwind the cpu state, and return to the main loop. + * + * If it is simpler to re-use the sysemu do_unaligned_access code, + * @ra is provided so that a "normal" cpu exception can be raised. + * In this case, the signal must be raised by the architecture cpu_loop. + */ + void (*record_sigbus)(CPUState *cpu, vaddr addr, + MMUAccessType access_type, uintptr_t ra); #endif /* CONFIG_SOFTMMU */ #endif /* NEED_CPU_H */ -- cgit v1.1 From 12ed56407e60371d45ffa3b7f2fd00c4d7efa580 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 4 Oct 2021 10:06:10 -0700 Subject: linux-user: Add cpu_loop_exit_sigbus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- include/exec/exec-all.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index f745785..6bb2a0f 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) {} -- cgit v1.1 From 37e891e38fe1e81fc468d8a000912f8e7ee61336 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 27 Jul 2021 19:41:04 -1000 Subject: tcg: Add helper_unaligned_{ld,st} for user-only sigbus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To be called from tcg generated code on hosts that support unaligned accesses natively, in response to an access that is supposed to be aligned. Reviewed-by: Warner Losh Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/tcg/tcg-ldst.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/tcg/tcg-ldst.h b/include/tcg/tcg-ldst.h index 8c86365..bf40942 100644 --- a/include/tcg/tcg-ldst.h +++ b/include/tcg/tcg-ldst.h @@ -70,5 +70,10 @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val, void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val, MemOpIdx oi, uintptr_t retaddr); +#else + +void QEMU_NORETURN helper_unaligned_ld(CPUArchState *env, target_ulong addr); +void QEMU_NORETURN helper_unaligned_st(CPUArchState *env, target_ulong addr); + #endif /* CONFIG_SOFTMMU */ #endif /* TCG_LDST_H */ -- cgit v1.1