Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20211102' into staging

- Split out host signal handing from accel/tcg/user-exec.c
  to linux-user/host/arch/host-signal.h
- Replace TCGCPUOps.tlb_fill with TCGCPUOps.record_sigsegv for user-only
- Add TCGCPUOps.record_sigbus for user-only
- Remove a lot of target-specific cpu_loop handling for signals,
  now accomplished with generic code.

# gpg: Signature made Tue 02 Nov 2021 07:06:14 AM EDT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate]

* remotes/rth/tags/pull-tcg-20211102: (60 commits)
  linux-user: Handle BUS_ADRALN in host_signal_handler
  tcg: Add helper_unaligned_{ld,st} for user-only sigbus
  accel/tcg: Report unaligned load/store for user-only
  accel/tcg: Report unaligned atomics for user-only
  target/sparc: Set fault address in sparc_cpu_do_unaligned_access
  target/sparc: Split out build_sfsr
  target/sparc: Remove DEBUG_UNALIGNED
  target/sh4: Set fault address in superh_cpu_do_unaligned_access
  target/s390x: Implement s390x_cpu_record_sigbus
  linux-user/ppc: Remove POWERPC_EXCP_ALIGN handling
  target/ppc: Restrict ppc_cpu_do_unaligned_access to sysemu
  target/ppc: Set fault address in ppc_cpu_do_unaligned_access
  target/ppc: Move SPR_DSISR setting to powerpc_excp
  target/microblaze: Do not set MO_ALIGN for user-only
  linux-user/hppa: Remove EXCP_UNALIGN handling
  target/arm: Implement arm_cpu_record_sigbus
  target/alpha: Implement alpha_cpu_record_sigbus
  linux-user: Add cpu_loop_exit_sigbus
  hw/core: Add TCGCPUOps.record_sigbus
  accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2021-11-02 13:44:53 -04:00
103 changed files with 1269 additions and 1436 deletions
+47 -8
View File
@@ -664,16 +664,55 @@ static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env,
}
/**
* cpu_signal_handler
* @signum: host signal number
* @pinfo: host siginfo_t
* @puc: host ucontext_t
* adjust_signal_pc:
* @pc: raw pc from the host signal ucontext_t.
* @is_write: host memory operation was write, or read-modify-write.
*
* 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.
* Alter @pc as required for unwinding. Return the type of the
* guest memory access -- host reads may be for guest execution.
*/
int cpu_signal_handler(int signum, void *pinfo, void *puc);
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_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);
/**
* 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) {}
+59 -12
View File
@@ -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);
@@ -68,6 +56,16 @@ struct TCGCPUOps {
#ifdef CONFIG_SOFTMMU
/** @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)
@@ -111,6 +109,55 @@ 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);
/**
* 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 */
+5
View File
@@ -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 */