summary refs log tree commit diff stats
path: root/bsd-user/qemu.h
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-01-31 20:20:54 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-01-31 20:20:54 +0000
commit5cbe64110dbe27f82d30552001acdc5eeaade11c (patch)
tree8ea1e2e5a9bb72419d8860ffe1a9cdb990e8229c /bsd-user/qemu.h
parent804b30d25f8d70dc2dea951883ea92235274a50c (diff)
parent1103d59caaa82c94b4223a5429c31895d2f05217 (diff)
downloadfocaccia-qemu-5cbe64110dbe27f82d30552001acdc5eeaade11c.tar.gz
focaccia-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/qemu.h')
-rw-r--r--bsd-user/qemu.h66
1 files changed, 43 insertions, 23 deletions
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 1b3b974afe..02921ac8b3 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -70,17 +70,9 @@ struct image_info {
     uint32_t  elf_flags;
 };
 
-#define MAX_SIGQUEUE_SIZE 1024
-
-struct qemu_sigqueue {
-    struct qemu_sigqueue *next;
-    target_siginfo_t info;
-};
-
 struct emulated_sigtable {
     int pending; /* true if signal is pending */
-    struct qemu_sigqueue *first;
-    struct qemu_sigqueue info;  /* Put first signal info here */
+    target_siginfo_t info;
 };
 
 /*
@@ -93,15 +85,39 @@ typedef struct TaskState {
     struct bsd_binprm *bprm;
     struct image_info *info;
 
+    struct emulated_sigtable sync_signal;
+    /*
+     * TODO: Since we block all signals while returning to the main CPU
+     * loop, this needn't be an array
+     */
     struct emulated_sigtable sigtab[TARGET_NSIG];
-    struct qemu_sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
-    struct qemu_sigqueue *first_free; /* first free siginfo queue entry */
-    int signal_pending; /* non zero if a signal may be pending */
-
-    uint8_t stack[];
+    /*
+     * Nonzero if process_pending_signals() needs to do something (either
+     * handle a pending signal or unblock signals).
+     * This flag is written from a signal handler so should be accessed via
+     * the qatomic_read() and qatomic_set() functions. (It is not accessed
+     * from multiple threads.)
+     */
+    int signal_pending;
+    /* True if we're leaving a sigsuspend and sigsuspend_mask is valid. */
+    bool in_sigsuspend;
+    /*
+     * This thread's signal mask, as requested by the guest program.
+     * The actual signal mask of this thread may differ:
+     *  + we don't let SIGSEGV and SIGBUS be blocked while running guest code
+     *  + sometimes we block all signals to avoid races
+     */
+    sigset_t signal_mask;
+    /*
+     * The signal mask imposed by a guest sigsuspend syscall, if we are
+     * currently in the middle of such a syscall
+     */
+    sigset_t sigsuspend_mask;
+
+    /* This thread's sigaltstack, if it has one */
+    struct target_sigaltstack sigaltstack_used;
 } __attribute__((aligned(16))) TaskState;
 
-void init_task_state(TaskState *ts);
 void stop_all_tasks(void);
 extern const char *qemu_uname_release;
 
@@ -201,16 +217,18 @@ print_openbsd_syscall(int num,
                       abi_long arg1, abi_long arg2, abi_long arg3,
                       abi_long arg4, abi_long arg5, abi_long arg6);
 void print_openbsd_syscall_ret(int num, abi_long ret);
+/**
+ * print_taken_signal:
+ * @target_signum: target signal being taken
+ * @tinfo: target_siginfo_t which will be passed to the guest for the signal
+ *
+ * Print strace output indicating that this signal is being taken by the guest,
+ * in a format similar to:
+ * --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+ */
+void print_taken_signal(int target_signum, const target_siginfo_t *tinfo);
 extern int do_strace;
 
-/* signal.c */
-void process_pending_signals(CPUArchState *cpu_env);
-void signal_init(void);
-long do_sigreturn(CPUArchState *env);
-long do_rt_sigreturn(CPUArchState *env);
-void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
-abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
-
 /* mmap.c */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
 abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
@@ -451,4 +469,6 @@ static inline void *lock_user_string(abi_ulong guest_addr)
 
 #include <pthread.h>
 
+#include "user/safe-syscall.h"
+
 #endif /* QEMU_H */