All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/40] bsd-user: upstream signal implementation
@ 2022-01-28 23:27 Warner Losh
  2022-01-28 23:27 ` [PATCH v3 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
                   ` (39 more replies)
  0 siblings, 40 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

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.

All the patches have been reviewed by at least one person, except these hunks:
    bsd-user/signal.c: implement do_sigaction
    bsd-user/signal.c: implement do_sigreturn
though more eyes on any if these changes is quite welcome. All the patches have
also been forward ported to the bsd-user 'blitz' branch and we now pass more
tests there than we did before (though it's only back up to a similar number of
tests to our ancient rebase-3.2 version).

New in version 3:

o Fixed do_sigcation to allow querying of SIGKILL or SIGSTOP.
o Fixed host/target confusion for do_sigaction return codes. Also added comments
  about why we use sigprocmask(2) instead of pthread_sigmask(3) since a question
  about this came up in review.
o For do_sigreturn, don't set the actual signal mask, but instead defer that
  to the main loop to avoid races with signals that are newly active, but
  blocked by the signal handler's signal mask and the main loop, as is done
  in linux-user.
o Fixed or added a number of comments based on review feedback for typos or todo
  items.
o bsd-user/signal-common.h: Move signal functions prototypes to here
  Move includes of signal-common.h to this patch hunk in */target_arch_cpu.h to fix
  compile issues.
o Also, rebased to current tip of master and fixed a minor conflict or two (which
  should get rid of the does not apply warning on patchew).

Patchew history: https://patchew.org/QEMU/20220125012947.14974-1-imp@bsdimp.com/

Warner Losh (40):
  bsd-user: Complete FreeBSD siginfo
  bsd-user: Create setup_sigframe_arch to setup sigframe context
  bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm
  bsd-user/arm/signal.c: get_mcontext should zero vfp data
  bsd-user: Remove vestiges of signal queueing code
  bsd-user: Bring in docs from linux-user for signal_pending
  bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user
  bsd-user/signal.c: implement force_sig_fault
  bsd-user/signal-common.h: Move signal functions prototypes to here
  bsd-user/signal.c: Implement cpu_loop_exit_sigsegv
  bsd-user/signal.c: implement cpu_loop_exit_sigbus
  bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  bsd-user/arm/target_arch_cpu.h: Correct code pointer
  bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  bsd-user/arm/target_arch_cpu.h: Implement data faults
  bsd-user/signal.c: implement abstract target / host signal translation
  bsd-user/signal.c: Implement signal_init()
  bsd-user/signal.c: Add si_type argument to queue_signal
  bsd-user/host/arm/host-signal.h: Implement host_signal_*
  bsd-user/host/i386/host-signal.h: Implement host_signal_*
  bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
  bsd-user: Add host signals to the build
  bsd-user: Add trace events for bsd-user
  bsd-user/signal.c: host_to_target_siginfo_noswap
  bsd-user/signal.c: Implement rewind_if_in_safe_syscall
  bsd-user/signal.c: Implement host_signal_handler
  bsd-user/strace.c: print_taken_signal
  bsd-user/signal.c: Implement dump_core_and_abort
  bsd-user/signal.c: Fill in queue_signal
  bsd-user/signal.c: sigset manipulation routines.
  bsd-user/signal.c: setup_frame
  bsd-user/signal.c: handle_pending_signal
  bsd-user/signal.c: tswap_siginfo
  bsd-user/signal.c: process_pending_signals
  bsd-user/signal.c: implement do_sigreturn
  bsd-user/signal.c: implement do_sigaction
  bsd-user/signal.c: do_sigaltstack
  MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on
  bsd-user: Rename arg name for target_cpu_reset to env
  bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for
    CPUArchState args

 MAINTAINERS                           |    1 +
 bsd-user/arm/signal.c                 |   59 +-
 bsd-user/arm/target_arch_cpu.h        |  101 +--
 bsd-user/freebsd/target_os_siginfo.h  |   15 +-
 bsd-user/freebsd/target_os_signal.h   |    3 +
 bsd-user/freebsd/target_os_ucontext.h |    6 +-
 bsd-user/host/arm/host-signal.h       |   35 +
 bsd-user/host/i386/host-signal.h      |   37 +
 bsd-user/host/x86_64/host-signal.h    |   37 +
 bsd-user/i386/signal.c                |   13 +
 bsd-user/i386/target_arch_cpu.h       |    5 +-
 bsd-user/main.c                       |   14 +-
 bsd-user/qemu.h                       |   66 +-
 bsd-user/signal-common.h              |   70 ++
 bsd-user/signal.c                     | 1008 ++++++++++++++++++++++++-
 bsd-user/strace.c                     |   97 +++
 bsd-user/syscall_defs.h               |    1 +
 bsd-user/trace-events                 |   11 +
 bsd-user/trace.h                      |    1 +
 bsd-user/x86_64/signal.c              |   13 +
 bsd-user/x86_64/target_arch_cpu.h     |    5 +-
 meson.build                           |    6 +-
 22 files changed, 1490 insertions(+), 114 deletions(-)
 create mode 100644 bsd-user/host/arm/host-signal.h
 create mode 100644 bsd-user/host/i386/host-signal.h
 create mode 100644 bsd-user/host/x86_64/host-signal.h
 create mode 100644 bsd-user/signal-common.h
 create mode 100644 bsd-user/trace-events
 create mode 100644 bsd-user/trace.h

-- 
2.33.1



^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH v3 01/40] bsd-user: Complete FreeBSD siginfo
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context Warner Losh
                   ` (38 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Fill in the missing FreeBSD siginfo fields, and add some comments.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/freebsd/target_os_siginfo.h | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/bsd-user/freebsd/target_os_siginfo.h b/bsd-user/freebsd/target_os_siginfo.h
index 84944faa4d3..d50a3034a88 100644
--- a/bsd-user/freebsd/target_os_siginfo.h
+++ b/bsd-user/freebsd/target_os_siginfo.h
@@ -71,11 +71,24 @@ typedef struct target_siginfo {
             int32_t _mqd;
         } _mesgp;
 
-        /* SIGPOLL */
+        /* SIGPOLL -- Not really genreated in FreeBSD ??? */
         struct {
             int _band;  /* POLL_IN, POLL_OUT, POLL_MSG */
         } _poll;
 
+        struct {
+            int _mqd;
+        } _mesgq;
+
+        struct {
+            /*
+             * Syscall number for signals delivered as a result of system calls
+             * denied by Capsicum.
+             */
+            int _syscall;
+        } _capsicum;
+
+        /* Spare for future growth */
         struct {
             abi_long __spare1__;
             int32_t  __spare2_[7];
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
  2022-01-28 23:27 ` [PATCH v3 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm Warner Losh
                   ` (37 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Define setup_sigframe_arch whose job it is to setup the mcontext for the
sigframe. Implement for x86 to just call mcontext.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/freebsd/target_os_signal.h |  3 +++
 bsd-user/i386/signal.c              | 13 +++++++++++++
 bsd-user/x86_64/signal.c            | 13 +++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/bsd-user/freebsd/target_os_signal.h b/bsd-user/freebsd/target_os_signal.h
index 3ed454e086d..43700d08f71 100644
--- a/bsd-user/freebsd/target_os_signal.h
+++ b/bsd-user/freebsd/target_os_signal.h
@@ -4,6 +4,9 @@
 #include "target_os_siginfo.h"
 #include "target_arch_signal.h"
 
+abi_long setup_sigframe_arch(CPUArchState *env, abi_ulong frame_addr,
+                             struct target_sigframe *frame, int flags);
+
 /* Compare to sys/signal.h */
 #define TARGET_SIGHUP  1       /* hangup */
 #define TARGET_SIGINT  2       /* interrupt */
diff --git a/bsd-user/i386/signal.c b/bsd-user/i386/signal.c
index 2939d32400c..5dd975ce56a 100644
--- a/bsd-user/i386/signal.c
+++ b/bsd-user/i386/signal.c
@@ -32,6 +32,19 @@ abi_long set_sigtramp_args(CPUX86State *env, int sig,
     return 0;
 }
 
+/*
+ * Compare to i386/i386/exec_machdep.c sendsig()
+ * Assumes that the memory is locked if frame points to user memory.
+ */
+abi_long setup_sigframe_arch(CPUX86State *env, abi_ulong frame_addr,
+                             struct target_sigframe *frame, int flags)
+{
+    target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
+
+    get_mcontext(env, mcp, flags);
+    return 0;
+}
+
 /* Compare to i386/i386/machdep.c get_mcontext() */
 abi_long get_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int flags)
 {
diff --git a/bsd-user/x86_64/signal.c b/bsd-user/x86_64/signal.c
index 8885152a7da..c3875bc4c6a 100644
--- a/bsd-user/x86_64/signal.c
+++ b/bsd-user/x86_64/signal.c
@@ -30,6 +30,19 @@ abi_long set_sigtramp_args(CPUX86State *regs,
     return 0;
 }
 
+/*
+ * Compare to amd64/amd64/exec_machdep.c sendsig()
+ * Assumes that the memory is locked if frame points to user memory.
+ */
+abi_long setup_sigframe_arch(CPUX86State *env, abi_ulong frame_addr,
+                             struct target_sigframe *frame, int flags)
+{
+    target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
+
+    get_mcontext(env, mcp, flags);
+    return 0;
+}
+
 /* Compare to amd64/amd64/machdep.c get_mcontext() */
 abi_long get_mcontext(CPUX86State *regs,
                 target_mcontext_t *mcp, int flags)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
  2022-01-28 23:27 ` [PATCH v3 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
  2022-01-28 23:27 ` [PATCH v3 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data Warner Losh
                   ` (36 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Fix the broken context setting for arm. FreeBSD's get_mcontext does not
fill in the vfp info. It's filled in in sigframe(). This corresponds to
the new setup_sigframe_arch which fills in mcontext, then adjusts it to
point to the vfp context in the sigframe and fills in that context as
well. Add pointer to where this code is done.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/signal.c | 50 ++++++++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index 1478f008d13..9026343b478 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -59,19 +59,31 @@ abi_long set_sigtramp_args(CPUARMState *env, int sig,
     return 0;
 }
 
+static abi_long get_vfpcontext(CPUARMState *env, abi_ulong frame_addr,
+                               struct target_sigframe *frame)
+{
+    /* see sendsig and get_vfpcontext in sys/arm/arm/exec_machdep.c */
+    target_mcontext_vfp_t *vfp = &frame->sf_vfp;
+    target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
+
+    /* Assumes that mcp and vfp are locked */
+    for (int i = 0; i < 32; i++) {
+        vfp->mcv_reg[i] = tswap64(*aa32_vfp_dreg(env, i));
+    }
+    vfp->mcv_fpscr = tswap32(vfp_get_fpscr(env));
+    mcp->mc_vfp_size = tswap32(sizeof(*vfp));
+    mcp->mc_vfp_ptr = tswap32(frame_addr + ((uintptr_t)vfp - (uintptr_t)frame));
+    return 0;
+}
+
 /*
- * Compare to arm/arm/machdep.c get_mcontext()
+ * Compare to arm/arm/exec_machdep.c get_mcontext()
  * Assumes that the memory is locked if mcp points to user memory.
  */
 abi_long get_mcontext(CPUARMState *env, target_mcontext_t *mcp, int flags)
 {
-    int err = 0;
     uint32_t *gr = mcp->__gregs;
 
-    if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != sizeof(target_mcontext_vfp_t)) {
-        return -TARGET_EINVAL;
-    }
-
     gr[TARGET_REG_CPSR] = tswap32(cpsr_read(env));
     if (flags & TARGET_MC_GET_CLEAR_RET) {
         gr[TARGET_REG_R0] = 0;
@@ -97,17 +109,21 @@ abi_long get_mcontext(CPUARMState *env, target_mcontext_t *mcp, int flags)
     gr[TARGET_REG_LR] = tswap32(env->regs[14]);
     gr[TARGET_REG_PC] = tswap32(env->regs[15]);
 
-    if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr != 0) {
-        /* see get_vfpcontext in sys/arm/arm/exec_machdep.c */
-        target_mcontext_vfp_t *vfp;
-        vfp = lock_user(VERIFY_WRITE, mcp->mc_vfp_ptr, sizeof(*vfp), 0);
-        for (int i = 0; i < 32; i++) {
-            vfp->mcv_reg[i] = tswap64(*aa32_vfp_dreg(env, i));
-        }
-        vfp->mcv_fpscr = tswap32(vfp_get_fpscr(env));
-        unlock_user(vfp, mcp->mc_vfp_ptr, sizeof(*vfp));
-    }
-    return err;
+    return 0;
+}
+
+/*
+ * Compare to arm/arm/exec_machdep.c sendsig()
+ * Assumes that the memory is locked if frame points to user memory.
+ */
+abi_long setup_sigframe_arch(CPUARMState *env, abi_ulong frame_addr,
+                             struct target_sigframe *frame, int flags)
+{
+    target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
+
+    get_mcontext(env, mcp, flags);
+    get_vfpcontext(env, frame_addr, frame);
+    return 0;
 }
 
 /* Compare to arm/arm/exec_machdep.c set_mcontext() */
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (2 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 05/40] bsd-user: Remove vestiges of signal queueing code Warner Losh
                   ` (35 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

FreeBSD's get_mcontext doesn't return any vfp data. Instead, it zeros
out the vfp feilds (and all the spare fields). Impelement this
behavior. We're still missing the sysarch(ARM_GET_VFPCONTEXT) syscall,
though.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/signal.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index 9026343b478..2b1dd745d13 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -109,6 +109,15 @@ abi_long get_mcontext(CPUARMState *env, target_mcontext_t *mcp, int flags)
     gr[TARGET_REG_LR] = tswap32(env->regs[14]);
     gr[TARGET_REG_PC] = tswap32(env->regs[15]);
 
+    /*
+     * FreeBSD's get_mcontext doesn't save VFP info, but sets the pointer and
+     * size to zero.  Applications that need the VFP state use
+     * sysarch(ARM_GET_VFPSTATE) and are expected to adjust mcontext after that.
+     */
+    mcp->mc_vfp_size = 0;
+    mcp->mc_vfp_ptr = 0;
+    memset(&mcp->mc_spare, 0, sizeof(mcp->mc_spare));
+
     return 0;
 }
 
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 05/40] bsd-user: Remove vestiges of signal queueing code
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (3 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 06/40] bsd-user: Bring in docs from linux-user for signal_pending Warner Losh
                   ` (34 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

bsd-user was copied from linux-user at a time when it queued
signals. Remove those vestiges of thse code. Retain the init function,
even though it's now empty since other stuff will likely be added
there. Make it static since it's not called from outside of main.c

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/main.c |  9 +--------
 bsd-user/qemu.h | 13 +------------
 2 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index cb5ea402361..29cf4e15693 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -215,15 +215,8 @@ void qemu_cpu_kick(CPUState *cpu)
 }
 
 /* Assumes contents are already zeroed.  */
-void init_task_state(TaskState *ts)
+static void init_task_state(TaskState *ts)
 {
-    int i;
-
-    ts->first_free = ts->sigqueue_table;
-    for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
-        ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
-    }
-    ts->sigqueue_table[i].next = NULL;
 }
 
 void gemu_log(const char *fmt, ...)
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 1b3b974afe9..4dd209e402d 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;
 };
 
 /*
@@ -94,14 +86,11 @@ typedef struct TaskState {
     struct image_info *info;
 
     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[];
 } __attribute__((aligned(16))) TaskState;
 
-void init_task_state(TaskState *ts);
 void stop_all_tasks(void);
 extern const char *qemu_uname_release;
 
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 06/40] bsd-user: Bring in docs from linux-user for signal_pending
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (4 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 05/40] bsd-user: Remove vestiges of signal queueing code Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
                   ` (33 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

This is currently unused, so no code adjustments are needed.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/qemu.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 4dd209e402d..671b26f00cc 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -86,7 +86,14 @@ typedef struct TaskState {
     struct image_info *info;
 
     struct emulated_sigtable sigtab[TARGET_NSIG];
-    int signal_pending; /* non zero if a signal may be pending */
+    /*
+     * 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;
 
     uint8_t stack[];
 } __attribute__((aligned(16))) TaskState;
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (5 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 06/40] bsd-user: Bring in docs from linux-user for signal_pending Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 08/40] bsd-user/signal.c: implement force_sig_fault Warner Losh
                   ` (32 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Move the EXCP_ATOMIC case to match linux-user/arm/cpu_loop.c:cpu_loop
ordering.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index c675419c30a..c526fc73502 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -180,12 +180,12 @@ static inline void target_cpu_loop(CPUARMState *env)
                 queue_signal(env, info.si_signo, &info);
             }
             break;
-        case EXCP_ATOMIC:
-            cpu_exec_step_atomic(cs);
-            break;
         case EXCP_YIELD:
             /* nothing to do here for user-mode, just resume guest code */
             break;
+        case EXCP_ATOMIC:
+            cpu_exec_step_atomic(cs);
+            break;
         default:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 08/40] bsd-user/signal.c: implement force_sig_fault
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (6 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here Warner Losh
                   ` (31 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Start to implement the force_sig_fault code. This currently just calls
queue_signal(). The bsd-user fork version of that will handle this the
synchronous nature of this call. Add signal-common.h to hold signal
helper functions like force_sig_fault.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal-common.h | 14 ++++++++++++++
 bsd-user/signal.c        | 18 ++++++++++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 bsd-user/signal-common.h

diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
new file mode 100644
index 00000000000..6207417d39e
--- /dev/null
+++ b/bsd-user/signal-common.h
@@ -0,0 +1,14 @@
+/*
+ * 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
+
+void force_sig_fault(int sig, int code, abi_ulong addr);
+
+#endif
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 05b277c6422..1206d0d728c 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu.h"
+#include "signal-common.h"
 
 /*
  * Stubbed out routines until we merge signal support from bsd-user
@@ -34,6 +35,23 @@ void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
     qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig);
 }
 
+/*
+ * 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.si_addr = addr;
+    queue_signal(env, sig, &info);
+}
+
 void signal_init(void)
 {
 }
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (7 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 08/40] bsd-user/signal.c: implement force_sig_fault Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
                   ` (30 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h    | 1 +
 bsd-user/i386/target_arch_cpu.h   | 1 +
 bsd-user/qemu.h                   | 8 --------
 bsd-user/signal-common.h          | 6 ++++++
 bsd-user/x86_64/target_arch_cpu.h | 1 +
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index c526fc73502..b7f728fd667 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -21,6 +21,7 @@
 #define _TARGET_ARCH_CPU_H_
 
 #include "target_arch.h"
+#include "signal-common.h"
 
 #define TARGET_DEFAULT_CPU_MODEL "any"
 
diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h
index b28602adbbd..472a96689fc 100644
--- a/bsd-user/i386/target_arch_cpu.h
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -20,6 +20,7 @@
 #define _TARGET_ARCH_CPU_H_
 
 #include "target_arch.h"
+#include "signal-common.h"
 
 #define TARGET_DEFAULT_CPU_MODEL "qemu32"
 
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 671b26f00cc..99c37fc9942 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -199,14 +199,6 @@ print_openbsd_syscall(int num,
 void print_openbsd_syscall_ret(int num, abi_long ret);
 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,
diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
index 6207417d39e..f9a9d1e01aa 100644
--- a/bsd-user/signal-common.h
+++ b/bsd-user/signal-common.h
@@ -9,6 +9,12 @@
 #ifndef SIGNAL_COMMON_H
 #define SIGNAL_COMMON_H
 
+long do_rt_sigreturn(CPUArchState *env);
+abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
+long do_sigreturn(CPUArchState *env);
 void force_sig_fault(int sig, int code, abi_ulong addr);
+void process_pending_signals(CPUArchState *env);
+void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
+void signal_init(void);
 
 #endif
diff --git a/bsd-user/x86_64/target_arch_cpu.h b/bsd-user/x86_64/target_arch_cpu.h
index 5172b230f09..14def48adb5 100644
--- a/bsd-user/x86_64/target_arch_cpu.h
+++ b/bsd-user/x86_64/target_arch_cpu.h
@@ -20,6 +20,7 @@
 #define _TARGET_ARCH_CPU_H_
 
 #include "target_arch.h"
+#include "signal-common.h"
 
 #define TARGET_DEFAULT_CPU_MODEL "qemu64"
 
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (8 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
                   ` (29 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

First attempt at implementing cpu_loop_exit_sigsegv, mostly copied from
linux-user version of this function.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 1206d0d728c..12de0e2dea4 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu.h"
 #include "signal-common.h"
+#include "hw/core/tcg-cpu-ops.h"
 
 /*
  * Stubbed out routines until we merge signal support from bsd-user
@@ -63,9 +64,17 @@ void process_pending_signals(CPUArchState *cpu_env)
 void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
                            MMUAccessType access_type, bool maperr, uintptr_t ra)
 {
-    qemu_log_mask(LOG_UNIMP, "No signal support for SIGSEGV\n");
-    /* unreachable */
-    abort();
+    const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
+
+    if (tcg_ops->record_sigsegv) {
+        tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
+    }
+
+    force_sig_fault(TARGET_SIGSEGV,
+                    maperr ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR,
+                    addr);
+    cpu->exception_index = EXCP_INTERRUPT;
+    cpu_loop_exit_restore(cpu, ra);
 }
 
 void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (9 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
                   ` (28 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

First attempt at implementing cpu_loop_exit_sigbus, mostly copied from
linux-user version of this function.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 12de0e2dea4..844dfa19095 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -80,7 +80,13 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
 void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
                           MMUAccessType access_type, uintptr_t ra)
 {
-    qemu_log_mask(LOG_UNIMP, "No signal support for SIGBUS\n");
-    /* unreachable */
-    abort();
+    const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
+
+    if (tcg_ops->record_sigbus) {
+        tcg_ops->record_sigbus(cpu, addr, access_type, ra);
+    }
+
+    force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, addr);
+    cpu->exception_index = EXCP_INTERRUPT;
+    cpu_loop_exit_restore(cpu, ra);
 }
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (10 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
                   ` (27 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Implement EXCP_DEBUG and EXCP_BKPT the same, as is done in
linux-user. The prior adjustment of register 15 isn't needed, so remove
that. Remove a redunant comment (that code in FreeBSD never handled
break points). It's unclear why BKPT was an alias for system calls,
but FreeBSD doesn't do that today.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index b7f728fd667..05b19ce6119 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -65,19 +65,7 @@ static inline void target_cpu_loop(CPUARMState *env)
             }
             break;
         case EXCP_SWI:
-        case EXCP_BKPT:
             {
-                /*
-                 * system call
-                 * See arm/arm/trap.c cpu_fetch_syscall_args()
-                 */
-                if (trapnr == EXCP_BKPT) {
-                    if (env->thumb) {
-                        env->regs[15] += 2;
-                    } else {
-                        env->regs[15] += 4;
-                    }
-                }
                 n = env->regs[7];
                 if (bsd_type == target_freebsd) {
                     int ret;
@@ -172,14 +160,8 @@ static inline void target_cpu_loop(CPUARMState *env)
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_DEBUG:
-            {
-
-                info.si_signo = TARGET_SIGTRAP;
-                info.si_errno = 0;
-                info.si_code = TARGET_TRAP_BRKPT;
-                info.si_addr = env->exception.vaddress;
-                queue_signal(env, info.si_signo, &info);
-            }
+        case EXCP_BKPT:
+            force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[15]);
             break;
         case EXCP_YIELD:
             /* nothing to do here for user-mode, just resume guest code */
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (11 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
                   ` (26 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

The code has moved in FreeBSD since the emulator was started, update the
comment to reflect that change.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 05b19ce6119..905f13aa1b9 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -73,7 +73,7 @@ static inline void target_cpu_loop(CPUARMState *env)
                     int32_t syscall_nr = n;
                     int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
 
-                    /* See arm/arm/trap.c cpu_fetch_syscall_args() */
+                    /* See arm/arm/syscall.c cpu_fetch_syscall_args() */
                     if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
                         syscall_nr = env->regs[0];
                         arg1 = env->regs[1];
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (12 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
                   ` (25 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Use force_sig_fault to implement unknown opcode. This just uninlines
that function, so simplify things by using it. Fold in EXCP_NOCP and
EXCP_INVSTATE, as is done in linux-user. Make a note about slight
differences with FreeBSD in case any of them turn out to be important
later.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 905f13aa1b9..9d790176420 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -51,18 +51,19 @@ static inline void target_cpu_loop(CPUARMState *env)
         process_queued_cpu_work(cs);
         switch (trapnr) {
         case EXCP_UDEF:
-            {
-                /* See arm/arm/undefined.c undefinedinstruction(); */
-                info.si_addr = env->regs[15];
-
-                /* illegal instruction */
-                info.si_signo = TARGET_SIGILL;
-                info.si_errno = 0;
-                info.si_code = TARGET_ILL_ILLOPC;
-                queue_signal(env, info.si_signo, &info);
-
-                /* TODO: What about instruction emulation? */
-            }
+        case EXCP_NOCP:
+        case EXCP_INVSTATE:
+            /*
+             * See arm/arm/undefined.c undefinedinstruction();
+             *
+             * A number of details aren't emulated (they likely don't matter):
+             * o Misaligned PC generates ILL_ILLADR (these can't come from qemu)
+             * o Thumb-2 instructions generate ILLADR
+             * o Both modes implement coprocessor instructions, which we don't
+             *   do here. FreeBSD just implements them for the VFP coprocessor
+             *   and special kernel breakpoints, trace points, dtrace, etc.
+             */
+            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->regs[15]);
             break;
         case EXCP_SWI:
             {
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (13 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 16/40] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
                   ` (24 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Update for the richer set of data faults that are now possible. Copied
largely from linux-user/arm/cpu_loop.c, with minor typo fixes.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h | 45 ++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 9d790176420..2b395d5c97f 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -39,8 +39,7 @@ static inline void target_cpu_init(CPUARMState *env,
 
 static inline void target_cpu_loop(CPUARMState *env)
 {
-    int trapnr;
-    target_siginfo_t info;
+    int trapnr, si_signo, si_code;
     unsigned int n;
     CPUState *cs = env_cpu(env);
 
@@ -150,15 +149,41 @@ static inline void target_cpu_loop(CPUARMState *env)
             /* just indicate that signals should be handled asap */
             break;
         case EXCP_PREFETCH_ABORT:
-            /* See arm/arm/trap.c prefetch_abort_handler() */
         case EXCP_DATA_ABORT:
-            /* See arm/arm/trap.c data_abort_handler() */
-            info.si_signo = TARGET_SIGSEGV;
-            info.si_errno = 0;
-            /* XXX: check env->error_code */
-            info.si_code = 0;
-            info.si_addr = env->exception.vaddress;
-            queue_signal(env, info.si_signo, &info);
+            /*
+             * See arm/arm/trap-v6.c prefetch_abort_handler() and
+             * data_abort_handler()
+             *
+             * However, FreeBSD maps these to a generic value and then uses that
+             * to maybe fault in pages in vm/vm_fault.c:vm_fault_trap(). I
+             * believe that the indirection maps the same as Linux, but haven't
+             * chased down every single possible indirection.
+             */
+
+            /* For user-only we don't set TTBCR_EAE, so look at the FSR. */
+            switch (env->exception.fsr & 0x1f) {
+            case 0x1: /* Alignment */
+                si_signo = TARGET_SIGBUS;
+                si_code = TARGET_BUS_ADRALN;
+                break;
+            case 0x3: /* Access flag fault, level 1 */
+            case 0x6: /* Access flag fault, level 2 */
+            case 0x9: /* Domain fault, level 1 */
+            case 0xb: /* Domain fault, level 2 */
+            case 0xd: /* Permission fault, level 1 */
+            case 0xf: /* Permission fault, level 2 */
+                si_signo = TARGET_SIGSEGV;
+                si_code = TARGET_SEGV_ACCERR;
+                break;
+            case 0x5: /* Translation fault, level 1 */
+            case 0x7: /* Translation fault, level 2 */
+                si_signo = TARGET_SIGSEGV;
+                si_code = TARGET_SEGV_MAPERR;
+                break;
+            default:
+                g_assert_not_reached();
+            }
+            force_sig_fault(si_signo, si_code, env->exception.vaddress);
             break;
         case EXCP_DEBUG:
         case EXCP_BKPT:
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 16/40] bsd-user/signal.c: implement abstract target / host signal translation
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (14 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 17/40] bsd-user/signal.c: Implement signal_init() Warner Losh
                   ` (23 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Implement host_to_target_signal and target_to_host_signal.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal-common.h |  2 ++
 bsd-user/signal.c        | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
index f9a9d1e01aa..efed23d9efb 100644
--- a/bsd-user/signal-common.h
+++ b/bsd-user/signal-common.h
@@ -13,8 +13,10 @@ long do_rt_sigreturn(CPUArchState *env);
 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
 long do_sigreturn(CPUArchState *env);
 void force_sig_fault(int sig, int code, abi_ulong addr);
+int host_to_target_signal(int sig);
 void process_pending_signals(CPUArchState *env);
 void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
 void signal_init(void);
+int target_to_host_signal(int sig);
 
 #endif
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 844dfa19095..1313baec96a 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -2,6 +2,7 @@
  *  Emulation of BSD signals
  *
  *  Copyright (c) 2003 - 2008 Fabrice Bellard
+ *  Copyright (c) 2013 Stacey Son
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -27,6 +28,21 @@
  * fork.
  */
 
+/*
+ * The BSD ABIs use the same singal numbers across all the CPU architectures, so
+ * (unlike Linux) these functions are just the identity mapping. This might not
+ * be true for XyzBSD running on AbcBSD, which doesn't currently work.
+ */
+int host_to_target_signal(int sig)
+{
+    return sig;
+}
+
+int target_to_host_signal(int sig)
+{
+    return sig;
+}
+
 /*
  * Queue a signal so that it will be send to the virtual CPU as soon as
  * possible.
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 17/40] bsd-user/signal.c: Implement signal_init()
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (15 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 16/40] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 18/40] bsd-user/signal.c: Add si_type argument to queue_signal Warner Losh
                   ` (22 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Initialize the signal state for the emulator. Setup a set of sane
default signal handlers, mirroring the host's signals. For fatal signals
(those that exit by default), establish our own set of signal
handlers. Stub out the actual signal handler we use for the moment.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org> XXX SIGPROF PENDING
---
 bsd-user/qemu.h   |  7 +++++
 bsd-user/signal.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 99c37fc9942..49f01932a53 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -94,6 +94,13 @@ typedef struct TaskState {
      * from multiple threads.)
      */
     int signal_pending;
+    /*
+     * 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;
 
     uint8_t stack[];
 } __attribute__((aligned(16))) TaskState;
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 1313baec96a..3ef7cf5e23c 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -28,6 +28,9 @@
  * fork.
  */
 
+static struct target_sigaction sigact_table[TARGET_NSIG];
+static void host_signal_handler(int host_sig, siginfo_t *info, void *puc);
+
 /*
  * The BSD ABIs use the same singal numbers across all the CPU architectures, so
  * (unlike Linux) these functions are just the identity mapping. This might not
@@ -52,6 +55,28 @@ void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
     qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig);
 }
 
+static int fatal_signal(int sig)
+{
+
+    switch (sig) {
+    case TARGET_SIGCHLD:
+    case TARGET_SIGURG:
+    case TARGET_SIGWINCH:
+    case TARGET_SIGINFO:
+        /* Ignored by default. */
+        return 0;
+    case TARGET_SIGCONT:
+    case TARGET_SIGSTOP:
+    case TARGET_SIGTSTP:
+    case TARGET_SIGTTIN:
+    case TARGET_SIGTTOU:
+        /* Job control signals.  */
+        return 0;
+    default:
+        return 1;
+    }
+}
+
 /*
  * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
  * 'force' part is handled in process_pending_signals().
@@ -69,8 +94,50 @@ void force_sig_fault(int sig, int code, abi_ulong addr)
     queue_signal(env, sig, &info);
 }
 
+static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
+{
+}
+
 void signal_init(void)
 {
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+    struct sigaction act;
+    struct sigaction oact;
+    int i;
+    int host_sig;
+
+    /* Set the signal mask from the host mask. */
+    sigprocmask(0, 0, &ts->signal_mask);
+
+    sigfillset(&act.sa_mask);
+    act.sa_sigaction = host_signal_handler;
+    act.sa_flags = SA_SIGINFO;
+
+    for (i = 1; i <= TARGET_NSIG; i++) {
+#ifdef CONFIG_GPROF
+        if (i == TARGET_SIGPROF) {
+            continue;
+        }
+#endif
+        host_sig = target_to_host_signal(i);
+        sigaction(host_sig, NULL, &oact);
+        if (oact.sa_sigaction == (void *)SIG_IGN) {
+            sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
+        } else if (oact.sa_sigaction == (void *)SIG_DFL) {
+            sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
+        }
+        /*
+         * If there's already a handler installed then something has
+         * gone horribly wrong, so don't even try to handle that case.
+         * Install some handlers for our own use.  We need at least
+         * SIGSEGV and SIGBUS, to detect exceptions.  We can not just
+         * trap all signals because it affects syscall interrupt
+         * behavior.  But do trap all default-fatal signals.
+         */
+        if (fatal_signal(i)) {
+            sigaction(host_sig, &act, NULL);
+        }
+    }
 }
 
 void process_pending_signals(CPUArchState *cpu_env)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 18/40] bsd-user/signal.c: Add si_type argument to queue_signal
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (16 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 17/40] bsd-user/signal.c: Implement signal_init() Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
                   ` (21 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Mirror the linux-user practice and add a si_type argument to queue
signal. This will be transported as the upper 8 bits in the si_type
element of siginfo so that we know what bits of the structure are valid
and so we can properly implement host_to_target_siginfo_noswap and
tswap_siginfo. Adapt the one caller of queue_signal to the new
interface.  Use all the same names as Linux (except _RT which we don't
treat differently, unlike Linux), though some are unused. Place this
into signal-common.h since that's a better place given bsd-user's
structure. Move prototype of queue_signal to signal-common.h to mirror
linux-user's location.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal-common.h | 26 +++++++++++++++++++++++++-
 bsd-user/signal.c        |  5 +++--
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
index efed23d9efb..80e9503238a 100644
--- a/bsd-user/signal-common.h
+++ b/bsd-user/signal-common.h
@@ -15,8 +15,32 @@ long do_sigreturn(CPUArchState *env);
 void force_sig_fault(int sig, int code, abi_ulong addr);
 int host_to_target_signal(int sig);
 void process_pending_signals(CPUArchState *env);
-void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
+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);
 
+/*
+ * 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
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 3ef7cf5e23c..ad8437a8bfb 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -50,7 +50,8 @@ int target_to_host_signal(int sig)
  * Queue a signal so that it will be send to the virtual CPU as soon as
  * possible.
  */
-void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
+void queue_signal(CPUArchState *env, int sig, int si_type,
+                  target_siginfo_t *info)
 {
     qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig);
 }
@@ -91,7 +92,7 @@ void force_sig_fault(int sig, int code, abi_ulong addr)
     info.si_errno = 0;
     info.si_code = code;
     info.si_addr = addr;
-    queue_signal(env, sig, &info);
+    queue_signal(env, sig, QEMU_SI_FAULT, &info);
 }
 
 static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_*
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (17 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 18/40] bsd-user/signal.c: Add si_type argument to queue_signal Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 20/40] bsd-user/host/i386/host-signal.h: " Warner Losh
                   ` (20 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Implement host_signal_pc, host_signal_set_pc and host_signal_write for
arm.

Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/host/arm/host-signal.h | 35 +++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 bsd-user/host/arm/host-signal.h

diff --git a/bsd-user/host/arm/host-signal.h b/bsd-user/host/arm/host-signal.h
new file mode 100644
index 00000000000..56679bd6993
--- /dev/null
+++ b/bsd-user/host/arm/host-signal.h
@@ -0,0 +1,35 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2021 Warner Losh
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ARM_HOST_SIGNAL_H
+#define ARM_HOST_SIGNAL_H
+
+#include <sys/ucontext.h>
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.__gregs[_REG_PC];
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.__gregs[_REG_PC] = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    /*
+     * In the FSR, bit 11 is WnR. FreeBSD returns this as part of the
+     * si_info.si_trapno.
+     */
+    uint32_t fsr = info->si_trapno;
+
+    return extract32(fsr, 11, 1);
+}
+
+#endif
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 20/40] bsd-user/host/i386/host-signal.h: Implement host_signal_*
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (18 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 21/40] bsd-user/host/x86_64/host-signal.h: " Warner Losh
                   ` (19 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Implement host_signal_pc, host_signal_set_pc and host_signal_write for
i386.

Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/host/i386/host-signal.h | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 bsd-user/host/i386/host-signal.h

diff --git a/bsd-user/host/i386/host-signal.h b/bsd-user/host/i386/host-signal.h
new file mode 100644
index 00000000000..169e61b154c
--- /dev/null
+++ b/bsd-user/host/i386/host-signal.h
@@ -0,0 +1,37 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2021 Warner Losh
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef I386_HOST_SIGNAL_H
+#define I386_HOST_SIGNAL_H
+
+#include <sys/ucontext.h>
+#include <machine/trap.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.mc_eip;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.mc_eip = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    /*
+     * Look in sys/i386/i386/trap.c. NOTE: mc_err == tr_err due to type punning
+     * between a trapframe and mcontext on FreeBSD/i386.
+     */
+    return uc->uc_mcontext.mc_trapno == T_PAGEFLT &&
+        uc->uc_mcontext.mc_err & PGEX_W;
+}
+
+#endif
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 21/40] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (19 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 20/40] bsd-user/host/i386/host-signal.h: " Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 22/40] bsd-user: Add host signals to the build Warner Losh
                   ` (18 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Implement host_signal_pc, host_signal_set_pc and host_signal_write for
x86_64.

Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/host/x86_64/host-signal.h | 37 ++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 bsd-user/host/x86_64/host-signal.h

diff --git a/bsd-user/host/x86_64/host-signal.h b/bsd-user/host/x86_64/host-signal.h
new file mode 100644
index 00000000000..47ca19f8814
--- /dev/null
+++ b/bsd-user/host/x86_64/host-signal.h
@@ -0,0 +1,37 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2021 Warner Losh
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef X86_64_HOST_SIGNAL_H
+#define X86_64_HOST_SIGNAL_H
+
+#include <sys/ucontext.h>
+#include <machine/trap.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.mc_rip;
+}
+
+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
+{
+    uc->uc_mcontext.mc_rip = pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    /*
+     * Look in sys/amd64/amd64/trap.c. NOTE: mc_err == tr_err due to type
+     * punning between a trapframe and mcontext on FreeBSD/amd64.
+     */
+    return uc->uc_mcontext.mc_trapno == T_PAGEFLT &&
+        uc->uc_mcontext.mc_err & PGEX_W;
+}
+
+#endif
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 22/40] bsd-user: Add host signals to the build
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (20 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 21/40] bsd-user/host/x86_64/host-signal.h: " Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 23/40] bsd-user: Add trace events for bsd-user Warner Losh
                   ` (17 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Start to add the host signal functionality to the build.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 1 +
 meson.build       | 1 +
 2 files changed, 2 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index ad8437a8bfb..f3e020e004a 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -22,6 +22,7 @@
 #include "qemu.h"
 #include "signal-common.h"
 #include "hw/core/tcg-cpu-ops.h"
+#include "host-signal.h"
 
 /*
  * Stubbed out routines until we merge signal support from bsd-user
diff --git a/meson.build b/meson.build
index 5dbc9a7a365..155403d44f4 100644
--- a/meson.build
+++ b/meson.build
@@ -2947,6 +2947,7 @@ foreach target : target_dirs
     if 'CONFIG_BSD_USER' in config_target
       base_dir = 'bsd-user'
       target_inc += include_directories('bsd-user/' / targetos)
+      target_inc += include_directories('bsd-user/host/' / host_arch)
       dir = base_dir / abi
       arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
     endif
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 23/40] bsd-user: Add trace events for bsd-user
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (21 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 22/40] bsd-user: Add host signals to the build Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
                   ` (16 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Add the bsd-user specific events and infrastructure. Only include the
linux-user trace events for linux-user, not bsd-user.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c     |  1 +
 bsd-user/trace-events | 11 +++++++++++
 bsd-user/trace.h      |  1 +
 meson.build           |  5 ++++-
 4 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 bsd-user/trace-events
 create mode 100644 bsd-user/trace.h

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index f3e020e004a..cb0036acb61 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "qemu.h"
 #include "signal-common.h"
+#include "trace.h"
 #include "hw/core/tcg-cpu-ops.h"
 #include "host-signal.h"
 
diff --git a/bsd-user/trace-events b/bsd-user/trace-events
new file mode 100644
index 00000000000..843896f6271
--- /dev/null
+++ b/bsd-user/trace-events
@@ -0,0 +1,11 @@
+# See docs/tracing.txt for syntax documentation.
+
+# bsd-user/signal.c
+user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=0x%"PRIx64
+user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=0x%"PRIx64
+user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=0x%"PRIx64
+user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=0x%"PRIx64
+user_dump_core_and_abort(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)"
+user_handle_signal(void *env, int target_sig) "env=%p signal %d"
+user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d("
+user_queue_signal(void *env, int target_sig) "env=%p signal %d"
diff --git a/bsd-user/trace.h b/bsd-user/trace.h
new file mode 100644
index 00000000000..593c0204add
--- /dev/null
+++ b/bsd-user/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-bsd_user.h"
diff --git a/meson.build b/meson.build
index 155403d44f4..5f433550718 100644
--- a/meson.build
+++ b/meson.build
@@ -2458,9 +2458,12 @@ trace_events_subdirs = [
   'monitor',
   'util',
 ]
-if have_user
+if have_linux_user
   trace_events_subdirs += [ 'linux-user' ]
 endif
+if have_bsd_user
+  trace_events_subdirs += [ 'bsd-user' ]
+endif
 if have_block
   trace_events_subdirs += [
     'authz',
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (22 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 23/40] bsd-user: Add trace events for bsd-user Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
                   ` (15 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Implement conversion of host to target siginfo.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index cb0036acb61..db8cf0a08f1 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -48,6 +48,119 @@ int target_to_host_signal(int sig)
     return sig;
 }
 
+static bool has_trapno(int tsig)
+{
+    return tsig == TARGET_SIGILL ||
+        tsig == TARGET_SIGFPE ||
+        tsig == TARGET_SIGSEGV ||
+        tsig == TARGET_SIGBUS ||
+        tsig == TARGET_SIGTRAP;
+}
+
+
+/* Siginfo conversion. */
+
+/*
+ * Populate tinfo w/o swapping based on guessing which fields are valid.
+ */
+static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
+        const siginfo_t *info)
+{
+    int sig = host_to_target_signal(info->si_signo);
+    int si_code = info->si_code;
+    int si_type;
+
+    /*
+     * Make sure we that the variable portion of the target siginfo is zeroed
+     * out so we don't leak anything into that.
+     */
+    memset(&tinfo->_reason, 0, sizeof(tinfo->_reason));
+
+    /*
+     * This is awkward, because we have to use a combination of the si_code and
+     * si_signo to figure out which of the union's members are valid.o We
+     * therefore make our best guess.
+     *
+     * Once we have made our guess, we record it in the top 16 bits of
+     * the si_code, so that tswap_siginfo() later can use it.
+     * tswap_siginfo() will strip these top bits out before writing
+     * si_code to the guest (sign-extending the lower bits).
+     */
+    tinfo->si_signo = sig;
+    tinfo->si_errno = info->si_errno;
+    tinfo->si_code = info->si_code;
+    tinfo->si_pid = info->si_pid;
+    tinfo->si_uid = info->si_uid;
+    tinfo->si_status = info->si_status;
+    tinfo->si_addr = (abi_ulong)(unsigned long)info->si_addr;
+    /*
+     * si_value is opaque to kernel. On all FreeBSD platforms,
+     * sizeof(sival_ptr) >= sizeof(sival_int) so the following
+     * always will copy the larger element.
+     */
+    tinfo->si_value.sival_ptr =
+        (abi_ulong)(unsigned long)info->si_value.sival_ptr;
+
+    switch (si_code) {
+        /*
+         * All the SI_xxx codes that are defined here are global to
+         * all the signals (they have values that none of the other,
+         * more specific signal info will set).
+         */
+    case SI_USER:
+    case SI_LWP:
+    case SI_KERNEL:
+    case SI_QUEUE:
+    case SI_ASYNCIO:
+        /*
+         * Only the fixed parts are valid (though FreeBSD doesn't always
+         * set all the fields to non-zero values.
+         */
+        si_type = QEMU_SI_NOINFO;
+        break;
+    case SI_TIMER:
+        tinfo->_reason._timer._timerid = info->_reason._timer._timerid;
+        tinfo->_reason._timer._overrun = info->_reason._timer._overrun;
+        si_type = QEMU_SI_TIMER;
+        break;
+    case SI_MESGQ:
+        tinfo->_reason._mesgq._mqd = info->_reason._mesgq._mqd;
+        si_type = QEMU_SI_MESGQ;
+        break;
+    default:
+        /*
+         * We have to go based on the signal number now to figure out
+         * what's valid.
+         */
+        if (has_trapno(sig)) {
+            tinfo->_reason._fault._trapno = info->_reason._fault._trapno;
+            si_type = QEMU_SI_FAULT;
+        }
+#ifdef TARGET_SIGPOLL
+        /*
+         * FreeBSD never had SIGPOLL, but emulates it for Linux so there's
+         * a chance it may popup in the future.
+         */
+        if (sig == TARGET_SIGPOLL) {
+            tinfo->_reason._poll._band = info->_reason._poll._band;
+            si_type = QEMU_SI_POLL;
+        }
+#endif
+        /*
+         * Unsure that this can actually be generated, and our support for
+         * capsicum is somewhere between weak and non-existant, but if we get
+         * one, then we know what to save.
+         */
+        if (sig == TARGET_SIGTRAP) {
+            tinfo->_reason._capsicum._syscall =
+                info->_reason._capsicum._syscall;
+            si_type = QEMU_SI_CAPSICUM;
+        }
+        break;
+    }
+    tinfo->si_code = deposit32(si_code, 24, 8, si_type);
+}
+
 /*
  * Queue a signal so that it will be send to the virtual CPU as soon as
  * possible.
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (23 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 26/40] bsd-user/signal.c: Implement host_signal_handler Warner Losh
                   ` (14 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/qemu.h   |  2 ++
 bsd-user/signal.c | 13 ++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 49f01932a53..8ed1bfbca89 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -446,4 +446,6 @@ static inline void *lock_user_string(abi_ulong guest_addr)
 
 #include <pthread.h>
 
+#include "user/safe-syscall.h"
+
 #endif /* QEMU_H */
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index db8cf0a08f1..454aef2993e 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -48,6 +48,18 @@ int target_to_host_signal(int sig)
     return sig;
 }
 
+/* Adjust the signal context to rewind out of safe-syscall if we're in it */
+static inline void rewind_if_in_safe_syscall(void *puc)
+{
+    ucontext_t *uc = (ucontext_t *)puc;
+    uintptr_t pcreg = host_signal_pc(uc);
+
+    if (pcreg > (uintptr_t)safe_syscall_start
+        && pcreg < (uintptr_t)safe_syscall_end) {
+        host_signal_set_pc(uc, (uintptr_t)safe_syscall_start);
+    }
+}
+
 static bool has_trapno(int tsig)
 {
     return tsig == TARGET_SIGILL ||
@@ -57,7 +69,6 @@ static bool has_trapno(int tsig)
         tsig == TARGET_SIGTRAP;
 }
 
-
 /* Siginfo conversion. */
 
 /*
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 26/40] bsd-user/signal.c: Implement host_signal_handler
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (24 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 27/40] bsd-user/strace.c: print_taken_signal Warner Losh
                   ` (13 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Implement host_signal_handler to handle signals generated by the host
and to do safe system calls.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 454aef2993e..24cf4b1120b 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -223,6 +223,111 @@ void force_sig_fault(int sig, int code, abi_ulong addr)
 
 static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
 {
+    CPUArchState *env = thread_cpu->env_ptr;
+    CPUState *cpu = env_cpu(env);
+    TaskState *ts = cpu->opaque;
+    target_siginfo_t tinfo;
+    ucontext_t *uc = puc;
+    struct emulated_sigtable *k;
+    int guest_sig;
+    uintptr_t pc = 0;
+    bool sync_sig = false;
+
+    /*
+     * Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
+     * handling wrt signal blocking and unwinding.
+     */
+    if ((host_sig == SIGSEGV || host_sig == SIGBUS) && info->si_code > 0) {
+        MMUAccessType access_type;
+        uintptr_t host_addr;
+        abi_ptr guest_addr;
+        bool is_write;
+
+        host_addr = (uintptr_t)info->si_addr;
+
+        /*
+         * Convert forcefully to guest address space: addresses outside
+         * reserved_va are still valid to report via SEGV_MAPERR.
+         */
+        guest_addr = h2g_nocheck(host_addr);
+
+        pc = host_signal_pc(uc);
+        is_write = host_signal_write(info, uc);
+        access_type = adjust_signal_pc(&pc, is_write);
+
+        if (host_sig == SIGSEGV) {
+            bool maperr = true;
+
+            if (info->si_code == SEGV_ACCERR && h2g_valid(host_addr)) {
+                /* If this was a write to a TB protected page, restart. */
+                if (is_write &&
+                    handle_sigsegv_accerr_write(cpu, &uc->uc_sigmask,
+                                                pc, guest_addr)) {
+                    return;
+                }
+
+                /*
+                 * With reserved_va, the whole address space is PROT_NONE,
+                 * which means that we may get ACCERR when we want MAPERR.
+                 */
+                if (page_get_flags(guest_addr) & PAGE_VALID) {
+                    maperr = false;
+                } else {
+                    info->si_code = SEGV_MAPERR;
+                }
+            }
+
+            sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
+            cpu_loop_exit_sigsegv(cpu, guest_addr, access_type, maperr, pc);
+        } else {
+            sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
+            if (info->si_code == BUS_ADRALN) {
+                cpu_loop_exit_sigbus(cpu, guest_addr, access_type, pc);
+            }
+        }
+
+        sync_sig = true;
+    }
+
+    /* Get the target signal number. */
+    guest_sig = host_to_target_signal(host_sig);
+    if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
+        return;
+    }
+    trace_user_host_signal(cpu, host_sig, guest_sig);
+
+    host_to_target_siginfo_noswap(&tinfo, info);
+
+    k = &ts->sigtab[guest_sig - 1];
+    k->info = tinfo;
+    k->pending = guest_sig;
+    ts->signal_pending = 1;
+
+    /*
+     * For synchronous signals, unwind the cpu state to the faulting
+     * insn and then exit back to the main loop so that the signal
+     * is delivered immediately.
+     */
+    if (sync_sig) {
+        cpu->exception_index = EXCP_INTERRUPT;
+        cpu_loop_exit_restore(cpu, pc);
+    }
+
+    rewind_if_in_safe_syscall(puc);
+
+    /*
+     * Block host signals until target signal handler entered. We
+     * can't block SIGSEGV or SIGBUS while we're executing guest
+     * code in case the guest code provokes one in the window between
+     * now and it getting out to the main loop. Signals will be
+     * unblocked again in process_pending_signals().
+     */
+    sigfillset(&uc->uc_sigmask);
+    sigdelset(&uc->uc_sigmask, SIGSEGV);
+    sigdelset(&uc->uc_sigmask, SIGBUS);
+
+    /* Interrupt the virtual CPU as soon as possible. */
+    cpu_exit(thread_cpu);
 }
 
 void signal_init(void)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 27/40] bsd-user/strace.c: print_taken_signal
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (25 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 26/40] bsd-user/signal.c: Implement host_signal_handler Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 28/40] bsd-user/signal.c: Implement dump_core_and_abort Warner Losh
                   ` (12 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

print_taken_signal() prints signals when we're tracing signals.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/qemu.h   | 10 +++++
 bsd-user/strace.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 8ed1bfbca89..a7964776fdb 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -204,6 +204,16 @@ 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;
 
 /* mmap.c */
diff --git a/bsd-user/strace.c b/bsd-user/strace.c
index be40b8a20cf..a77d10dd6b6 100644
--- a/bsd-user/strace.c
+++ b/bsd-user/strace.c
@@ -31,6 +31,24 @@ int do_strace;
 /*
  * Utility functions
  */
+static const char *
+get_comma(int last)
+{
+    return (last) ? "" : ",";
+}
+
+/*
+ * Prints out raw parameter using given format.  Caller needs
+ * to do byte swapping if needed.
+ */
+static void
+print_raw_param(const char *fmt, abi_long param, int last)
+{
+    char format[64];
+
+    (void)snprintf(format, sizeof(format), "%s%s", fmt, get_comma(last));
+    gemu_log(format, param);
+}
 
 static void print_sysctl(const struct syscallname *name, abi_long arg1,
         abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
@@ -239,3 +257,82 @@ void print_openbsd_syscall_ret(int num, abi_long ret)
 
     print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
 }
+
+static void
+print_signal(abi_ulong arg, int last)
+{
+    const char *signal_name = NULL;
+    switch (arg) {
+    case TARGET_SIGHUP:
+        signal_name = "SIGHUP";
+        break;
+    case TARGET_SIGINT:
+        signal_name = "SIGINT";
+        break;
+    case TARGET_SIGQUIT:
+        signal_name = "SIGQUIT";
+        break;
+    case TARGET_SIGILL:
+        signal_name = "SIGILL";
+        break;
+    case TARGET_SIGABRT:
+        signal_name = "SIGABRT";
+        break;
+    case TARGET_SIGFPE:
+        signal_name = "SIGFPE";
+        break;
+    case TARGET_SIGKILL:
+        signal_name = "SIGKILL";
+        break;
+    case TARGET_SIGSEGV:
+        signal_name = "SIGSEGV";
+        break;
+    case TARGET_SIGPIPE:
+        signal_name = "SIGPIPE";
+        break;
+    case TARGET_SIGALRM:
+        signal_name = "SIGALRM";
+        break;
+    case TARGET_SIGTERM:
+        signal_name = "SIGTERM";
+        break;
+    case TARGET_SIGUSR1:
+        signal_name = "SIGUSR1";
+        break;
+    case TARGET_SIGUSR2:
+        signal_name = "SIGUSR2";
+        break;
+    case TARGET_SIGCHLD:
+        signal_name = "SIGCHLD";
+        break;
+    case TARGET_SIGCONT:
+        signal_name = "SIGCONT";
+        break;
+    case TARGET_SIGSTOP:
+        signal_name = "SIGSTOP";
+        break;
+    case TARGET_SIGTTIN:
+        signal_name = "SIGTTIN";
+        break;
+    case TARGET_SIGTTOU:
+        signal_name = "SIGTTOU";
+        break;
+    }
+    if (signal_name == NULL) {
+        print_raw_param("%ld", arg, last);
+        return;
+    }
+    gemu_log("%s%s", signal_name, get_comma(last));
+}
+
+void print_taken_signal(int target_signum, const target_siginfo_t *tinfo)
+{
+    /*
+     * Print the strace output for a signal being taken:
+     * --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+     */
+    gemu_log("%d ", getpid());
+    gemu_log("--- ");
+    print_signal(target_signum, 1);
+    gemu_log(" ---\n");
+}
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 28/40] bsd-user/signal.c: Implement dump_core_and_abort
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (26 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 27/40] bsd-user/strace.c: print_taken_signal Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 29/40] bsd-user/signal.c: Fill in queue_signal Warner Losh
                   ` (11 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Force delivering a signal and generating a core file. It's a global
function for the moment...

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c       | 76 +++++++++++++++++++++++++++++++++++++++++
 bsd-user/syscall_defs.h |  1 +
 2 files changed, 77 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 24cf4b1120b..ccda7adbeef 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -172,6 +172,82 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
     tinfo->si_code = deposit32(si_code, 24, 8, si_type);
 }
 
+/* Returns 1 if given signal should dump core if not handled. */
+static int core_dump_signal(int sig)
+{
+    switch (sig) {
+    case TARGET_SIGABRT:
+    case TARGET_SIGFPE:
+    case TARGET_SIGILL:
+    case TARGET_SIGQUIT:
+    case TARGET_SIGSEGV:
+    case TARGET_SIGTRAP:
+    case TARGET_SIGBUS:
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+/* Abort execution with signal. */
+static void QEMU_NORETURN dump_core_and_abort(int target_sig)
+{
+    CPUArchState *env = thread_cpu->env_ptr;
+    CPUState *cpu = env_cpu(env);
+    TaskState *ts = cpu->opaque;
+    int core_dumped = 0;
+    int host_sig;
+    struct sigaction act;
+
+    host_sig = target_to_host_signal(target_sig);
+    gdb_signalled(env, target_sig);
+
+    /* Dump core if supported by target binary format */
+    if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
+        stop_all_tasks();
+        core_dumped =
+            ((*ts->bprm->core_dump)(target_sig, env) == 0);
+    }
+    if (core_dumped) {
+        struct rlimit nodump;
+
+        /*
+         * We already dumped the core of target process, we don't want
+         * a coredump of qemu itself.
+         */
+         getrlimit(RLIMIT_CORE, &nodump);
+         nodump.rlim_cur = 0;
+         setrlimit(RLIMIT_CORE, &nodump);
+         (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) "
+             "- %s\n", target_sig, strsignal(host_sig), "core dumped");
+    }
+
+    /*
+     * The proper exit code for dying from an uncaught signal is
+     * -<signal>.  The kernel doesn't allow exit() or _exit() to pass
+     * a negative value.  To get the proper exit code we need to
+     * actually die from an uncaught signal.  Here the default signal
+     * handler is installed, we send ourself a signal and we wait for
+     * it to arrive.
+     */
+    memset(&act, 0, sizeof(act));
+    sigfillset(&act.sa_mask);
+    act.sa_handler = SIG_DFL;
+    sigaction(host_sig, &act, NULL);
+
+    kill(getpid(), host_sig);
+
+    /*
+     * Make sure the signal isn't masked (just reuse the mask inside
+     * of act).
+     */
+    sigdelset(&act.sa_mask, host_sig);
+    sigsuspend(&act.sa_mask);
+
+    /* unreachable */
+    abort();
+}
+
 /*
  * Queue a signal so that it will be send to the virtual CPU as soon as
  * possible.
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
index 04a1a886d7b..62b472b990b 100644
--- a/bsd-user/syscall_defs.h
+++ b/bsd-user/syscall_defs.h
@@ -21,6 +21,7 @@
 #define _SYSCALL_DEFS_H_
 
 #include <sys/syscall.h>
+#include <sys/resource.h>
 
 #include "errno_defs.h"
 
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 29/40] bsd-user/signal.c: Fill in queue_signal
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (27 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 28/40] bsd-user/signal.c: Implement dump_core_and_abort Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 30/40] bsd-user/signal.c: sigset manipulation routines Warner Losh
                   ` (10 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Fill in queue signal implementation, as well as routines allocate and
delete elements of the signal queue.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/qemu.h   |  5 +++++
 bsd-user/signal.c | 13 ++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index a7964776fdb..1648a509b9c 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -85,6 +85,11 @@ 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];
     /*
      * Nonzero if process_pending_signals() needs to do something (either
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index ccda7adbeef..34663f7a28a 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -255,7 +255,18 @@ static void QEMU_NORETURN dump_core_and_abort(int target_sig)
 void queue_signal(CPUArchState *env, int sig, int si_type,
                   target_siginfo_t *info)
 {
-    qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig);
+    CPUState *cpu = env_cpu(env);
+    TaskState *ts = cpu->opaque;
+
+    trace_user_queue_signal(env, sig);
+
+    info->si_code = deposit32(info->si_code, 24, 8, si_type);
+
+    ts->sync_signal.info = *info;
+    ts->sync_signal.pending = sig;
+    /* Signal that a new signal is pending. */
+    qatomic_set(&ts->signal_pending, 1);
+    return;
 }
 
 static int fatal_signal(int sig)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 30/40] bsd-user/signal.c: sigset manipulation routines.
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (28 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 29/40] bsd-user/signal.c: Fill in queue_signal Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 31/40] bsd-user/signal.c: setup_frame Warner Losh
                   ` (9 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

target_sigemptyset: resets a set to having no bits set
target_sigaddset:   adds a signal to a set
target_sigismember: returns true when signal is a member
host_to_target_sigset_internal: convert host sigset to target
host_to_target_sigset: convert host sigset to target
target_to_host_sigset_internal: convert target sigset to host
target_to_host_sigset: convert target sigset to host

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal-common.h |  2 ++
 bsd-user/signal.c        | 74 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
index 80e9503238a..ee819266f54 100644
--- a/bsd-user/signal-common.h
+++ b/bsd-user/signal-common.h
@@ -14,11 +14,13 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
 long do_sigreturn(CPUArchState *env);
 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
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 34663f7a28a..84dafa4e9fe 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -32,6 +32,9 @@
 
 static struct target_sigaction sigact_table[TARGET_NSIG];
 static void host_signal_handler(int host_sig, siginfo_t *info, void *puc);
+static void target_to_host_sigset_internal(sigset_t *d,
+        const target_sigset_t *s);
+
 
 /*
  * The BSD ABIs use the same singal numbers across all the CPU architectures, so
@@ -48,6 +51,25 @@ int target_to_host_signal(int sig)
     return sig;
 }
 
+static inline void target_sigemptyset(target_sigset_t *set)
+{
+    memset(set, 0, sizeof(*set));
+}
+
+static inline void target_sigaddset(target_sigset_t *set, int signum)
+{
+    signum--;
+    uint32_t mask = (uint32_t)1 << (signum % TARGET_NSIG_BPW);
+    set->__bits[signum / TARGET_NSIG_BPW] |= mask;
+}
+
+static inline int target_sigismember(const target_sigset_t *set, int signum)
+{
+    signum--;
+    abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
+    return (set->__bits[signum / TARGET_NSIG_BPW] & mask) != 0;
+}
+
 /* Adjust the signal context to rewind out of safe-syscall if we're in it */
 static inline void rewind_if_in_safe_syscall(void *puc)
 {
@@ -60,6 +82,58 @@ static inline void rewind_if_in_safe_syscall(void *puc)
     }
 }
 
+/*
+ * Note: The following take advantage of the BSD signal property that all
+ * signals are available on all architectures.
+ */
+static void host_to_target_sigset_internal(target_sigset_t *d,
+        const sigset_t *s)
+{
+    int i;
+
+    target_sigemptyset(d);
+    for (i = 1; i <= NSIG; i++) {
+        if (sigismember(s, i)) {
+            target_sigaddset(d, host_to_target_signal(i));
+        }
+    }
+}
+
+void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
+{
+    target_sigset_t d1;
+    int i;
+
+    host_to_target_sigset_internal(&d1, s);
+    for (i = 0; i < _SIG_WORDS; i++) {
+        d->__bits[i] = tswap32(d1.__bits[i]);
+    }
+}
+
+static void target_to_host_sigset_internal(sigset_t *d,
+        const target_sigset_t *s)
+{
+    int i;
+
+    sigemptyset(d);
+    for (i = 1; i <= TARGET_NSIG; i++) {
+        if (target_sigismember(s, i)) {
+            sigaddset(d, target_to_host_signal(i));
+        }
+    }
+}
+
+void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
+{
+    target_sigset_t s1;
+    int i;
+
+    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+        s1.__bits[i] = tswap32(s->__bits[i]);
+    }
+    target_to_host_sigset_internal(d, &s1);
+}
+
 static bool has_trapno(int tsig)
 {
     return tsig == TARGET_SIGILL ||
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 31/40] bsd-user/signal.c: setup_frame
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (29 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 30/40] bsd-user/signal.c: sigset manipulation routines Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 32/40] bsd-user/signal.c: handle_pending_signal Warner Losh
                   ` (8 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

setup_frame sets up a signalled stack frame. Associated routines to
extract the pointer to the stack frame and to support alternate stacks.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/main.c   |  5 +++
 bsd-user/qemu.h   |  3 +-
 bsd-user/signal.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 29cf4e15693..f1d58e905e7 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -217,6 +217,11 @@ void qemu_cpu_kick(CPUState *cpu)
 /* Assumes contents are already zeroed.  */
 static void init_task_state(TaskState *ts)
 {
+    ts->sigaltstack_used = (struct target_sigaltstack) {
+        .ss_sp = 0,
+        .ss_size = 0,
+        .ss_flags = TARGET_SS_DISABLE,
+    };
 }
 
 void gemu_log(const char *fmt, ...)
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 1648a509b9c..de20650a00d 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -107,7 +107,8 @@ typedef struct TaskState {
      */
     sigset_t signal_mask;
 
-    uint8_t stack[];
+    /* This thread's sigaltstack, if it has one */
+    struct target_sigaltstack sigaltstack_used;
 } __attribute__((aligned(16))) TaskState;
 
 void stop_all_tasks(void);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 84dafa4e9fe..dbc13736073 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -35,6 +35,16 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc);
 static void target_to_host_sigset_internal(sigset_t *d,
         const target_sigset_t *s);
 
+static inline int on_sig_stack(TaskState *ts, unsigned long sp)
+{
+    return sp - ts->sigaltstack_used.ss_sp < ts->sigaltstack_used.ss_size;
+}
+
+static inline int sas_ss_flags(TaskState *ts, unsigned long sp)
+{
+    return ts->sigaltstack_used.ss_size == 0 ? SS_DISABLE :
+        on_sig_stack(ts, sp) ? SS_ONSTACK : 0;
+}
 
 /*
  * The BSD ABIs use the same singal numbers across all the CPU architectures, so
@@ -491,6 +501,79 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
     cpu_exit(thread_cpu);
 }
 
+static inline abi_ulong get_sigframe(struct target_sigaction *ka,
+        CPUArchState *env, size_t frame_size)
+{
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+    abi_ulong sp;
+
+    /* Use default user stack */
+    sp = get_sp_from_cpustate(env);
+
+    if ((ka->sa_flags & TARGET_SA_ONSTACK) && sas_ss_flags(ts, sp) == 0) {
+        sp = ts->sigaltstack_used.ss_sp + ts->sigaltstack_used.ss_size;
+    }
+
+/* TODO: make this a target_arch function / define */
+#if defined(TARGET_ARM)
+    return (sp - frame_size) & ~7;
+#elif defined(TARGET_AARCH64)
+    return (sp - frame_size) & ~15;
+#else
+    return sp - frame_size;
+#endif
+}
+
+/* compare to $M/$M/exec_machdep.c sendsig and sys/kern/kern_sig.c sigexit */
+
+static void setup_frame(int sig, int code, struct target_sigaction *ka,
+    target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *env)
+{
+    struct target_sigframe *frame;
+    abi_ulong frame_addr;
+    int i;
+
+    frame_addr = get_sigframe(ka, env, sizeof(*frame));
+    trace_user_setup_frame(env, frame_addr);
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+        unlock_user_struct(frame, frame_addr, 1);
+        dump_core_and_abort(TARGET_SIGILL);
+        return;
+    }
+
+    memset(frame, 0, sizeof(*frame));
+    setup_sigframe_arch(env, frame_addr, frame, 0);
+
+    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+        __put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i]);
+    }
+
+    if (tinfo) {
+        frame->sf_si.si_signo = tinfo->si_signo;
+        frame->sf_si.si_errno = tinfo->si_errno;
+        frame->sf_si.si_code = tinfo->si_code;
+        frame->sf_si.si_pid = tinfo->si_pid;
+        frame->sf_si.si_uid = tinfo->si_uid;
+        frame->sf_si.si_status = tinfo->si_status;
+        frame->sf_si.si_addr = tinfo->si_addr;
+        /* see host_to_target_siginfo_noswap() for more details */
+        frame->sf_si.si_value.sival_ptr = tinfo->si_value.sival_ptr;
+        /*
+         * At this point, whatever is in the _reason union is complete
+         * and in target order, so just copy the whole thing over, even
+         * if it's too large for this specific signal.
+         * host_to_target_siginfo_noswap() and tswap_siginfo() have ensured
+         * that's so.
+         */
+        memcpy(&frame->sf_si._reason, &tinfo->_reason,
+               sizeof(tinfo->_reason));
+    }
+
+    set_sigtramp_args(env, sig, frame, frame_addr, ka);
+
+    unlock_user_struct(frame, frame_addr, 1);
+}
+
 void signal_init(void)
 {
     TaskState *ts = (TaskState *)thread_cpu->opaque;
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 32/40] bsd-user/signal.c: handle_pending_signal
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (30 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 31/40] bsd-user/signal.c: setup_frame Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 33/40] bsd-user/signal.c: tswap_siginfo Warner Losh
                   ` (7 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Handle a queued signal.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/qemu.h   |  7 ++++
 bsd-user/signal.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index de20650a00d..02921ac8b3b 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -99,6 +99,8 @@ typedef struct TaskState {
      * 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:
@@ -106,6 +108,11 @@ typedef struct TaskState {
      *  + 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;
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index dbc13736073..366e047cccc 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -616,6 +616,93 @@ void signal_init(void)
     }
 }
 
+static void handle_pending_signal(CPUArchState *env, int sig,
+                                  struct emulated_sigtable *k)
+{
+    CPUState *cpu = env_cpu(env);
+    TaskState *ts = cpu->opaque;
+    struct target_sigaction *sa;
+    int code;
+    sigset_t set;
+    abi_ulong handler;
+    target_siginfo_t tinfo;
+    target_sigset_t target_old_set;
+
+    trace_user_handle_signal(env, sig);
+
+    k->pending = 0;
+
+    sig = gdb_handlesig(cpu, sig);
+    if (!sig) {
+        sa = NULL;
+        handler = TARGET_SIG_IGN;
+    } else {
+        sa = &sigact_table[sig - 1];
+        handler = sa->_sa_handler;
+    }
+
+    if (do_strace) {
+        print_taken_signal(sig, &k->info);
+    }
+
+    if (handler == TARGET_SIG_DFL) {
+        /*
+         * default handler : ignore some signal. The other are job
+         * control or fatal.
+         */
+        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN ||
+            sig == TARGET_SIGTTOU) {
+            kill(getpid(), SIGSTOP);
+        } else if (sig != TARGET_SIGCHLD && sig != TARGET_SIGURG &&
+                   sig != TARGET_SIGINFO && sig != TARGET_SIGWINCH &&
+                   sig != TARGET_SIGCONT) {
+            dump_core_and_abort(sig);
+        }
+    } else if (handler == TARGET_SIG_IGN) {
+        /* ignore sig */
+    } else if (handler == TARGET_SIG_ERR) {
+        dump_core_and_abort(sig);
+    } else {
+        /* compute the blocked signals during the handler execution */
+        sigset_t *blocked_set;
+
+        target_to_host_sigset(&set, &sa->sa_mask);
+        /*
+         * SA_NODEFER indicates that the current signal should not be
+         * blocked during the handler.
+         */
+        if (!(sa->sa_flags & TARGET_SA_NODEFER)) {
+            sigaddset(&set, target_to_host_signal(sig));
+        }
+
+        /*
+         * Save the previous blocked signal state to restore it at the
+         * end of the signal execution (see do_sigreturn).
+         */
+        host_to_target_sigset_internal(&target_old_set, &ts->signal_mask);
+
+        blocked_set = ts->in_sigsuspend ?
+            &ts->sigsuspend_mask : &ts->signal_mask;
+        sigorset(&ts->signal_mask, blocked_set, &set);
+        ts->in_sigsuspend = false;
+        sigprocmask(SIG_SETMASK, &ts->signal_mask, NULL);
+
+        /* XXX VM86 on x86 ??? */
+
+        code = k->info.si_code; /* From host, so no si_type */
+        /* prepare the stack frame of the virtual CPU */
+        if (sa->sa_flags & TARGET_SA_SIGINFO) {
+            tswap_siginfo(&tinfo, &k->info);
+            setup_frame(sig, code, sa, &target_old_set, &tinfo, env);
+        } else {
+            setup_frame(sig, code, sa, &target_old_set, NULL, env);
+        }
+        if (sa->sa_flags & TARGET_SA_RESETHAND) {
+            sa->_sa_handler = TARGET_SIG_DFL;
+        }
+    }
+}
+
 void process_pending_signals(CPUArchState *cpu_env)
 {
 }
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 33/40] bsd-user/signal.c: tswap_siginfo
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (31 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 32/40] bsd-user/signal.c: handle_pending_signal Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:27 ` [PATCH v3 34/40] bsd-user/signal.c: process_pending_signals Warner Losh
                   ` (6 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Convert siginfo from targer to host.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 366e047cccc..34e8c811ad6 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -256,6 +256,59 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
     tinfo->si_code = deposit32(si_code, 24, 8, si_type);
 }
 
+static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
+{
+    int si_type = extract32(info->si_code, 24, 8);
+    int si_code = sextract32(info->si_code, 0, 24);
+
+    __put_user(info->si_signo, &tinfo->si_signo);
+    __put_user(info->si_errno, &tinfo->si_errno);
+    __put_user(si_code, &tinfo->si_code); /* Zero out si_type, it's internal */
+    __put_user(info->si_pid, &tinfo->si_pid);
+    __put_user(info->si_uid, &tinfo->si_uid);
+    __put_user(info->si_status, &tinfo->si_status);
+    __put_user(info->si_addr, &tinfo->si_addr);
+    /*
+     * Unswapped, because we passed it through mostly untouched.  si_value is
+     * opaque to the kernel, so we didn't bother with potentially wasting cycles
+     * to swap it into host byte order.
+     */
+    tinfo->si_value.sival_ptr = info->si_value.sival_ptr;
+
+    /*
+     * We can use our internal marker of which fields in the structure
+     * are valid, rather than duplicating the guesswork of
+     * host_to_target_siginfo_noswap() here.
+     */
+    switch (si_type) {
+    case QEMU_SI_NOINFO:        /* No additional info */
+        break;
+    case QEMU_SI_FAULT:
+        __put_user(info->_reason._fault._trapno,
+                   &tinfo->_reason._fault._trapno);
+        break;
+    case QEMU_SI_TIMER:
+        __put_user(info->_reason._timer._timerid,
+                   &tinfo->_reason._timer._timerid);
+        __put_user(info->_reason._timer._overrun,
+                   &tinfo->_reason._timer._overrun);
+        break;
+    case QEMU_SI_MESGQ:
+        __put_user(info->_reason._mesgq._mqd, &tinfo->_reason._mesgq._mqd);
+        break;
+    case QEMU_SI_POLL:
+        /* Note: Not generated on FreeBSD */
+        __put_user(info->_reason._poll._band, &tinfo->_reason._poll._band);
+        break;
+    case QEMU_SI_CAPSICUM:
+        __put_user(info->_reason._capsicum._syscall,
+                   &tinfo->_reason._capsicum._syscall);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 /* Returns 1 if given signal should dump core if not handled. */
 static int core_dump_signal(int sig)
 {
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 34/40] bsd-user/signal.c: process_pending_signals
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (32 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 33/40] bsd-user/signal.c: tswap_siginfo Warner Losh
@ 2022-01-28 23:27 ` Warner Losh
  2022-01-28 23:28 ` [PATCH v3 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
                   ` (5 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Process the currently queued signals.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 34e8c811ad6..4b398745f45 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -756,8 +756,62 @@ static void handle_pending_signal(CPUArchState *env, int sig,
     }
 }
 
-void process_pending_signals(CPUArchState *cpu_env)
+void process_pending_signals(CPUArchState *env)
 {
+    CPUState *cpu = env_cpu(env);
+    int sig;
+    sigset_t *blocked_set, set;
+    struct emulated_sigtable *k;
+    TaskState *ts = cpu->opaque;
+
+    while (qatomic_read(&ts->signal_pending)) {
+        sigfillset(&set);
+        sigprocmask(SIG_SETMASK, &set, 0);
+
+    restart_scan:
+        sig = ts->sync_signal.pending;
+        if (sig) {
+            /*
+             * Synchronous signals are forced by the emulated CPU in some way.
+             * If they are set to ignore, restore the default handler (see
+             * sys/kern_sig.c trapsignal() and execsigs() for this behavior)
+             * though maybe this is done only when forcing exit for non SIGCHLD.
+             */
+            if (sigismember(&ts->signal_mask, target_to_host_signal(sig)) ||
+                sigact_table[sig - 1]._sa_handler == TARGET_SIG_IGN) {
+                sigdelset(&ts->signal_mask, target_to_host_signal(sig));
+                sigact_table[sig - 1]._sa_handler = TARGET_SIG_DFL;
+            }
+            handle_pending_signal(env, sig, &ts->sync_signal);
+        }
+
+        k = ts->sigtab;
+        for (sig = 1; sig <= TARGET_NSIG; sig++, k++) {
+            blocked_set = ts->in_sigsuspend ?
+                &ts->sigsuspend_mask : &ts->signal_mask;
+            if (k->pending &&
+                !sigismember(blocked_set, target_to_host_signal(sig))) {
+                handle_pending_signal(env, sig, k);
+                /*
+                 * Restart scan from the beginning, as handle_pending_signal
+                 * might have resulted in a new synchronous signal (eg SIGSEGV).
+                 */
+                goto restart_scan;
+            }
+        }
+
+        /*
+         * Unblock signals and check one more time. Unblocking signals may cause
+         * us to take another host signal, which will set signal_pending again.
+         */
+        qatomic_set(&ts->signal_pending, 0);
+        ts->in_sigsuspend = false;
+        set = ts->signal_mask;
+        sigdelset(&set, SIGSEGV);
+        sigdelset(&set, SIGBUS);
+        sigprocmask(SIG_SETMASK, &set, 0);
+    }
+    ts->in_sigsuspend = false;
 }
 
 void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 35/40] bsd-user/signal.c: implement do_sigreturn
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (33 preceding siblings ...)
  2022-01-28 23:27 ` [PATCH v3 34/40] bsd-user/signal.c: process_pending_signals Warner Losh
@ 2022-01-28 23:28 ` Warner Losh
  2022-01-30 21:14   ` Richard Henderson
  2022-01-28 23:28 ` [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
                   ` (4 subsequent siblings)
  39 siblings, 1 reply; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Implements the meat of a sigreturn(2) system call via do_sigreturn, and
helper reset_signal_mask. Fix the prototype of do_sigreturn in qemu.h
and remove do_rt_sigreturn since it's linux only.

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/signal-common.h |  2 +-
 bsd-user/signal.c        | 55 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
index ee819266f54..786ec592d18 100644
--- a/bsd-user/signal-common.h
+++ b/bsd-user/signal-common.h
@@ -11,7 +11,7 @@
 
 long do_rt_sigreturn(CPUArchState *env);
 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
-long do_sigreturn(CPUArchState *env);
+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);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 4b398745f45..79e1128d4f6 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -627,6 +627,61 @@ static void setup_frame(int sig, int code, struct target_sigaction *ka,
     unlock_user_struct(frame, frame_addr, 1);
 }
 
+static int reset_signal_mask(target_ucontext_t *ucontext)
+{
+    int i;
+    sigset_t blocked;
+    target_sigset_t target_set;
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+    for (i = 0; i < TARGET_NSIG_WORDS; i++)
+        if (__get_user(target_set.__bits[i],
+                    &ucontext->uc_sigmask.__bits[i])) {
+            return -TARGET_EFAULT;
+        }
+    target_to_host_sigset_internal(&blocked, &target_set);
+    ts->signal_mask = blocked;
+
+    return 0;
+}
+
+/* See sys/$M/$M/exec_machdep.c sigreturn() */
+long do_sigreturn(CPUArchState *env, abi_ulong addr)
+{
+    long ret;
+    abi_ulong target_ucontext;
+    target_ucontext_t *ucontext = NULL;
+
+    /* Get the target ucontext address from the stack frame */
+    ret = get_ucontext_sigreturn(env, addr, &target_ucontext);
+    if (is_error(ret)) {
+        return ret;
+    }
+    trace_user_do_sigreturn(env, addr);
+    if (!lock_user_struct(VERIFY_READ, ucontext, target_ucontext, 0)) {
+        goto badframe;
+    }
+
+    /* Set the register state back to before the signal. */
+    if (set_mcontext(env, &ucontext->uc_mcontext, 1)) {
+        goto badframe;
+    }
+
+    /* And reset the signal mask. */
+    if (reset_signal_mask(ucontext)) {
+        goto badframe;
+    }
+
+    unlock_user_struct(ucontext, target_ucontext, 0);
+    return -TARGET_EJUSTRETURN;
+
+badframe:
+    if (ucontext != NULL) {
+        unlock_user_struct(ucontext, target_ucontext, 0);
+    }
+    return -TARGET_EFAULT;
+}
+
 void signal_init(void)
 {
     TaskState *ts = (TaskState *)thread_cpu->opaque;
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (34 preceding siblings ...)
  2022-01-28 23:28 ` [PATCH v3 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
@ 2022-01-28 23:28 ` Warner Losh
  2022-01-30 21:19   ` Richard Henderson
  2022-01-28 23:28 ` [PATCH v3 37/40] bsd-user/signal.c: do_sigaltstack Warner Losh
                   ` (3 subsequent siblings)
  39 siblings, 1 reply; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

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/signal-common.h | 22 +++++++++++
 bsd-user/signal.c        | 83 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/bsd-user/signal-common.h b/bsd-user/signal-common.h
index 786ec592d18..7ff8e8f2e40 100644
--- a/bsd-user/signal-common.h
+++ b/bsd-user/signal-common.h
@@ -9,7 +9,29 @@
 #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);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 79e1128d4f6..24074d629e2 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -309,6 +309,25 @@ 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(). We depend on the FreeBSD behaivor here where
+     * this will only affect this thread's signal mask. We don't use
+     * pthread_sigmask which might seem more correct because that routine also
+     * does odd things with SIGCANCEL to implement pthread_cancel().
+     */
+    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)
 {
@@ -554,6 +573,70 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
     cpu_exit(thread_cpu);
 }
 
+/* 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) {
+        return -TARGET_EINVAL;
+    }
+
+    if ((sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP) &&
+        act != NULL && act->_sa_handler != TARGET_SIG_DFL) {
+        return -TARGET_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 *env, size_t frame_size)
 {
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 37/40] bsd-user/signal.c: do_sigaltstack
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (35 preceding siblings ...)
  2022-01-28 23:28 ` [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
@ 2022-01-28 23:28 ` Warner Losh
  2022-01-28 23:28 ` [PATCH v3 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on Warner Losh
                   ` (2 subsequent siblings)
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson, def,
	jrtc27, Warner Losh

Implement the meat of the sigaltstack(2) system call with do_sigaltstack.

With that, all the stubbed out routines are complete, so remove
now-incorrect comment.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/signal.c | 72 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 67 insertions(+), 5 deletions(-)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 24074d629e2..65687fbe7dc 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -25,11 +25,6 @@
 #include "hw/core/tcg-cpu-ops.h"
 #include "host-signal.h"
 
-/*
- * Stubbed out routines until we merge signal support from bsd-user
- * fork.
- */
-
 static struct target_sigaction sigact_table[TARGET_NSIG];
 static void host_signal_handler(int host_sig, siginfo_t *info, void *puc);
 static void target_to_host_sigset_internal(sigset_t *d,
@@ -573,6 +568,73 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
     cpu_exit(thread_cpu);
 }
 
+/* do_sigaltstack() returns target values and errnos. */
+/* compare to kern/kern_sig.c sys_sigaltstack() and kern_sigaltstack() */
+abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
+{
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+    int ret;
+    target_stack_t oss;
+
+    if (uoss_addr) {
+        /* Save current signal stack params */
+        oss.ss_sp = tswapl(ts->sigaltstack_used.ss_sp);
+        oss.ss_size = tswapl(ts->sigaltstack_used.ss_size);
+        oss.ss_flags = tswapl(sas_ss_flags(ts, sp));
+    }
+
+    if (uss_addr) {
+        target_stack_t *uss;
+        target_stack_t ss;
+        size_t minstacksize = TARGET_MINSIGSTKSZ;
+
+        ret = -TARGET_EFAULT;
+        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
+            goto out;
+        }
+        __get_user(ss.ss_sp, &uss->ss_sp);
+        __get_user(ss.ss_size, &uss->ss_size);
+        __get_user(ss.ss_flags, &uss->ss_flags);
+        unlock_user_struct(uss, uss_addr, 0);
+
+        ret = -TARGET_EPERM;
+        if (on_sig_stack(ts, sp)) {
+            goto out;
+        }
+
+        ret = -TARGET_EINVAL;
+        if (ss.ss_flags != TARGET_SS_DISABLE
+            && ss.ss_flags != TARGET_SS_ONSTACK
+            && ss.ss_flags != 0) {
+            goto out;
+        }
+
+        if (ss.ss_flags == TARGET_SS_DISABLE) {
+            ss.ss_size = 0;
+            ss.ss_sp = 0;
+        } else {
+            ret = -TARGET_ENOMEM;
+            if (ss.ss_size < minstacksize) {
+                goto out;
+            }
+        }
+
+        ts->sigaltstack_used.ss_sp = ss.ss_sp;
+        ts->sigaltstack_used.ss_size = ss.ss_size;
+    }
+
+    if (uoss_addr) {
+        ret = -TARGET_EFAULT;
+        if (copy_to_user(uoss_addr, &oss, sizeof(oss))) {
+            goto out;
+        }
+    }
+
+    ret = 0;
+out:
+    return ret;
+}
+
 /* do_sigaction() return host values and errnos */
 int do_sigaction(int sig, const struct target_sigaction *act,
         struct target_sigaction *oact)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (36 preceding siblings ...)
  2022-01-28 23:28 ` [PATCH v3 37/40] bsd-user/signal.c: do_sigaltstack Warner Losh
@ 2022-01-28 23:28 ` Warner Losh
  2022-01-28 23:28 ` [PATCH v3 39/40] bsd-user: Rename arg name for target_cpu_reset to env Warner Losh
  2022-01-28 23:28 ` [PATCH v3 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args Warner Losh
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

tests/vm/*bsd (especailly tests/vm/freebsd) are adjacent to the bsd-user
stuff and we're keen on keeping them working as well.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e4b3a4bcdf4..b7487f9b54b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3181,6 +3181,7 @@ R: Kyle Evans <kevans@freebsd.org>
 S: Maintained
 F: bsd-user/
 F: configs/targets/*-bsd-user.mak
+F: tests/vm/*bsd
 T: git https://github.com/qemu-bsd-user/qemu-bsd-user bsd-user-rebase-3.1
 
 Linux user
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 39/40] bsd-user: Rename arg name for target_cpu_reset to env
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (37 preceding siblings ...)
  2022-01-28 23:28 ` [PATCH v3 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on Warner Losh
@ 2022-01-28 23:28 ` Warner Losh
  2022-01-28 23:28 ` [PATCH v3 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args Warner Losh
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Rename the parameter name for target_cpu_reset's CPUArchState * arg from
cpu to env.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/arm/target_arch_cpu.h    | 2 +-
 bsd-user/i386/target_arch_cpu.h   | 4 ++--
 bsd-user/x86_64/target_arch_cpu.h | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 2b395d5c97f..b087db48fa4 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -213,7 +213,7 @@ static inline void target_cpu_clone_regs(CPUARMState *env, target_ulong newsp)
     env->regs[0] = 0;
 }
 
-static inline void target_cpu_reset(CPUArchState *cpu)
+static inline void target_cpu_reset(CPUArchState *env)
 {
 }
 
diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h
index 472a96689fc..3cbf69d8af2 100644
--- a/bsd-user/i386/target_arch_cpu.h
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -200,9 +200,9 @@ static inline void target_cpu_clone_regs(CPUX86State *env, target_ulong newsp)
     env->regs[R_EAX] = 0;
 }
 
-static inline void target_cpu_reset(CPUArchState *cpu)
+static inline void target_cpu_reset(CPUArchState *env)
 {
-    cpu_reset(env_cpu(cpu));
+    cpu_reset(env_cpu(env));
 }
 
 #endif /* ! _TARGET_ARCH_CPU_H_ */
diff --git a/bsd-user/x86_64/target_arch_cpu.h b/bsd-user/x86_64/target_arch_cpu.h
index 14def48adb5..0a9c0f08946 100644
--- a/bsd-user/x86_64/target_arch_cpu.h
+++ b/bsd-user/x86_64/target_arch_cpu.h
@@ -238,9 +238,9 @@ static inline void target_cpu_clone_regs(CPUX86State *env, target_ulong newsp)
     env->regs[R_EAX] = 0;
 }
 
-static inline void target_cpu_reset(CPUArchState *cpu)
+static inline void target_cpu_reset(CPUArchState *env)
 {
-    cpu_reset(env_cpu(cpu));
+    cpu_reset(env_cpu(env));
 }
 
 #endif /* ! _TARGET_ARCH_CPU_H_ */
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v3 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args
  2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
                   ` (38 preceding siblings ...)
  2022-01-28 23:28 ` [PATCH v3 39/40] bsd-user: Rename arg name for target_cpu_reset to env Warner Losh
@ 2022-01-28 23:28 ` Warner Losh
  39 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-28 23:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Kyle Evans, Richard Henderson, def, jrtc27, Warner Losh

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/freebsd/target_os_ucontext.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bsd-user/freebsd/target_os_ucontext.h b/bsd-user/freebsd/target_os_ucontext.h
index 41b28b2c150..b196b1c629f 100644
--- a/bsd-user/freebsd/target_os_ucontext.h
+++ b/bsd-user/freebsd/target_os_ucontext.h
@@ -36,9 +36,9 @@ abi_long set_sigtramp_args(CPUArchState *env, int sig,
                            struct target_sigframe *frame,
                            abi_ulong frame_addr,
                            struct target_sigaction *ka);
-abi_long get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags);
-abi_long set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int srflag);
-abi_long get_ucontext_sigreturn(CPUArchState *regs, abi_ulong target_sf,
+abi_long get_mcontext(CPUArchState *env, target_mcontext_t *mcp, int flags);
+abi_long set_mcontext(CPUArchState *env, target_mcontext_t *mcp, int srflag);
+abi_long get_ucontext_sigreturn(CPUArchState *env, abi_ulong target_sf,
                                 abi_ulong *target_uc);
 
 #endif /* TARGET_OS_UCONTEXT_H */
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH v3 35/40] bsd-user/signal.c: implement do_sigreturn
  2022-01-28 23:28 ` [PATCH v3 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
@ 2022-01-30 21:14   ` Richard Henderson
  0 siblings, 0 replies; 44+ messages in thread
From: Richard Henderson @ 2022-01-30 21:14 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/29/22 10:28, Warner Losh wrote:
> +static int reset_signal_mask(target_ucontext_t *ucontext)
> +{
> +    int i;
> +    sigset_t blocked;
> +    target_sigset_t target_set;
> +    TaskState *ts = (TaskState *)thread_cpu->opaque;
> +
> +    for (i = 0; i < TARGET_NSIG_WORDS; i++)
> +        if (__get_user(target_set.__bits[i],
> +                    &ucontext->uc_sigmask.__bits[i])) {
> +            return -TARGET_EFAULT;
> +        }

Nit: missing braces for the loop.  Otherwise,

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction
  2022-01-28 23:28 ` [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
@ 2022-01-30 21:19   ` Richard Henderson
  2022-01-30 21:34     ` Warner Losh
  0 siblings, 1 reply; 44+ messages in thread
From: Richard Henderson @ 2022-01-30 21:19 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/29/22 10:28, Warner Losh wrote:
> +    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. */

It surely is -- we never set another thread's sigaction, and we've just blocked all 
signals, so we're signal-safe.  Am I missing something?

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction
  2022-01-30 21:19   ` Richard Henderson
@ 2022-01-30 21:34     ` Warner Losh
  0 siblings, 0 replies; 44+ messages in thread
From: Warner Losh @ 2022-01-30 21:34 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, Stacey Son, Kyle Evans, QEMU Developers,
	Konrad Witaszczyk, Jessica Clarke

[-- Attachment #1: Type: text/plain, Size: 849 bytes --]

On Sun, Jan 30, 2022 at 2:19 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/29/22 10:28, Warner Losh wrote:
> > +    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. */
>
> It surely is -- we never set another thread's sigaction, and we've just
> blocked all
> signals, so we're signal-safe.  Am I missing something?
>

Now that I look at it, I can't understand why this comment is here. I'll
remove it.

Warner


> Otherwise,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
>
> r~
>

[-- Attachment #2: Type: text/html, Size: 1600 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2022-01-30 21:38 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-28 23:27 [PATCH v3 00/40] bsd-user: upstream signal implementation Warner Losh
2022-01-28 23:27 ` [PATCH v3 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
2022-01-28 23:27 ` [PATCH v3 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context Warner Losh
2022-01-28 23:27 ` [PATCH v3 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm Warner Losh
2022-01-28 23:27 ` [PATCH v3 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data Warner Losh
2022-01-28 23:27 ` [PATCH v3 05/40] bsd-user: Remove vestiges of signal queueing code Warner Losh
2022-01-28 23:27 ` [PATCH v3 06/40] bsd-user: Bring in docs from linux-user for signal_pending Warner Losh
2022-01-28 23:27 ` [PATCH v3 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
2022-01-28 23:27 ` [PATCH v3 08/40] bsd-user/signal.c: implement force_sig_fault Warner Losh
2022-01-28 23:27 ` [PATCH v3 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here Warner Losh
2022-01-28 23:27 ` [PATCH v3 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
2022-01-28 23:27 ` [PATCH v3 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
2022-01-28 23:27 ` [PATCH v3 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
2022-01-28 23:27 ` [PATCH v3 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
2022-01-28 23:27 ` [PATCH v3 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
2022-01-28 23:27 ` [PATCH v3 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
2022-01-28 23:27 ` [PATCH v3 16/40] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
2022-01-28 23:27 ` [PATCH v3 17/40] bsd-user/signal.c: Implement signal_init() Warner Losh
2022-01-28 23:27 ` [PATCH v3 18/40] bsd-user/signal.c: Add si_type argument to queue_signal Warner Losh
2022-01-28 23:27 ` [PATCH v3 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
2022-01-28 23:27 ` [PATCH v3 20/40] bsd-user/host/i386/host-signal.h: " Warner Losh
2022-01-28 23:27 ` [PATCH v3 21/40] bsd-user/host/x86_64/host-signal.h: " Warner Losh
2022-01-28 23:27 ` [PATCH v3 22/40] bsd-user: Add host signals to the build Warner Losh
2022-01-28 23:27 ` [PATCH v3 23/40] bsd-user: Add trace events for bsd-user Warner Losh
2022-01-28 23:27 ` [PATCH v3 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
2022-01-28 23:27 ` [PATCH v3 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
2022-01-28 23:27 ` [PATCH v3 26/40] bsd-user/signal.c: Implement host_signal_handler Warner Losh
2022-01-28 23:27 ` [PATCH v3 27/40] bsd-user/strace.c: print_taken_signal Warner Losh
2022-01-28 23:27 ` [PATCH v3 28/40] bsd-user/signal.c: Implement dump_core_and_abort Warner Losh
2022-01-28 23:27 ` [PATCH v3 29/40] bsd-user/signal.c: Fill in queue_signal Warner Losh
2022-01-28 23:27 ` [PATCH v3 30/40] bsd-user/signal.c: sigset manipulation routines Warner Losh
2022-01-28 23:27 ` [PATCH v3 31/40] bsd-user/signal.c: setup_frame Warner Losh
2022-01-28 23:27 ` [PATCH v3 32/40] bsd-user/signal.c: handle_pending_signal Warner Losh
2022-01-28 23:27 ` [PATCH v3 33/40] bsd-user/signal.c: tswap_siginfo Warner Losh
2022-01-28 23:27 ` [PATCH v3 34/40] bsd-user/signal.c: process_pending_signals Warner Losh
2022-01-28 23:28 ` [PATCH v3 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
2022-01-30 21:14   ` Richard Henderson
2022-01-28 23:28 ` [PATCH v3 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
2022-01-30 21:19   ` Richard Henderson
2022-01-30 21:34     ` Warner Losh
2022-01-28 23:28 ` [PATCH v3 37/40] bsd-user/signal.c: do_sigaltstack Warner Losh
2022-01-28 23:28 ` [PATCH v3 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on Warner Losh
2022-01-28 23:28 ` [PATCH v3 39/40] bsd-user: Rename arg name for target_cpu_reset to env Warner Losh
2022-01-28 23:28 ` [PATCH v3 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args Warner Losh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.