From: Warner Losh <imp@bsdimp.com>
To: qemu-devel@nongnu.org
Cc: Kyle Evans <kevans@freebsd.org>, Stacey Son <sson@FreeBSD.org>,
Warner Losh <imp@bsdimp.com>
Subject: [PATCH 29/30] bsd-user/signal.c: implement do_sigaction
Date: Sun, 9 Jan 2022 09:19:22 -0700 [thread overview]
Message-ID: <20220109161923.85683-30-imp@bsdimp.com> (raw)
In-Reply-To: <20220109161923.85683-1-imp@bsdimp.com>
Implement the meat of the sigaction(2) system call with do_sigaction and
helper routiner block_signals (which is also used to implemement signal
masking so it's global).
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
bsd-user/qemu.h | 21 +++++++++++++
bsd-user/signal.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index b8c64ca0e5b..c643d6ba246 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -226,8 +226,29 @@ int host_to_target_signal(int sig);
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
long do_sigreturn(CPUArchState *regs, abi_ulong addr);
+int do_sigaction(int sig, const struct target_sigaction *act,
+ struct target_sigaction *oact);
void QEMU_NORETURN force_sig(int target_sig);
int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
+/**
+ * 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 */
/* mmap.c */
int target_mprotect(abi_ulong start, abi_ulong len, int prot);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index d11f5eddd7e..f055d1db407 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -231,6 +231,22 @@ static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
}
}
+int block_signals(void)
+{
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
+ sigset_t set;
+
+ /*
+ * It's OK to block everything including SIGSEGV, because we won't run any
+ * further guest code before unblocking signals in
+ * process_pending_signals().
+ */
+ sigfillset(&set);
+ sigprocmask(SIG_SETMASK, &set, 0);
+
+ return qatomic_xchg(&ts->signal_pending, 1);
+}
+
/* Returns 1 if given signal should dump core if not handled. */
static int core_dump_signal(int sig)
{
@@ -534,6 +550,66 @@ static int fatal_signal(int sig)
}
}
+/* do_sigaction() return host values and errnos */
+int do_sigaction(int sig, const struct target_sigaction *act,
+ struct target_sigaction *oact)
+{
+ struct target_sigaction *k;
+ struct sigaction act1;
+ int host_sig;
+ int ret = 0;
+
+ if (sig < 1 || sig > TARGET_NSIG || TARGET_SIGKILL == sig ||
+ TARGET_SIGSTOP == sig) {
+ return -EINVAL;
+ }
+
+ if (block_signals()) {
+ return -TARGET_ERESTART;
+ }
+
+ k = &sigact_table[sig - 1];
+ if (oact) {
+ oact->_sa_handler = tswapal(k->_sa_handler);
+ oact->sa_flags = tswap32(k->sa_flags);
+ oact->sa_mask = k->sa_mask;
+ }
+ if (act) {
+ /* XXX: this is most likely not threadsafe. */
+ k->_sa_handler = tswapal(act->_sa_handler);
+ k->sa_flags = tswap32(act->sa_flags);
+ k->sa_mask = act->sa_mask;
+
+ /* Update the host signal state. */
+ host_sig = target_to_host_signal(sig);
+ if (host_sig != SIGSEGV && host_sig != SIGBUS) {
+ memset(&act1, 0, sizeof(struct sigaction));
+ sigfillset(&act1.sa_mask);
+ act1.sa_flags = SA_SIGINFO;
+ if (k->sa_flags & TARGET_SA_RESTART) {
+ act1.sa_flags |= SA_RESTART;
+ }
+ /*
+ * Note: It is important to update the host kernel signal mask to
+ * avoid getting unexpected interrupted system calls.
+ */
+ if (k->_sa_handler == TARGET_SIG_IGN) {
+ act1.sa_sigaction = (void *)SIG_IGN;
+ } else if (k->_sa_handler == TARGET_SIG_DFL) {
+ if (fatal_signal(sig)) {
+ act1.sa_sigaction = host_signal_handler;
+ } else {
+ act1.sa_sigaction = (void *)SIG_DFL;
+ }
+ } else {
+ act1.sa_sigaction = host_signal_handler;
+ }
+ ret = sigaction(host_sig, &act1, NULL);
+ }
+ }
+ return ret;
+}
+
static inline abi_ulong get_sigframe(struct target_sigaction *ka,
CPUArchState *regs, size_t frame_size)
{
--
2.33.1
next prev parent reply other threads:[~2022-01-09 16:31 UTC|newest]
Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
2022-01-13 15:47 ` Peter Maydell
2022-01-23 21:30 ` Richard Henderson
2022-01-09 16:18 ` [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault Warner Losh
2022-01-13 16:43 ` Peter Maydell
2022-01-23 21:36 ` Richard Henderson
2022-01-09 16:18 ` [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
2022-01-13 17:00 ` Peter Maydell
2022-01-23 21:38 ` Richard Henderson
2022-01-09 16:18 ` [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
2022-01-13 17:00 ` Peter Maydell
2022-01-23 21:38 ` Richard Henderson
2022-01-09 16:18 ` [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
2022-01-13 17:13 ` Peter Maydell
2022-01-14 6:33 ` Warner Losh
2022-01-23 21:40 ` Richard Henderson
2022-01-09 16:18 ` [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
2022-01-13 17:15 ` Peter Maydell
2022-01-14 6:38 ` Warner Losh
2022-01-14 10:22 ` Peter Maydell
2022-01-17 4:12 ` Warner Losh
2022-01-23 21:43 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
2022-01-13 17:19 ` Peter Maydell
2022-01-23 22:07 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
2022-01-13 17:40 ` Peter Maydell
2022-01-14 18:13 ` Warner Losh
2022-01-14 18:21 ` Peter Maydell
2022-01-24 1:12 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
2022-01-13 17:44 ` Peter Maydell
2022-01-14 18:27 ` Warner Losh
2022-01-09 16:19 ` [PATCH 10/30] bsd-user/signal.c: Implement signal_init() Warner Losh
2022-01-13 19:28 ` Peter Maydell
2022-01-14 18:51 ` Warner Losh
2022-01-24 1:38 ` Richard Henderson
2022-01-24 21:35 ` Warner Losh
2022-01-09 16:19 ` [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
2022-01-13 19:32 ` Peter Maydell
2022-01-17 3:53 ` Warner Losh
2022-01-09 16:19 ` [PATCH 12/30] bsd-user/host/i386/host-signal.h: " Warner Losh
2022-01-13 19:33 ` Peter Maydell
2022-01-24 1:49 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: " Warner Losh
2022-01-13 19:33 ` Peter Maydell
2022-01-24 1:52 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 14/30] bsd-user: Add host signals to the build Warner Losh
2022-01-13 19:35 ` Peter Maydell
2022-01-24 1:56 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 15/30] bsd-user: Add trace events for bsd-usr Warner Losh
2022-01-13 19:37 ` Peter Maydell
2022-01-24 1:57 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
2022-01-13 19:43 ` Peter Maydell
2022-01-15 6:19 ` Warner Losh
2022-01-15 11:08 ` Peter Maydell
2022-01-24 2:05 ` Richard Henderson
2022-01-24 21:45 ` Warner Losh
2022-01-09 16:19 ` [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
2022-01-13 19:44 ` Peter Maydell
2022-01-24 2:09 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler Warner Losh
2022-01-13 20:17 ` Peter Maydell
2022-01-16 20:52 ` Warner Losh
2022-01-09 16:19 ` [PATCH 19/30] bsd-user/strace.c: print_taken_signal Warner Losh
2022-01-13 20:20 ` Peter Maydell
2022-01-24 2:45 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 20/30] bsd-user/signal.c: core_dump_signal Warner Losh
2022-01-13 20:22 ` Peter Maydell
2022-01-13 20:28 ` Warner Losh
2022-01-13 20:40 ` Peter Maydell
2022-01-24 3:01 ` Richard Henderson
2022-01-09 16:19 ` [PATCH 21/30] bsd-user/signal.c: force_sig Warner Losh
2022-01-13 20:29 ` Peter Maydell
2022-01-13 20:53 ` Peter Maydell
2022-01-13 23:04 ` Kyle Evans
2022-01-18 22:27 ` Warner Losh
2022-01-09 16:19 ` [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal Warner Losh
2022-01-13 20:37 ` Peter Maydell
2022-01-17 16:22 ` Warner Losh
2022-01-17 16:33 ` Peter Maydell
2022-01-09 16:19 ` [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines Warner Losh
2022-01-14 11:13 ` Peter Maydell
2022-01-22 16:44 ` Warner Losh
2022-01-22 18:00 ` Kyle Evans
2022-01-09 16:19 ` [PATCH 24/30] bsd-user/signal.c: setup_frame Warner Losh
2022-01-14 11:40 ` Peter Maydell
2022-01-17 6:58 ` Warner Losh
2022-01-17 7:24 ` Warner Losh
2022-01-09 16:19 ` [PATCH 25/30] bsd-user/signal.c: handle_pending_signal Warner Losh
2022-01-14 11:50 ` Peter Maydell
2022-01-09 16:19 ` [PATCH 26/30] bsd-user/signal.c: tswap_siginfo Warner Losh
2022-01-14 11:54 ` Peter Maydell
2022-01-09 16:19 ` [PATCH 27/30] bsd-user/signal.c: process_pending_signals Warner Losh
2022-01-14 11:55 ` Peter Maydell
2022-01-17 2:09 ` Warner Losh
2022-01-09 16:19 ` [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn Warner Losh
2022-01-14 12:12 ` Peter Maydell
2022-01-09 16:19 ` Warner Losh [this message]
2022-01-14 13:13 ` [PATCH 29/30] bsd-user/signal.c: implement do_sigaction Peter Maydell
2022-01-09 16:19 ` [PATCH 30/30] bsd-user/signal.c: do_sigaltstack Warner Losh
2022-01-14 13:18 ` Peter Maydell
2022-01-22 22:20 ` Warner Losh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220109161923.85683-30-imp@bsdimp.com \
--to=imp@bsdimp.com \
--cc=kevans@freebsd.org \
--cc=qemu-devel@nongnu.org \
--cc=sson@FreeBSD.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).