All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/40] bsd-user: upstream our signal implementation
@ 2022-01-25  1:29 Warner Losh
  2022-01-25  1:29 ` [PATCH v2 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
                   ` (39 more replies)
  0 siblings, 40 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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. However, all
signals are always queued for batch processing (except synchronous ones that
kill the process). The full context can be found in the 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).

I lumped thinks slightly larger than past patch sets, but none of the patches
should exceed about 100 lines of diffs (there is one that clocks in at 166
though, but I had trouble splitting it smaller). With over 30k lines of diffs
between the two repos, I need to find more efficient ways of getting things
reviewed and each extra chunk takes time to curate so I'm searching for a good
happy medium.

New in version 2:

Lots of changes based on feedback garnered in v1. The patch numbers are only
loosely related as some were dropped or merged and others were added. I've
not rebased this yet to a newer revision due to the volume of changes.

o Removed an unnecessary memset for the signal table, it's already all 0's.
o Fixed a number of comments as suggested in the first round of review.
o yoda speak removed have I.
o added a path to the MAINTAINERS entry for bsd related VMs
o removed MIPS code from trapframe construction
o Add si_code call to queue_signal
o Remove final remnants of signal queueing on BSD
o Add documentation of fields of the task structure
o Remove a bunch of comments that are no longer correct or turned out to
  be false...
o Get FSR directly from the siginfo rather than doing crazy things to
  find it.
o Move target_sigaltstack_used to ts->sigaltstack_used and adjust all
  references to be per-stack.
o rename force_sig to dump_core_and_abort
o Create a new setup_sigframe_arch to save/restore context. Most
  architectures this is just get_mcontext, but arm needs special
  setup.
o Move to generating SIGILL when we can't write the signal trap frame.
o Add comments about a few extreme edge cases for SIGILL instructions
o rewrite arm's host_signal_write to use the trap frame it needs to
  get the data rather than the prior bogus assumptions.
o Add more comments to the signal related Task elements, cribbed from
  linux-user
o Move to storing QEMU supecific signal si_code, stored in the top
  8 bits of si_code. BSD uses bit 16 to indicate the code is 'generic'
  and not tied to a specific signal type, so we have to preserve that
  bit. Only bit 16 is used, but steer clear by using the top 8 bits.
o Don't gratuitously move fatal_signal
o add has_trapno function for those signals that have si_trapno.
o Move to using synchronous signals or signals artificially crated by
  qemu. Since only one of these can ever happen at the time, we
  can simplify the code in a manner similar to linux-user.
o Fix a number of "see this routine" pointers to match modern FreeBSD
  and/or remove obsolete architectures from the generic pointers.
o Fixed the division of labor between host_to_target_siginfo_noswap
  and tswap_siginfo. We now record a 'si_type' field that can be
  used to determine which parts of the siginfo are valid. _noswap
  will record its guess and if that guess is present, tswap_siginfo
  will use it.
o Fix arm get_mcontext to match what FreeBSD does by removing saving
  of vfp there and zeroing the vfp pointers.
o Exclude SIGPROF when CONFIG_GPROF active.
o A few formatting issues that I'd ignored for version 1.
o consistently used env as the name for CPUArchState (noted in one
  patch, but present in more and in a couple places in upstream so
  I fixed those too).

Not adressed:
o Signal mask issues around sigaction and sigreturn. These will be
  addressed while people comment on the rest of these changes. I've
  noted the exact details in a couple of commit messages.

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                 |   58 +-
 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       |    4 +-
 bsd-user/main.c                       |   14 +-
 bsd-user/meson.build                  |    1 +
 bsd-user/qemu.h                       |   62 +-
 bsd-user/signal-common.h              |   70 ++
 bsd-user/signal.c                     | 1001 ++++++++++++++++++++++++-
 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     |    4 +-
 meson.build                           |    6 +-
 23 files changed, 1477 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] 72+ messages in thread

* [PATCH v2 01/40] bsd-user: Complete FreeBSD siginfo
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  5:43   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context Warner Losh
                   ` (38 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
  2022-01-25  1:29 ` [PATCH v2 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  5:45   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm Warner Losh
                   ` (37 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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..7491629477a 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 *regs, 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] 72+ messages in thread

* [PATCH v2 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
  2022-01-25  1:29 ` [PATCH v2 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
  2022-01-25  1:29 ` [PATCH v2 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  5:56   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data Warner Losh
                   ` (36 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 bsd-user/arm/signal.c               | 50 +++++++++++++++++++----------
 bsd-user/freebsd/target_os_signal.h |  2 +-
 2 files changed, 34 insertions(+), 18 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() */
diff --git a/bsd-user/freebsd/target_os_signal.h b/bsd-user/freebsd/target_os_signal.h
index 7491629477a..43700d08f71 100644
--- a/bsd-user/freebsd/target_os_signal.h
+++ b/bsd-user/freebsd/target_os_signal.h
@@ -4,7 +4,7 @@
 #include "target_os_siginfo.h"
 #include "target_arch_signal.h"
 
-abi_long setup_sigframe_arch(CPUArchState *regs, abi_ulong frame_addr,
+abi_long setup_sigframe_arch(CPUArchState *env, abi_ulong frame_addr,
                              struct target_sigframe *frame, int flags);
 
 /* Compare to sys/signal.h */
-- 
2.33.1



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

* [PATCH v2 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (2 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  5:59   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 05/40] bsd-user: Remove vestiges of signal queueing code Warner Losh
                   ` (35 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 bsd-user/arm/signal.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index 9026343b478..6eadc6e3c56 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -109,6 +109,14 @@ 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 set_mcontext doesn't save VFP info, but blanks it out instead.
+     * Instead, sysarch(ARM_GET_VFPSTATE) is used instead.
+     */
+    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] 72+ messages in thread

* [PATCH v2 05/40] bsd-user: Remove vestiges of signal queueing code
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (3 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:16   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 06/40] bsd-user: Bring in docs from linux-user for signal_pending Warner Losh
                   ` (34 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 06/40] bsd-user: Bring in docs from linux-user for signal_pending
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (4 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 05/40] bsd-user: Remove vestiges of signal queueing code Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:16   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
                   ` (33 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (5 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 06/40] bsd-user: Bring in docs from linux-user for signal_pending Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 08/40] bsd-user/signal.c: implement force_sig_fault Warner Losh
                   ` (32 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 08/40] bsd-user/signal.c: implement force_sig_fault
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (6 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 07/40] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here Warner Losh
                   ` (31 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (7 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 08/40] bsd-user/signal.c: implement force_sig_fault Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:17   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
                   ` (30 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 bsd-user/qemu.h          | 8 --------
 bsd-user/signal-common.h | 6 ++++++
 2 files changed, 6 insertions(+), 8 deletions(-)

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
-- 
2.33.1



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

* [PATCH v2 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (8 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
                   ` (29 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (9 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 10/40] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 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; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (10 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
                   ` (27 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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 | 23 +++--------------------
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index c526fc73502..05b19ce6119 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"
 
@@ -64,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;
@@ -171,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] 72+ messages in thread

* [PATCH v2 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (11 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 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; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (12 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:27   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
                   ` (25 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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..f4b72939b2d 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
+             * 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] 72+ messages in thread

* [PATCH v2 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (13 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 16/40] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
                   ` (24 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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 f4b72939b2d..2f1ab4c6ac2 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] 72+ messages in thread

* [PATCH v2 16/40] bsd-user/signal.c: implement abstract target / host signal translation
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (14 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:29   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 17/40] bsd-user/signal.c: Implement signal_init() Warner Losh
                   ` (23 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 17/40] bsd-user/signal.c: Implement signal_init()
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (15 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 16/40] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 18/40] bsd-user/signal.c: Add si_type argument to queue_signal Warner Losh
                   ` (22 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 18/40] bsd-user/signal.c: Add si_type argument to queue_signal
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (16 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 17/40] bsd-user/signal.c: Implement signal_init() Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:38   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
                   ` (21 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_*
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (17 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 18/40] bsd-user/signal.c: Add si_type argument to queue_signal Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  6:38   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 20/40] bsd-user/host/i386/host-signal.h: " Warner Losh
                   ` (20 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 20/40] bsd-user/host/i386/host-signal.h: Implement host_signal_*
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (18 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 21/40] bsd-user/host/x86_64/host-signal.h: " Warner Losh
                   ` (19 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 21/40] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (19 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 20/40] bsd-user/host/i386/host-signal.h: " Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 22/40] bsd-user: Add host signals to the build Warner Losh
                   ` (18 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 22/40] bsd-user: Add host signals to the build
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (20 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 21/40] bsd-user/host/x86_64/host-signal.h: " Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 23/40] bsd-user: Add trace events for bsd-user Warner Losh
                   ` (17 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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/meson.build | 1 +
 bsd-user/signal.c    | 1 +
 meson.build          | 1 +
 3 files changed, 3 insertions(+)

diff --git a/bsd-user/meson.build b/bsd-user/meson.build
index 9fcb80c3fa8..a768e65d35e 100644
--- a/bsd-user/meson.build
+++ b/bsd-user/meson.build
@@ -4,6 +4,7 @@ endif
 
 bsd_user_ss = ss.source_set()
 
+common_user_inc += include_directories('host/' / host_arch)
 common_user_inc += include_directories('.')
 
 bsd_user_ss.add(files(
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 c1b1db1e28c..99bb7ba3a57 100644
--- a/meson.build
+++ b/meson.build
@@ -2932,6 +2932,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] 72+ messages in thread

* [PATCH v2 23/40] bsd-user: Add trace events for bsd-user
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (21 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 22/40] bsd-user: Add host signals to the build Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
                   ` (16 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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 99bb7ba3a57..9fc9e0ddab9 100644
--- a/meson.build
+++ b/meson.build
@@ -2437,9 +2437,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] 72+ messages in thread

* [PATCH v2 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (22 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 23/40] bsd-user: Add trace events for bsd-user Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:40   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
                   ` (15 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (23 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 26/40] bsd-user/signal.c: Implement host_signal_handler Warner Losh
                   ` (14 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 26/40] bsd-user/signal.c: Implement host_signal_handler
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (24 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 25/40] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:42   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 27/40] bsd-user/strace.c: print_taken_signal Warner Losh
                   ` (13 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 27/40] bsd-user/strace.c: print_taken_signal
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (25 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 26/40] bsd-user/signal.c: Implement host_signal_handler Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 28/40] bsd-user/signal.c: Implement dump_core_and_abort Warner Losh
                   ` (12 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 28/40] bsd-user/signal.c: Implement dump_core_and_abort
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (26 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 27/40] bsd-user/strace.c: print_taken_signal Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 29/40] bsd-user/signal.c: Fill in queue_signal Warner Losh
                   ` (11 subsequent siblings)
  39 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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] 72+ messages in thread

* [PATCH v2 29/40] bsd-user/signal.c: Fill in queue_signal
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (27 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 28/40] bsd-user/signal.c: Implement dump_core_and_abort Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:44   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 30/40] bsd-user/signal.c: sigset manipulation routines Warner Losh
                   ` (10 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 bsd-user/qemu.h   |  1 +
 bsd-user/signal.c | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index a7964776fdb..fe0aedcdf3f 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -85,6 +85,7 @@ typedef struct TaskState {
     struct bsd_binprm *bprm;
     struct image_info *info;
 
+    struct emulated_sigtable sync_signal;
     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] 72+ messages in thread

* [PATCH v2 30/40] bsd-user/signal.c: sigset manipulation routines.
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (28 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 29/40] bsd-user/signal.c: Fill in queue_signal Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:45   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 31/40] bsd-user/signal.c: setup_frame Warner Losh
                   ` (9 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* [PATCH v2 31/40] bsd-user/signal.c: setup_frame
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (29 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 30/40] bsd-user/signal.c: sigset manipulation routines Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:47   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 32/40] bsd-user/signal.c: handle_pending_signal Warner Losh
                   ` (8 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 bsd-user/main.c   |  5 +++
 bsd-user/qemu.h   |  3 +-
 bsd-user/signal.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 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 fe0aedcdf3f..05be5de3f03 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -103,7 +103,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..79a7083ddb3 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,78 @@ 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;
+    }
+
+#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] 72+ messages in thread

* [PATCH v2 32/40] bsd-user/signal.c: handle_pending_signal
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (30 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 31/40] bsd-user/signal.c: setup_frame Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:51   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 33/40] bsd-user/signal.c: tswap_siginfo Warner Losh
                   ` (7 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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 05be5de3f03..376b3d48eba 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -95,6 +95,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:
@@ -102,6 +104,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 79a7083ddb3..d82d916bfbc 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -615,6 +615,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] 72+ messages in thread

* [PATCH v2 33/40] bsd-user/signal.c: tswap_siginfo
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (31 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 32/40] bsd-user/signal.c: handle_pending_signal Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:52   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 34/40] bsd-user/signal.c: process_pending_signals Warner Losh
                   ` (6 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 bsd-user/signal.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index d82d916bfbc..aef1fa95490 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] 72+ messages in thread

* [PATCH v2 34/40] bsd-user/signal.c: process_pending_signals
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (32 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 33/40] bsd-user/signal.c: tswap_siginfo Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  7:54   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
                   ` (5 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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 aef1fa95490..9ec4354d232 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -755,8 +755,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 anothe rhost 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] 72+ messages in thread

* [PATCH v2 35/40] bsd-user/signal.c: implement do_sigreturn
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (33 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 34/40] bsd-user/signal.c: process_pending_signals Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27 23:05   ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
                   ` (4 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>

PENDING COMMENTS: from 	Peter Maydell <peter.maydell@linaro.org>

do_sigreturn() itself shouldn't be setting the active signal
mask, at least if you follow the linux-user design. It just
sets the thread's signal_mask field in the TaskState by
calling set_sigmask(), and then on our way out in the
main cpu loop we'll call process_pending_signals() which
sets the real thread signal mask to that value. (This, together
with do_sigreturn() calling block_signals() before it starts
work, avoids some race conditions where a host signal is delivered
as soon as we unblock, I think.)
---
 bsd-user/signal-common.h |  2 +-
 bsd-user/signal.c        | 56 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 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 9ec4354d232..05caf812ccb 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -626,6 +626,62 @@ 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;
+    sigprocmask(SIG_SETMASK, &ts->signal_mask, NULL);
+
+    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] 72+ messages in thread

* [PATCH v2 36/40] bsd-user/signal.c: implement do_sigaction
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (34 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27 22:46   ` Warner Losh
  2022-01-25  1:29 ` [PATCH v2 37/40] bsd-user/signal.c: do_sigaltstack Warner Losh
                   ` (3 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>

Pending Comments from Peter Maydell <peter.maydell@linaro.org>

(1) in block_signals, sigprocmast
For linux-user we rely on sigprocmask() in a multithreaded
program setting the signal mask for only the calling thread,
which isn't POSIX-mandated. (Arguably we should use
pthread_sigmask() instead, but we don't for basically
historical reasons since linux-user is host-OS-specific anyway.)
Does BSD have the same "this changes this thread's signal mask"
semantics for sigprocmask()?

(2) do_sigaction, first if validating which signals can be sent
Kernel seems to allow SIGKILL and SIGSTOP unless act is
non-NULL and act->sa_handler is SIG_DFL ?
https://github.com/freebsd/freebsd-src/blob/main/sys/kern/kern_sig.c#L747
(Compare linux-user commit ee3500d33a7431, a recent bugfix.)

(3) Noting confusion in do_sigaction between host and target
errnos (they are identical on BSD, but we should still return
the right sort in case it ever does matter).
---
 bsd-user/signal-common.h | 22 ++++++++++++
 bsd-user/signal.c        | 76 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 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 05caf812ccb..42021556d65 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -309,6 +309,22 @@ static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
     }
 }
 
+int block_signals(void)
+{
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+    sigset_t set;
+
+    /*
+     * It's OK to block everything including SIGSEGV, because we won't run any
+     * further guest code before unblocking signals in
+     * process_pending_signals().
+     */
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, 0);
+
+    return qatomic_xchg(&ts->signal_pending, 1);
+}
+
 /* Returns 1 if given signal should dump core if not handled. */
 static int core_dump_signal(int sig)
 {
@@ -554,6 +570,66 @@ 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 || sig == TARGET_SIGKILL ||
+        sig == TARGET_SIGSTOP) {
+        return -EINVAL;
+    }
+
+    if (block_signals()) {
+        return -TARGET_ERESTART;
+    }
+
+    k = &sigact_table[sig - 1];
+    if (oact) {
+        oact->_sa_handler = tswapal(k->_sa_handler);
+        oact->sa_flags = tswap32(k->sa_flags);
+        oact->sa_mask = k->sa_mask;
+    }
+    if (act) {
+        /* XXX: this is most likely not threadsafe. */
+        k->_sa_handler = tswapal(act->_sa_handler);
+        k->sa_flags = tswap32(act->sa_flags);
+        k->sa_mask = act->sa_mask;
+
+        /* Update the host signal state. */
+        host_sig = target_to_host_signal(sig);
+        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
+            memset(&act1, 0, sizeof(struct sigaction));
+            sigfillset(&act1.sa_mask);
+            act1.sa_flags = SA_SIGINFO;
+            if (k->sa_flags & TARGET_SA_RESTART) {
+                act1.sa_flags |= SA_RESTART;
+            }
+            /*
+             *  Note: It is important to update the host kernel signal mask to
+             *  avoid getting unexpected interrupted system calls.
+             */
+            if (k->_sa_handler == TARGET_SIG_IGN) {
+                act1.sa_sigaction = (void *)SIG_IGN;
+            } else if (k->_sa_handler == TARGET_SIG_DFL) {
+                if (fatal_signal(sig)) {
+                    act1.sa_sigaction = host_signal_handler;
+                } else {
+                    act1.sa_sigaction = (void *)SIG_DFL;
+                }
+            } else {
+                act1.sa_sigaction = host_signal_handler;
+            }
+            ret = sigaction(host_sig, &act1, NULL);
+        }
+    }
+    return ret;
+}
+
 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
         CPUArchState *env, size_t frame_size)
 {
-- 
2.33.1



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

* [PATCH v2 37/40] bsd-user/signal.c: do_sigaltstack
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (35 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  8:00   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on Warner Losh
                   ` (2 subsequent siblings)
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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 42021556d65..4ec5598eb43 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,
@@ -570,6 +565,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] 72+ messages in thread

* [PATCH v2 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (36 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 37/40] bsd-user/signal.c: do_sigaltstack Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  8:00   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 39/40] bsd-user: Rename arg name for target_cpu_reset to env Warner Losh
  2022-01-25  1:29 ` [PATCH v2 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args Warner Losh
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c98a61caeee..a2809761f65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3101,6 +3101,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] 72+ messages in thread

* [PATCH v2 39/40] bsd-user: Rename arg name for target_cpu_reset to env
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (37 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  8:00   ` Richard Henderson
  2022-01-25  1:29 ` [PATCH v2 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args Warner Losh
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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 2f1ab4c6ac2..a52c39f6943 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 b28602adbbd..91849b5804a 100644
--- a/bsd-user/i386/target_arch_cpu.h
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -199,9 +199,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 5172b230f09..535aa9192da 100644
--- a/bsd-user/x86_64/target_arch_cpu.h
+++ b/bsd-user/x86_64/target_arch_cpu.h
@@ -237,9 +237,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] 72+ messages in thread

* [PATCH v2 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args
  2022-01-25  1:29 [PATCH v2 00/40] bsd-user: upstream our signal implementation Warner Losh
                   ` (38 preceding siblings ...)
  2022-01-25  1:29 ` [PATCH v2 39/40] bsd-user: Rename arg name for target_cpu_reset to env Warner Losh
@ 2022-01-25  1:29 ` Warner Losh
  2022-01-27  8:00   ` Richard Henderson
  39 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-25  1:29 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>
---
 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] 72+ messages in thread

* Re: [PATCH v2 01/40] bsd-user: Complete FreeBSD siginfo
  2022-01-25  1:29 ` [PATCH v2 01/40] bsd-user: Complete FreeBSD siginfo Warner Losh
@ 2022-01-27  5:43   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  5:43 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> Fill in the missing FreeBSD siginfo fields, and add some comments.
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/freebsd/target_os_siginfo.h | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)

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


r~




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

* Re: [PATCH v2 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context
  2022-01-25  1:29 ` [PATCH v2 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context Warner Losh
@ 2022-01-27  5:45   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  5:45 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   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(+)

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


r~




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

* Re: [PATCH v2 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm
  2022-01-25  1:29 ` [PATCH v2 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm Warner Losh
@ 2022-01-27  5:56   ` Richard Henderson
  2022-01-27 16:42     ` Warner Losh
  0 siblings, 1 reply; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  5:56 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/arm/signal.c               | 50 +++++++++++++++++++----------
>   bsd-user/freebsd/target_os_signal.h |  2 +-
>   2 files changed, 34 insertions(+), 18 deletions(-)

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

> diff --git a/bsd-user/freebsd/target_os_signal.h b/bsd-user/freebsd/target_os_signal.h
> index 7491629477a..43700d08f71 100644
> --- a/bsd-user/freebsd/target_os_signal.h
> +++ b/bsd-user/freebsd/target_os_signal.h
> @@ -4,7 +4,7 @@
>   #include "target_os_siginfo.h"
>   #include "target_arch_signal.h"
>   
> -abi_long setup_sigframe_arch(CPUArchState *regs, abi_ulong frame_addr,
> +abi_long setup_sigframe_arch(CPUArchState *env, abi_ulong frame_addr,
>                                struct target_sigframe *frame, int flags);
>   
>   /* Compare to sys/signal.h */

Should be in patch 2.


r~


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

* Re: [PATCH v2 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data
  2022-01-25  1:29 ` [PATCH v2 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data Warner Losh
@ 2022-01-27  5:59   ` Richard Henderson
  2022-01-27 15:44     ` Warner Losh
  0 siblings, 1 reply; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  5:59 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/arm/signal.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
> index 9026343b478..6eadc6e3c56 100644
> --- a/bsd-user/arm/signal.c
> +++ b/bsd-user/arm/signal.c
> @@ -109,6 +109,14 @@ 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 set_mcontext doesn't save VFP info, but blanks it out instead.
> +     * Instead, sysarch(ARM_GET_VFPSTATE) is used instead.
> +     */

Could be rewritten with fewer "instead".  You wanted get_mcontext.
Otherwise,

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


r~



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

* Re: [PATCH v2 05/40] bsd-user: Remove vestiges of signal queueing code
  2022-01-25  1:29 ` [PATCH v2 05/40] bsd-user: Remove vestiges of signal queueing code Warner Losh
@ 2022-01-27  6:16   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:16 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/main.c |  9 +--------
>   bsd-user/qemu.h | 13 +------------
>   2 files changed, 2 insertions(+), 20 deletions(-)

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

r~


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

* Re: [PATCH v2 06/40] bsd-user: Bring in docs from linux-user for signal_pending
  2022-01-25  1:29 ` [PATCH v2 06/40] bsd-user: Bring in docs from linux-user for signal_pending Warner Losh
@ 2022-01-27  6:16   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:16 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> This is currently unused, so no code adjustments are needed.
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/qemu.h | 9 ++++++++-
>   1 file changed, 8 insertions(+), 1 deletion(-)

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

r~


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

* Re: [PATCH v2 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here
  2022-01-25  1:29 ` [PATCH v2 09/40] bsd-user/signal-common.h: Move signal functions prototypes to here Warner Losh
@ 2022-01-27  6:17   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:17 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/qemu.h          | 8 --------
>   bsd-user/signal-common.h | 6 ++++++
>   2 files changed, 6 insertions(+), 8 deletions(-)

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

r~


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

* Re: [PATCH v2 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-25  1:29 ` [PATCH v2 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
@ 2022-01-27  6:27   ` Richard Henderson
  2022-01-27 15:40     ` Warner Losh
  0 siblings, 1 reply; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:27 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> +        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

As I mentioned, misaligned pc will not come here for qemu.
In the Arm ARM, see aarch32/functions/registers/BXWritePC:

// For branches to an unaligned PC counter in A32 state, the processor takes the branch
// and does one of:
// * Forces the address to be aligned
// * Leaves the PC unaligned, meaning the target generates a PC Alignment fault.

The hardware will either refuse to allow bit 1 to be set when bit 0 is clear, OR it will 
generate a PREFETCH_DATA_ABORT for Alignment.

QEMU will do the latter.


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


r~


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

* Re: [PATCH v2 16/40] bsd-user/signal.c: implement abstract target / host signal translation
  2022-01-25  1:29 ` [PATCH v2 16/40] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
@ 2022-01-27  6:29   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:29 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal-common.h |  2 ++
>   bsd-user/signal.c        | 16 ++++++++++++++++
>   2 files changed, 18 insertions(+)

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

r~


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

* Re: [PATCH v2 18/40] bsd-user/signal.c: Add si_type argument to queue_signal
  2022-01-25  1:29 ` [PATCH v2 18/40] bsd-user/signal.c: Add si_type argument to queue_signal Warner Losh
@ 2022-01-27  6:38   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:38 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal-common.h | 26 +++++++++++++++++++++++++-
>   bsd-user/signal.c        |  5 +++--
>   2 files changed, 28 insertions(+), 3 deletions(-)

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

r~


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

* Re: [PATCH v2 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_*
  2022-01-25  1:29 ` [PATCH v2 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
@ 2022-01-27  6:38   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  6:38 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/host/arm/host-signal.h | 35 +++++++++++++++++++++++++++++++++
>   1 file changed, 35 insertions(+)
>   create mode 100644 bsd-user/host/arm/host-signal.h

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

r~


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

* Re: [PATCH v2 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-25  1:29 ` [PATCH v2 24/40] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
@ 2022-01-27  7:40   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:40 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 113 insertions(+)

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

r~


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

* Re: [PATCH v2 26/40] bsd-user/signal.c: Implement host_signal_handler
  2022-01-25  1:29 ` [PATCH v2 26/40] bsd-user/signal.c: Implement host_signal_handler Warner Losh
@ 2022-01-27  7:42   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:42 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 105 insertions(+)

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

r~


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

* Re: [PATCH v2 29/40] bsd-user/signal.c: Fill in queue_signal
  2022-01-25  1:29 ` [PATCH v2 29/40] bsd-user/signal.c: Fill in queue_signal Warner Losh
@ 2022-01-27  7:44   ` Richard Henderson
  2022-01-27 15:34     ` Warner Losh
  0 siblings, 1 reply; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:44 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/qemu.h   |  1 +
>   bsd-user/signal.c | 13 ++++++++++++-
>   2 files changed, 13 insertions(+), 1 deletion(-)

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

> +    struct emulated_sigtable sync_signal;
>       struct emulated_sigtable sigtab[TARGET_NSIG];

I'll note that we don't need an array of these, since we block all signals while returning 
to the main cpu loop, so we can't receive a second async signal.  Something to be fixed 
for both l-user and b-user later...


r~


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

* Re: [PATCH v2 30/40] bsd-user/signal.c: sigset manipulation routines.
  2022-01-25  1:29 ` [PATCH v2 30/40] bsd-user/signal.c: sigset manipulation routines Warner Losh
@ 2022-01-27  7:45   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:45 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal-common.h |  2 ++
>   bsd-user/signal.c        | 74 ++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 76 insertions(+)

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

r~


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

* Re: [PATCH v2 31/40] bsd-user/signal.c: setup_frame
  2022-01-25  1:29 ` [PATCH v2 31/40] bsd-user/signal.c: setup_frame Warner Losh
@ 2022-01-27  7:47   ` Richard Henderson
  2022-01-27 15:30     ` Warner Losh
  0 siblings, 1 reply; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:47 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/main.c   |  5 +++
>   bsd-user/qemu.h   |  3 +-
>   bsd-user/signal.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 89 insertions(+), 1 deletion(-)

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


> +#if defined(TARGET_ARM)
> +    return (sp - frame_size) & ~7;
> +#elif defined(TARGET_AARCH64)
> +    return (sp - frame_size) & ~15;
> +#else
> +    return sp - frame_size;
> +#endif

Just double-checking that this is still in the cleanup queue.
I would expect x86 to require 16 byte alignment as well, for sse.


r~


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

* Re: [PATCH v2 32/40] bsd-user/signal.c: handle_pending_signal
  2022-01-25  1:29 ` [PATCH v2 32/40] bsd-user/signal.c: handle_pending_signal Warner Losh
@ 2022-01-27  7:51   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:51 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/qemu.h   |  7 ++++
>   bsd-user/signal.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 94 insertions(+)

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

r~


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

* Re: [PATCH v2 33/40] bsd-user/signal.c: tswap_siginfo
  2022-01-25  1:29 ` [PATCH v2 33/40] bsd-user/signal.c: tswap_siginfo Warner Losh
@ 2022-01-27  7:52   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:52 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 53 insertions(+)

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

r~


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

* Re: [PATCH v2 34/40] bsd-user/signal.c: process_pending_signals
  2022-01-25  1:29 ` [PATCH v2 34/40] bsd-user/signal.c: process_pending_signals Warner Losh
@ 2022-01-27  7:54   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  7:54 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 55 insertions(+), 1 deletion(-)

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

> +         * us to take anothe rhost signal, which will set signal_pending again.

Typo around "another".


r~


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

* Re: [PATCH v2 37/40] bsd-user/signal.c: do_sigaltstack
  2022-01-25  1:29 ` [PATCH v2 37/40] bsd-user/signal.c: do_sigaltstack Warner Losh
@ 2022-01-27  8:00   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  8:00 UTC (permalink / raw)
  To: Warner Losh, qemu-devel
  Cc: Peter Maydell, def, Stacey Son, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 72 +++++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 67 insertions(+), 5 deletions(-)

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

r~


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

* Re: [PATCH v2 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on
  2022-01-25  1:29 ` [PATCH v2 38/40] MAINTAINERS: Add tests/vm/*bsd to the list to get reviews on Warner Losh
@ 2022-01-27  8:00   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  8:00 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> 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>
> ---
>   MAINTAINERS | 1 +
>   1 file changed, 1 insertion(+)

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

r~


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

* Re: [PATCH v2 39/40] bsd-user: Rename arg name for target_cpu_reset to env
  2022-01-25  1:29 ` [PATCH v2 39/40] bsd-user: Rename arg name for target_cpu_reset to env Warner Losh
@ 2022-01-27  8:00   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  8:00 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> Rename the parameter name for target_cpu_reset's CPUArchState * arg from
> cpu to env.
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   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(-)

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

r~


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

* Re: [PATCH v2 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args
  2022-01-25  1:29 ` [PATCH v2 40/40] bsd-user/freebsd/target_os_ucontext.h: Prefer env as arg name for CPUArchState args Warner Losh
@ 2022-01-27  8:00   ` Richard Henderson
  0 siblings, 0 replies; 72+ messages in thread
From: Richard Henderson @ 2022-01-27  8:00 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Peter Maydell, def, jrtc27, Kyle Evans

On 1/25/22 12:29, Warner Losh wrote:
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/freebsd/target_os_ucontext.h | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)

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

r~


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

* Re: [PATCH v2 31/40] bsd-user/signal.c: setup_frame
  2022-01-27  7:47   ` Richard Henderson
@ 2022-01-27 15:30     ` Warner Losh
  0 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-27 15:30 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: 1232 bytes --]

On Thu, Jan 27, 2022 at 12:47 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/25/22 12:29, Warner Losh wrote:
> > 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>
> > ---
> >   bsd-user/main.c   |  5 +++
> >   bsd-user/qemu.h   |  3 +-
> >   bsd-user/signal.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++
> >   3 files changed, 89 insertions(+), 1 deletion(-)
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
>
> > +#if defined(TARGET_ARM)
> > +    return (sp - frame_size) & ~7;
> > +#elif defined(TARGET_AARCH64)
> > +    return (sp - frame_size) & ~15;
> > +#else
> > +    return sp - frame_size;
> > +#endif
>
> Just double-checking that this is still in the cleanup queue.
> I would expect x86 to require 16 byte alignment as well, for sse


I'll add

/* TODO: make this a target_arch function / define */

to make it clear that it's still on the list...  Thanks for the reminder.
There's
a lot on the list, alas...

 Warner


>
> r~
>

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

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

* Re: [PATCH v2 29/40] bsd-user/signal.c: Fill in queue_signal
  2022-01-27  7:44   ` Richard Henderson
@ 2022-01-27 15:34     ` Warner Losh
  0 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-27 15: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: 1140 bytes --]

On Thu, Jan 27, 2022 at 12:44 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/25/22 12:29, Warner Losh wrote:
> > 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>
> > ---
> >   bsd-user/qemu.h   |  1 +
> >   bsd-user/signal.c | 13 ++++++++++++-
> >   2 files changed, 13 insertions(+), 1 deletion(-)
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
> > +    struct emulated_sigtable sync_signal;
> >       struct emulated_sigtable sigtab[TARGET_NSIG];
>
> I'll note that we don't need an array of these, since we block all signals
> while returning
> to the main cpu loop, so we can't receive a second async signal.
> Something to be fixed
> for both l-user and b-user later...
>

I'll add
+    /*
+     * TODO: Since we block all signals while returning to the main CPU
+     * loop, this needn't be an array
+     */
before the array to document this so it doesn't get lost...

Warner

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

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

* Re: [PATCH v2 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-27  6:27   ` Richard Henderson
@ 2022-01-27 15:40     ` Warner Losh
  0 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-27 15:40 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, Konrad Witaszczyk, QEMU Developers, Kyle Evans,
	Jessica Clarke

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

On Wed, Jan 26, 2022 at 11:27 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/25/22 12:29, Warner Losh wrote:
> > +        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
>
> As I mentioned, misaligned pc will not come here for qemu.
> In the Arm ARM, see aarch32/functions/registers/BXWritePC:
>
> // For branches to an unaligned PC counter in A32 state, the processor
> takes the branch
> // and does one of:
> // * Forces the address to be aligned
> // * Leaves the PC unaligned, meaning the target generates a PC Alignment
> fault.
>
> The hardware will either refuse to allow bit 1 to be set when bit 0 is
> clear, OR it will
> generate a PREFETCH_DATA_ABORT for Alignment.
>
> QEMU will do the latter.
>

Ah, right. I'd meant to update the comments and it slipped my mind. I'll
note
that this can't happen in qemu.


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

Thanks for this (and all the other) review and feedback.

Warner




> r~
>

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

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

* Re: [PATCH v2 04/40] bsd-user/arm/signal.c: get_mcontext should zero vfp data
  2022-01-27  5:59   ` Richard Henderson
@ 2022-01-27 15:44     ` Warner Losh
  0 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-27 15:44 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, Konrad Witaszczyk, QEMU Developers, Kyle Evans,
	Jessica Clarke

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

On Wed, Jan 26, 2022 at 10:59 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/25/22 12:29, Warner Losh wrote:
> > 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>
> > ---
> >   bsd-user/arm/signal.c | 8 ++++++++
> >   1 file changed, 8 insertions(+)
> >
> > diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
> > index 9026343b478..6eadc6e3c56 100644
> > --- a/bsd-user/arm/signal.c
> > +++ b/bsd-user/arm/signal.c
> > @@ -109,6 +109,14 @@ 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 set_mcontext doesn't save VFP info, but blanks it out
> instead.
> > +     * Instead, sysarch(ARM_GET_VFPSTATE) is used instead.
> > +     */
>
> Could be rewritten with fewer "instead".  You wanted get_mcontext.
>

Yes. Instead is indeed over used over and over redundantly :)

Thanks!

Warner


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

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

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

* Re: [PATCH v2 03/40] bsd-user/arm/signal.c: Implement setup_sigframe_arch for arm
  2022-01-27  5:56   ` Richard Henderson
@ 2022-01-27 16:42     ` Warner Losh
  0 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-27 16:42 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, Konrad Witaszczyk, QEMU Developers, Kyle Evans,
	Jessica Clarke

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

On Wed, Jan 26, 2022 at 10:56 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/25/22 12:29, Warner Losh wrote:
> > 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>
> > ---
> >   bsd-user/arm/signal.c               | 50 +++++++++++++++++++----------
> >   bsd-user/freebsd/target_os_signal.h |  2 +-
> >   2 files changed, 34 insertions(+), 18 deletions(-)
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
> > diff --git a/bsd-user/freebsd/target_os_signal.h
> b/bsd-user/freebsd/target_os_signal.h
> > index 7491629477a..43700d08f71 100644
> > --- a/bsd-user/freebsd/target_os_signal.h
> > +++ b/bsd-user/freebsd/target_os_signal.h
> > @@ -4,7 +4,7 @@
> >   #include "target_os_siginfo.h"
> >   #include "target_arch_signal.h"
> >
> > -abi_long setup_sigframe_arch(CPUArchState *regs, abi_ulong frame_addr,
> > +abi_long setup_sigframe_arch(CPUArchState *env, abi_ulong frame_addr,
> >                                struct target_sigframe *frame, int flags);
> >
> >   /* Compare to sys/signal.h */
>
> Should be in patch 2.
>

Yea, I back merged those changes after making them on blitz and landed it
in the
wrong spot. Good eye.

Warner


> r~
>

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

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

* Re: [PATCH v2 36/40] bsd-user/signal.c: implement do_sigaction
  2022-01-25  1:29 ` [PATCH v2 36/40] bsd-user/signal.c: implement do_sigaction Warner Losh
@ 2022-01-27 22:46   ` Warner Losh
  2022-01-28 10:37     ` Peter Maydell
  0 siblings, 1 reply; 72+ messages in thread
From: Warner Losh @ 2022-01-27 22:46 UTC (permalink / raw)
  To: Warner Losh
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson,
	QEMU Developers, def@freebsd.org, jrtc27@freebsd.org



> On Jan 24, 2022, at 6:29 PM, Warner Losh <imp@bsdimp.com> wrote:
> 
> 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>
> 
> Pending Comments from Peter Maydell <peter.maydell@linaro.org>
> 
> (1) in block_signals, sigprocmast
> For linux-user we rely on sigprocmask() in a multithreaded
> program setting the signal mask for only the calling thread,
> which isn't POSIX-mandated. (Arguably we should use
> pthread_sigmask() instead, but we don't for basically
> historical reasons since linux-user is host-OS-specific anyway.)
> Does BSD have the same "this changes this thread's signal mask"
> semantics for sigprocmask()?

FreeBSD changes this on a per-thread basis for both
sigprocmask and pthread_sigmask(). pthread_sigmask() just
does some extra stuff with SIGCANCEL for pthread_cancel
support which qemu doesn’t use. They are the same. I’m inclined
to leave it as sigprocmask() since I’m unsure what the implications
of doing funky things for SIGCANCEL would be.

> (2) do_sigaction, first if validating which signals can be sent
> Kernel seems to allow SIGKILL and SIGSTOP unless act is
> non-NULL and act->sa_handler is SIG_DFL ?
> https://github.com/freebsd/freebsd-src/blob/main/sys/kern/kern_sig.c#L747
> (Compare linux-user commit ee3500d33a7431, a recent bugfix.)

That fix is relevant, so I’ll bring that in. Thanks!

> (3) Noting confusion in do_sigaction between host and target
> errnos (they are identical on BSD, but we should still return
> the right sort in case it ever does matter).

Will fix before V3 of patches.

Warner

> ---
> bsd-user/signal-common.h | 22 ++++++++++++
> bsd-user/signal.c        | 76 ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 98 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 05caf812ccb..42021556d65 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -309,6 +309,22 @@ static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
>     }
> }
> 
> +int block_signals(void)
> +{
> +    TaskState *ts = (TaskState *)thread_cpu->opaque;
> +    sigset_t set;
> +
> +    /*
> +     * It's OK to block everything including SIGSEGV, because we won't run any
> +     * further guest code before unblocking signals in
> +     * process_pending_signals().
> +     */
> +    sigfillset(&set);
> +    sigprocmask(SIG_SETMASK, &set, 0);
> +
> +    return qatomic_xchg(&ts->signal_pending, 1);
> +}
> +
> /* Returns 1 if given signal should dump core if not handled. */
> static int core_dump_signal(int sig)
> {
> @@ -554,6 +570,66 @@ 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 || sig == TARGET_SIGKILL ||
> +        sig == TARGET_SIGSTOP) {
> +        return -EINVAL;
> +    }
> +
> +    if (block_signals()) {
> +        return -TARGET_ERESTART;
> +    }
> +
> +    k = &sigact_table[sig - 1];
> +    if (oact) {
> +        oact->_sa_handler = tswapal(k->_sa_handler);
> +        oact->sa_flags = tswap32(k->sa_flags);
> +        oact->sa_mask = k->sa_mask;
> +    }
> +    if (act) {
> +        /* XXX: this is most likely not threadsafe. */
> +        k->_sa_handler = tswapal(act->_sa_handler);
> +        k->sa_flags = tswap32(act->sa_flags);
> +        k->sa_mask = act->sa_mask;
> +
> +        /* Update the host signal state. */
> +        host_sig = target_to_host_signal(sig);
> +        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
> +            memset(&act1, 0, sizeof(struct sigaction));
> +            sigfillset(&act1.sa_mask);
> +            act1.sa_flags = SA_SIGINFO;
> +            if (k->sa_flags & TARGET_SA_RESTART) {
> +                act1.sa_flags |= SA_RESTART;
> +            }
> +            /*
> +             *  Note: It is important to update the host kernel signal mask to
> +             *  avoid getting unexpected interrupted system calls.
> +             */
> +            if (k->_sa_handler == TARGET_SIG_IGN) {
> +                act1.sa_sigaction = (void *)SIG_IGN;
> +            } else if (k->_sa_handler == TARGET_SIG_DFL) {
> +                if (fatal_signal(sig)) {
> +                    act1.sa_sigaction = host_signal_handler;
> +                } else {
> +                    act1.sa_sigaction = (void *)SIG_DFL;
> +                }
> +            } else {
> +                act1.sa_sigaction = host_signal_handler;
> +            }
> +            ret = sigaction(host_sig, &act1, NULL);
> +        }
> +    }
> +    return ret;
> +}
> +
> static inline abi_ulong get_sigframe(struct target_sigaction *ka,
>         CPUArchState *env, size_t frame_size)
> {
> -- 
> 2.33.1
> 



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

* Re: [PATCH v2 35/40] bsd-user/signal.c: implement do_sigreturn
  2022-01-25  1:29 ` [PATCH v2 35/40] bsd-user/signal.c: implement do_sigreturn Warner Losh
@ 2022-01-27 23:05   ` Warner Losh
  0 siblings, 0 replies; 72+ messages in thread
From: Warner Losh @ 2022-01-27 23:05 UTC (permalink / raw)
  To: Warner Losh
  Cc: Peter Maydell, Stacey Son, Kyle Evans, Richard Henderson,
	qemu-devel, def@freebsd.org, jrtc27@freebsd.org



> On Jan 24, 2022, at 6:29 PM, Warner Losh <imp@bsdimp.com> wrote:
> 
> 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>
> 
> PENDING COMMENTS: from 	Peter Maydell <peter.maydell@linaro.org>
> 
> do_sigreturn() itself shouldn't be setting the active signal
> mask, at least if you follow the linux-user design. It just
> sets the thread's signal_mask field in the TaskState by
> calling set_sigmask(), and then on our way out in the
> main cpu loop we'll call process_pending_signals() which
> sets the real thread signal mask to that value. (This, together
> with do_sigreturn() calling block_signals() before it starts
> work, avoids some race conditions where a host signal is delivered
> as soon as we unblock, I think.)

I think this is correct. We’re already setting the signal_mask element
in a mostly similar way to linux-user, so all I need to do is to remove the
setting the actual signal mask. The rest of this is already in place. I’ll
included in v3.

Warner

> ---
> bsd-user/signal-common.h |  2 +-
> bsd-user/signal.c        | 56 ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 57 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 9ec4354d232..05caf812ccb 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -626,6 +626,62 @@ 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;
> +    sigprocmask(SIG_SETMASK, &ts->signal_mask, NULL);
> +
> +    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	[flat|nested] 72+ messages in thread

* Re: [PATCH v2 36/40] bsd-user/signal.c: implement do_sigaction
  2022-01-27 22:46   ` Warner Losh
@ 2022-01-28 10:37     ` Peter Maydell
  0 siblings, 0 replies; 72+ messages in thread
From: Peter Maydell @ 2022-01-28 10:37 UTC (permalink / raw)
  To: Warner Losh
  Cc: Stacey Son, Kyle Evans, Richard Henderson, QEMU Developers, def,
	jrtc27, Warner Losh

On Thu, 27 Jan 2022 at 22:46, Warner Losh <wlosh@bsdimp.com> wrote:
>
>
>
> > On Jan 24, 2022, at 6:29 PM, Warner Losh <imp@bsdimp.com> wrote:
> >
> > 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>
> >
> > Pending Comments from Peter Maydell <peter.maydell@linaro.org>
> >
> > (1) in block_signals, sigprocmast
> > For linux-user we rely on sigprocmask() in a multithreaded
> > program setting the signal mask for only the calling thread,
> > which isn't POSIX-mandated. (Arguably we should use
> > pthread_sigmask() instead, but we don't for basically
> > historical reasons since linux-user is host-OS-specific anyway.)
> > Does BSD have the same "this changes this thread's signal mask"
> > semantics for sigprocmask()?
>
> FreeBSD changes this on a per-thread basis for both
> sigprocmask and pthread_sigmask(). pthread_sigmask() just
> does some extra stuff with SIGCANCEL for pthread_cancel
> support which qemu doesn’t use. They are the same. I’m inclined
> to leave it as sigprocmask() since I’m unsure what the implications
> of doing funky things for SIGCANCEL would be.

Yes, that sounds like the right thing.

thanks
-- PMM


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

end of thread, other threads:[~2022-01-28 10:39 UTC | newest]

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

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.