diff options
author | Peter Maydell | 2022-01-31 21:20:54 +0100 |
---|---|---|
committer | Peter Maydell | 2022-01-31 21:20:54 +0100 |
commit | 5cbe64110dbe27f82d30552001acdc5eeaade11c (patch) | |
tree | 8ea1e2e5a9bb72419d8860ffe1a9cdb990e8229c /bsd-user/signal-common.h | |
parent | Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220130' into s... (diff) | |
parent | bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchStat... (diff) | |
download | qemu-5cbe64110dbe27f82d30552001acdc5eeaade11c.tar.gz qemu-5cbe64110dbe27f82d30552001acdc5eeaade11c.tar.xz qemu-5cbe64110dbe27f82d30552001acdc5eeaade11c.zip |
Merge remote-tracking branch 'remotes/bsdimp/tags/bsd-user-arm-2022q1-pull-request' into staging
bsd-user: upstream signal implementation
Upstream the bsd-user fork signal implementation, for the most part. This
series of commits represents nearly all of the infrastructure that surround
signals, except the actual system call glue (that was also reworked in the
fork and needs its own series). In addition, this adds the sigsegv and sigbus
code to arm. Even in the fork, we don't have good x86 signal implementation,
so there's little to upstream for that at the moment.
bsd-user's signal implementation is similar to linux-user's. The full context
can be found in the bsd-user's fork's 'blitz branch' at
https://github.com/qemu-bsd-user/qemu-bsd-user/tree/blitz which shows how these
are used to implement various system calls. Since this was built from
linux-user's stack stuff, evolved for BSD with the passage of a few years, it
no-doubt missed some bug fixes from linux-user (though nothing obvious stood out
in the quick comparison I made). After the first round of reviews, many of these
improvements have been incorporated.
Patchew history: https://patchew.org/QEMU/20220125012947.14974-1-imp@bsdimp.com/
# gpg: Signature made Mon 31 Jan 2022 19:55:51 GMT
# gpg: using RSA key 2035F894B00AA3CF7CCDE1B76C1CD1287DB01100
# gpg: Good signature from "Warner Losh <wlosh@netflix.com>" [unknown]
# gpg: aka "Warner Losh <imp@bsdimp.com>" [unknown]
# gpg: aka "Warner Losh <imp@freebsd.org>" [unknown]
# gpg: aka "Warner Losh <imp@village.org>" [unknown]
# gpg: aka "Warner Losh <wlosh@bsdimp.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2035 F894 B00A A3CF 7CCD E1B7 6C1C D128 7DB0 1100
* remotes/bsdimp/tags/bsd-user-arm-2022q1-pull-request: (40 commits)
bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args
bsd-user: Rename arg name for target_cpu_reset to env
MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on
bsd-user/signal.c: do_sigaltstack
bsd-user/signal.c: implement do_sigaction
bsd-user/signal.c: implement do_sigreturn
bsd-user/signal.c: process_pending_signals
bsd-user/signal.c: tswap_siginfo
bsd-user/signal.c: handle_pending_signal
bsd-user/signal.c: setup_frame
bsd-user/signal.c: sigset manipulation routines.
bsd-user/signal.c: Fill in queue_signal
bsd-user/signal.c: Implement dump_core_and_abort
bsd-user/strace.c: print_taken_signal
bsd-user/signal.c: Implement host_signal_handler
bsd-user/signal.c: Implement rewind_if_in_safe_syscall
bsd-user/signal.c: host_to_target_siginfo_noswap
bsd-user: Add trace events for bsd-user
bsd-user: Add host signals to the build
bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'bsd-user/signal-common.h')
-rw-r--r-- | bsd-user/signal-common.h | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h new file mode 100644 index 0000000000..7ff8e8f2e4 --- /dev/null +++ b/bsd-user/signal-common.h @@ -0,0 +1,70 @@ +/* + * Emulation of BSD signals + * + * Copyright (c) 2013 Stacey Son + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef SIGNAL_COMMON_H +#define SIGNAL_COMMON_H + +/** + * block_signals: block all signals while handling this guest syscall + * + * Block all signals, and arrange that the signal mask is returned to + * its correct value for the guest before we resume execution of guest code. + * If this function returns non-zero, then the caller should immediately + * return -TARGET_ERESTARTSYS to the main loop, which will take the pending + * signal and restart execution of the syscall. + * If block_signals() returns zero, then the caller can continue with + * emulation of the system call knowing that no signals can be taken + * (and therefore that no race conditions will result). + * This should only be called once, because if it is called a second time + * it will always return non-zero. (Think of it like a mutex that can't + * be recursively locked.) + * Signals will be unblocked again by process_pending_signals(). + * + * Return value: non-zero if there was a pending signal, zero if not. + */ +int block_signals(void); /* Returns non zero if signal pending */ + +long do_rt_sigreturn(CPUArchState *env); +int do_sigaction(int sig, const struct target_sigaction *act, + struct target_sigaction *oact); +abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); +long do_sigreturn(CPUArchState *env, abi_ulong addr); +void force_sig_fault(int sig, int code, abi_ulong addr); +int host_to_target_signal(int sig); +void host_to_target_sigset(target_sigset_t *d, const sigset_t *s); +void process_pending_signals(CPUArchState *env); +void queue_signal(CPUArchState *env, int sig, int si_type, + target_siginfo_t *info); +void signal_init(void); +int target_to_host_signal(int sig); +void target_to_host_sigset(sigset_t *d, const target_sigset_t *s); + +/* + * Within QEMU the top 8 bits of si_code indicate which of the parts of the + * union in target_siginfo is valid. This only applies between + * host_to_target_siginfo_noswap() and tswap_siginfo(); it does not appear + * either within host siginfo_t or in target_siginfo structures which we get + * from the guest userspace program. Linux kenrels use this internally, but BSD + * kernels don't do this, but its a useful abstraction. + * + * The linux-user version of this uses the top 16 bits, but FreeBSD's SI_USER + * and other signal indepenent SI_ codes have bit 16 set, so we only use the top + * byte instead. + * + * For FreeBSD, we have si_pid, si_uid, si_status, and si_addr always. Linux and + * {Open,Net}BSD have a different approach (where their reason field is larger, + * but whose siginfo has fewer fields always). + */ +#define QEMU_SI_NOINFO 0 /* nothing other than si_signo valid */ +#define QEMU_SI_FAULT 1 /* _fault is valid in _reason */ +#define QEMU_SI_TIMER 2 /* _timer is valid in _reason */ +#define QEMU_SI_MESGQ 3 /* _mesgq is valid in _reason */ +#define QEMU_SI_POLL 4 /* _poll is valid in _reason */ +#define QEMU_SI_CAPSICUM 5 /* _capsicum is valid in _reason */ + +#endif |