Message ID | 20210813131809.28655-6-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | linux-user: Clean up siginfo_t handling for arm, aarch64 | expand |
On 8/13/21 3:18 AM, Peter Maydell wrote: > +void force_sig_fault(int sig, int code, abi_ulong addr) Better as abi_ptr? Otherwise, Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
On Sun, 15 Aug 2021 at 21:10, Richard Henderson <richard.henderson@linaro.org> wrote: > > On 8/13/21 3:18 AM, Peter Maydell wrote: > > +void force_sig_fault(int sig, int code, abi_ulong addr) > > Better as abi_ptr? I followed the same type used for 'addr' in the target_siginfo_t struct definition. -- PMM
On 8/15/21 11:03 PM, Peter Maydell wrote: > On Sun, 15 Aug 2021 at 21:10, Richard Henderson > <richard.henderson@linaro.org> wrote: >> >> On 8/13/21 3:18 AM, Peter Maydell wrote: >>> +void force_sig_fault(int sig, int code, abi_ulong addr) >> >> Better as abi_ptr? > > I followed the same type used for 'addr' in the target_siginfo_t > struct definition. Fair enough. r~
diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h index ea86328b289..536c7ac2c20 100644 --- a/linux-user/signal-common.h +++ b/linux-user/signal-common.h @@ -40,6 +40,7 @@ void tswap_siginfo(target_siginfo_t *tinfo, void set_sigmask(const sigset_t *set); void force_sig(int sig); void force_sigsegv(int oldsig); +void force_sig_fault(int sig, int code, abi_ulong addr); #if defined(TARGET_ARCH_HAS_SETUP_FRAME) void setup_frame(int sig, struct target_sigaction *ka, target_sigset_t *set, CPUArchState *env); diff --git a/linux-user/signal.c b/linux-user/signal.c index fd3c6a3e60d..5ea8e4584a7 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -646,6 +646,23 @@ void force_sig(int sig) queue_signal(env, info.si_signo, QEMU_SI_KILL, &info); } +/* + * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the + * 'force' part is handled in process_pending_signals(). + */ +void force_sig_fault(int sig, int code, abi_ulong addr) +{ + CPUState *cpu = thread_cpu; + CPUArchState *env = cpu->env_ptr; + target_siginfo_t info = {}; + + info.si_signo = sig; + info.si_errno = 0; + info.si_code = code; + info._sifields._sigfault._addr = addr; + queue_signal(env, sig, QEMU_SI_FAULT, &info); +} + /* Force a SIGSEGV if we couldn't write to memory trying to set * up the signal frame. oldsig is the signal we were trying to handle * at the point of failure.
In many places in the linux-user code we need to queue a signal for the guest using the QEMU_SI_FAULT si_type. This requires that the caller sets up and passes us a target_siginfo, including setting the appropriate part of the _sifields union for the si_type. In a number of places the code forgets to set the _sifields union field. Provide a new force_sig_fault() function, which does the same thing as the Linux kernel function of that name -- it takes the signal number, the si_code value and the address to use in _sifields._sigfault, and assembles the target_siginfo itself. This makes the callsites simpler and means it's harder to forget to pass in an address value. We follow force_sig() and the kernel's force_sig_fault() in not requiring the caller to pass in the CPU pointer but always acting on the CPU of the current thread. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- linux-user/signal-common.h | 1 + linux-user/signal.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) -- 2.20.1