All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/30] bsd-user: upstream our signal implementation
@ 2022-01-09 16:18 Warner Losh
  2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
                   ` (29 more replies)
  0 siblings, 30 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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.

Warner Losh (30):
  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.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/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-usr
  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: core_dump_signal
  bsd-user/signal.c: force_sig
  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

 bsd-user/arm/target_arch_cpu.h     |   91 +--
 bsd-user/host/arm/host-signal.h    |   39 ++
 bsd-user/host/i386/host-signal.h   |   37 +
 bsd-user/host/x86_64/host-signal.h |   37 +
 bsd-user/meson.build               |    1 +
 bsd-user/qemu.h                    |   46 +-
 bsd-user/signal-common.h           |   14 +
 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 +
 meson.build                        |    6 +-
 13 files changed, 1327 insertions(+), 55 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] 105+ messages in thread

* [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
@ 2022-01-09 16:18 ` Warner Losh
  2022-01-13 15:47   ` Peter Maydell
  2022-01-23 21:30   ` Richard Henderson
  2022-01-09 16:18 ` [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault Warner Losh
                   ` (28 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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>
---
 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] 105+ messages in thread

* [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
  2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
@ 2022-01-09 16:18 ` Warner Losh
  2022-01-13 16:43   ` Peter Maydell
  2022-01-23 21:36   ` Richard Henderson
  2022-01-09 16:18 ` [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
                   ` (27 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 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] 105+ messages in thread

* [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
  2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
  2022-01-09 16:18 ` [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault Warner Losh
@ 2022-01-09 16:18 ` Warner Losh
  2022-01-13 17:00   ` Peter Maydell
  2022-01-23 21:38   ` Richard Henderson
  2022-01-09 16:18 ` [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
                   ` (26 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 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] 105+ messages in thread

* [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (2 preceding siblings ...)
  2022-01-09 16:18 ` [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
@ 2022-01-09 16:18 ` Warner Losh
  2022-01-13 17:00   ` Peter Maydell
  2022-01-23 21:38   ` Richard Henderson
  2022-01-09 16:18 ` [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
                   ` (25 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 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] 105+ messages in thread

* [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (3 preceding siblings ...)
  2022-01-09 16:18 ` [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
@ 2022-01-09 16:18 ` Warner Losh
  2022-01-13 17:13   ` Peter Maydell
  2022-01-23 21:40   ` Richard Henderson
  2022-01-09 16:18 ` [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
                   ` (24 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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).

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 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] 105+ messages in thread

* [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (4 preceding siblings ...)
  2022-01-09 16:18 ` [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
@ 2022-01-09 16:18 ` Warner Losh
  2022-01-13 17:15   ` Peter Maydell
  2022-01-23 21:43   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
                   ` (23 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Warner Losh

The code has moved in FreeBSD since the emulator was started, update the
comment to reflect that change. Remove now-redundant comment saying the
same thing (but incorrectly).

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 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] 105+ messages in thread

* [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (5 preceding siblings ...)
  2022-01-09 16:18 ` [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 17:19   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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.

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/arm/target_arch_cpu.h | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 905f13aa1b9..996a361e3fe 100644
--- a/bsd-user/arm/target_arch_cpu.h
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -51,18 +51,12 @@ 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();
+             */
+            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->regs[15]);
             break;
         case EXCP_SWI:
             {
-- 
2.33.1



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

* [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (6 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 17:40   ` Peter Maydell
  2022-01-24  1:12   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
                   ` (21 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Warner Losh

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

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/arm/target_arch_cpu.h | 44 ++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
index 996a361e3fe..51e592bcfe7 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);
 
@@ -143,15 +142,40 @@ 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: /* Permision fault, level 1 */
+            case 0xf: /* Permision 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] 105+ messages in thread

* [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (7 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 17:44   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 10/30] bsd-user/signal.c: Implement signal_init() Warner Losh
                   ` (20 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 bsd-user/qemu.h   |  2 ++
 bsd-user/signal.c | 11 +++++++++++
 2 files changed, 13 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 1b3b974afe9..334f8b1d715 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -210,6 +210,8 @@ 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);
+int target_to_host_signal(int sig);
+int host_to_target_signal(int sig);
 
 /* mmap.c */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 844dfa19095..7ea86149981 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,16 @@
  * fork.
  */
 
+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] 105+ messages in thread

* [PATCH 10/30] bsd-user/signal.c: Implement signal_init()
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (8 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:28   ` Peter Maydell
  2022-01-24  1:38   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
                   ` (19 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 bsd-user/qemu.h   |  1 +
 bsd-user/signal.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 334f8b1d715..0e0b8db708b 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -97,6 +97,7 @@ typedef struct TaskState {
     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 */
+    sigset_t signal_mask;
 
     uint8_t stack[];
 } __attribute__((aligned(16))) TaskState;
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 7ea86149981..b2c91c39379 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);
+
 int host_to_target_signal(int sig)
 {
     return sig;
@@ -47,6 +50,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().
@@ -64,8 +89,51 @@ 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);
+
+    /*
+     * Set all host signal handlers. ALL signals are blocked during the
+     * handlers to serialize them.
+     */
+    memset(sigact_table, 0, sizeof(sigact_table));
+
+    sigfillset(&act.sa_mask);
+    act.sa_sigaction = host_signal_handler;
+    act.sa_flags = SA_SIGINFO;
+
+    for (i = 1; i <= TARGET_NSIG; i++) {
+        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] 105+ messages in thread

* [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_*
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (9 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 10/30] bsd-user/signal.c: Implement signal_init() Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:32   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 12/30] bsd-user/host/i386/host-signal.h: " Warner Losh
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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 | 39 +++++++++++++++++++++++++++++++++
 1 file changed, 39 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..e403c26caed
--- /dev/null
+++ b/bsd-user/host/arm/host-signal.h
@@ -0,0 +1,39 @@
+/*
+ * 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 which we don't have access to here.  We assume that uc
+     * is part of a trapframe and reach around to get to the si_info that's in
+     * the sigframe just before it, though this may be unwise.
+     */
+    siginfo_t *si;
+    si = &((siginfo_t *)uc)[-1];
+    uint32_t fsr = si->si_trapno;
+
+    return extract32(fsr, 11, 1);
+}
+
+#endif
-- 
2.33.1



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

* [PATCH 12/30] bsd-user/host/i386/host-signal.h: Implement host_signal_*
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (10 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:33   ` Peter Maydell
  2022-01-24  1:49   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: " Warner Losh
                   ` (17 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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>
---
 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] 105+ messages in thread

* [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (11 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 12/30] bsd-user/host/i386/host-signal.h: " Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:33   ` Peter Maydell
  2022-01-24  1:52   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 14/30] bsd-user: Add host signals to the build Warner Losh
                   ` (16 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, 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>
---
 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..43961685df1
--- /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] 105+ messages in thread

* [PATCH 14/30] bsd-user: Add host signals to the build
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (12 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: " Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:35   ` Peter Maydell
  2022-01-24  1:56   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 15/30] bsd-user: Add trace events for bsd-usr Warner Losh
                   ` (15 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Warner Losh

Start to add the host signal functionality to the build.

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 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 b2c91c39379..bf5c7eb0c02 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] 105+ messages in thread

* [PATCH 15/30] bsd-user: Add trace events for bsd-usr
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (13 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 14/30] bsd-user: Add host signals to the build Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:37   ` Peter Maydell
  2022-01-24  1:57   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
                   ` (14 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 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 bf5c7eb0c02..7168d851be8 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..a624a9fc34e
--- /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_force_sig(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] 105+ messages in thread

* [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (14 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 15/30] bsd-user: Add trace events for bsd-usr Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:43   ` Peter Maydell
  2022-01-24  2:05   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
                   ` (13 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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 | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 7168d851be8..3fe8b2d9898 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -43,6 +43,43 @@ int target_to_host_signal(int sig)
     return sig;
 }
 
+/* Siginfo conversion. */
+static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
+        const siginfo_t *info)
+{
+    int sig, code;
+
+    sig = host_to_target_signal(info->si_signo);
+    /* XXX should have host_to_target_si_code() */
+    code = tswap32(info->si_code);
+    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 */
+    tinfo->si_value.sival_ptr =
+        (abi_ulong)(unsigned long)info->si_value.sival_ptr;
+    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig ||
+            SIGTRAP == sig) {
+        tinfo->_reason._fault._trapno = info->_reason._fault._trapno;
+    }
+#ifdef SIGPOLL
+    if (SIGPOLL == sig) {
+        tinfo->_reason._poll._band = info->_reason._poll._band;
+    }
+#endif
+    if (SI_TIMER == code) {
+        int timerid;
+
+        timerid = info->_reason._timer._timerid;
+        tinfo->_reason._timer._timerid = timerid;
+        tinfo->_reason._timer._overrun = info->_reason._timer._overrun;
+    }
+}
+
 /*
  * 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] 105+ messages in thread

* [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (15 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 19:44   ` Peter Maydell
  2022-01-24  2:09   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler Warner Losh
                   ` (12 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Warner Losh

Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/qemu.h   |  2 ++
 bsd-user/signal.c | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 0e0b8db708b..e5e97632c82 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -454,4 +454,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 3fe8b2d9898..b1331f63d61 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -43,6 +43,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);
+    }
+}
+
 /* Siginfo conversion. */
 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
         const siginfo_t *info)
-- 
2.33.1



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

* [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (16 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 20:17   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 19/30] bsd-user/strace.c: print_taken_signal Warner Losh
                   ` (11 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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 b1331f63d61..a6e07277fb2 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -142,6 +142,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)
 {
+    CPUState *cpu = thread_cpu;
+    CPUArchState *env = cpu->env_ptr;
+    int sig;
+    target_siginfo_t tinfo;
+    ucontext_t *uc = puc;
+    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. */
+    sig = host_to_target_signal(host_sig);
+    if (sig < 1 || sig > TARGET_NSIG) {
+        return;
+    }
+    trace_user_host_signal(cpu, host_sig, sig);
+
+    host_to_target_siginfo_noswap(&tinfo, info);
+
+    queue_signal(env, sig, &tinfo);       /* XXX how to cope with failure? */
+    /*
+     * Linux does something else here -> the queue signal may be wrong, but
+     * maybe not.  And then it does the rewind_if_in_safe_syscall
+     */
+
+    /*
+     * 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.
+     XXXX Should this be in queue_signal?
+     */
+    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] 105+ messages in thread

* [PATCH 19/30] bsd-user/strace.c: print_taken_signal
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (17 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 20:20   ` Peter Maydell
  2022-01-24  2:45   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 20/30] bsd-user/signal.c: core_dump_signal Warner Losh
                   ` (10 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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>
---
 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 e5e97632c82..7c54a933eb8 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -202,6 +202,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;
 
 /* signal.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] 105+ messages in thread

* [PATCH 20/30] bsd-user/signal.c: core_dump_signal
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (18 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 19/30] bsd-user/strace.c: print_taken_signal Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 20:22   ` Peter Maydell
  2022-01-24  3:01   ` Richard Henderson
  2022-01-09 16:19 ` [PATCH 21/30] bsd-user/signal.c: force_sig Warner Losh
                   ` (9 subsequent siblings)
  29 siblings, 2 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, Warner Losh

Returns 1 for signals that cause core files.

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 | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index a6e07277fb2..824535be8b8 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -92,6 +92,23 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
     }
 }
 
+/* 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;
+    }
+}
+
 /*
  * 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] 105+ messages in thread

* [PATCH 21/30] bsd-user/signal.c: force_sig
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (19 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 20/30] bsd-user/signal.c: core_dump_signal Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 20:29   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal Warner Losh
                   ` (8 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, Warner Losh

Force delivering a signal and generating a core file.

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       | 59 +++++++++++++++++++++++++++++++++++++++++
 bsd-user/syscall_defs.h |  1 +
 3 files changed, 61 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 7c54a933eb8..e12617f5d69 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -223,6 +223,7 @@ 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);
 int target_to_host_signal(int sig);
 int host_to_target_signal(int sig);
+void QEMU_NORETURN force_sig(int target_sig);
 
 /* mmap.c */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 824535be8b8..97f42f9c45e 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -109,6 +109,65 @@ static int core_dump_signal(int sig)
     }
 }
 
+/* Abort execution with signal. */
+void QEMU_NORETURN force_sig(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] 105+ messages in thread

* [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (20 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 21/30] bsd-user/signal.c: force_sig Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-13 20:37   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines Warner Losh
                   ` (7 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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/signal.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 97f42f9c45e..93c3b3c5033 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -109,6 +109,29 @@ static int core_dump_signal(int sig)
     }
 }
 
+/* Signal queue handling. */
+static inline struct qemu_sigqueue *alloc_sigqueue(CPUArchState *env)
+{
+    CPUState *cpu = env_cpu(env);
+    TaskState *ts = cpu->opaque;
+    struct qemu_sigqueue *q = ts->first_free;
+
+    if (!q) {
+        return NULL;
+    }
+    ts->first_free = q->next;
+    return q;
+}
+
+static inline void free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q)
+{
+
+    CPUState *cpu = env_cpu(env);
+    TaskState *ts = cpu->opaque;
+    q->next = ts->first_free;
+    ts->first_free = q;
+}
+
 /* Abort execution with signal. */
 void QEMU_NORETURN force_sig(int target_sig)
 {
@@ -174,7 +197,54 @@ void QEMU_NORETURN force_sig(int target_sig)
  */
 void queue_signal(CPUArchState *env, int sig, 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;
+    struct emulated_sigtable *k;
+    struct qemu_sigqueue *q, **pq;
+
+    k = &ts->sigtab[sig - 1];
+    trace_user_queue_signal(env, sig); /* We called this in the caller? XXX */
+    /*
+     * XXX does the segv changes make this go away? -- I think so
+     */
+    if (sig == TARGET_SIGSEGV && sigismember(&ts->signal_mask, SIGSEGV)) {
+        /*
+         * Guest has blocked SIGSEGV but we got one anyway. Assume this is a
+         * forced SIGSEGV (ie one the kernel handles via force_sig_info because
+         * it got a real MMU fault). A blocked SIGSEGV in that situation is
+         * treated as if using the default handler. This is not correct if some
+         * other process has randomly sent us a SIGSEGV via kill(), but that is
+         * not easy to distinguish at this point, so we assume it doesn't
+         * happen.
+         */
+        force_sig(sig);
+    }
+
+    pq = &k->first;
+
+    /*
+     * FreeBSD signals are always queued.  Linux only queues real time signals.
+     * XXX this code is not thread safe.  "What lock protects ts->sigtab?"
+     */
+    if (!k->pending) {
+        /* first signal */
+        q = &k->info;
+    } else {
+        q = alloc_sigqueue(env);
+        if (!q) {
+            return; /* XXX WHAT TO DO */
+        }
+        while (*pq != NULL) {
+            pq = &(*pq)->next;
+        }
+    }
+    *pq = q;
+    q->info = *info;
+    q->next = NULL;
+    k->pending = 1;
+    /* Signal that a new signal is pending. */
+    ts->signal_pending = 1;
+    return;
 }
 
 static int fatal_signal(int sig)
-- 
2.33.1



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

* [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines.
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (21 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 11:13   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 24/30] bsd-user/signal.c: setup_frame Warner Losh
                   ` (6 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, Warner Losh

target_sigemptyset: resets a set to having no bits set
qemu_sigorset:      computes the or of two sets
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/qemu.h   |  3 ++
 bsd-user/signal.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index e12617f5d69..e8c417c7c33 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -223,7 +223,10 @@ 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);
 int target_to_host_signal(int sig);
 int host_to_target_signal(int sig);
+void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
+void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
 void QEMU_NORETURN force_sig(int target_sig);
+int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
 
 /* mmap.c */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 93c3b3c5033..8dadc9a39a7 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);
+
 
 int host_to_target_signal(int sig)
 {
@@ -43,6 +46,44 @@ int target_to_host_signal(int sig)
     return sig;
 }
 
+static inline void target_sigemptyset(target_sigset_t *set)
+{
+    memset(set, 0, sizeof(*set));
+}
+
+#include <signal.h>
+
+int
+qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
+{
+    sigset_t work;
+    int i;
+
+    sigemptyset(&work);
+    for (i = 1; i < NSIG; ++i) {
+        if (sigismember(left, i) || sigismember(right, i)) {
+            sigaddset(&work, i);
+        }
+    }
+
+    *dest = work;
+    return 0;
+}
+
+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)
 {
@@ -55,6 +96,54 @@ static inline void rewind_if_in_safe_syscall(void *puc)
     }
 }
 
+static void host_to_target_sigset_internal(target_sigset_t *d,
+        const sigset_t *s)
+{
+    int i;
+
+    target_sigemptyset(d);
+    for (i = 1; i <= TARGET_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 < TARGET_NSIG_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);
+}
+
 /* Siginfo conversion. */
 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
         const siginfo_t *info)
-- 
2.33.1



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

* [PATCH 24/30] bsd-user/signal.c: setup_frame
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (22 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 11:40   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 25/30] bsd-user/signal.c: handle_pending_signal Warner Losh
                   ` (5 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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/signal.c | 166 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 144 insertions(+), 22 deletions(-)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 8dadc9a39a7..8e1427553da 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -30,11 +30,27 @@
  * fork.
  */
 
+static target_stack_t target_sigaltstack_used = {
+    .ss_sp = 0,
+    .ss_size = 0,
+    .ss_flags = TARGET_SS_DISABLE,
+};
+
 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);
 
+static inline int on_sig_stack(unsigned long sp)
+{
+    return sp - target_sigaltstack_used.ss_sp < target_sigaltstack_used.ss_size;
+}
+
+static inline int sas_ss_flags(unsigned long sp)
+{
+    return target_sigaltstack_used.ss_size == 0 ? SS_DISABLE : on_sig_stack(sp)
+        ? SS_ONSTACK : 0;
+}
 
 int host_to_target_signal(int sig)
 {
@@ -336,28 +352,6 @@ void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
     return;
 }
 
-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().
@@ -484,6 +478,134 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
     cpu_exit(thread_cpu);
 }
 
+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;
+    }
+}
+
+static inline abi_ulong get_sigframe(struct target_sigaction *ka,
+        CPUArchState *regs, size_t frame_size)
+{
+    abi_ulong sp;
+
+    /* Use default user stack */
+    sp = get_sp_from_cpustate(regs);
+
+    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
+        sp = target_sigaltstack_used.ss_sp +
+            target_sigaltstack_used.ss_size;
+    }
+
+#if defined(TARGET_MIPS) || 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 mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c sendsig() */
+static void setup_frame(int sig, int code, struct target_sigaction *ka,
+    target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *regs)
+{
+    struct target_sigframe *frame;
+    abi_ulong frame_addr;
+    int i;
+
+    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
+    trace_user_setup_frame(regs, frame_addr);
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+        goto give_sigsegv;
+    }
+
+    memset(frame, 0, sizeof(*frame));
+#if defined(TARGET_MIPS)
+    int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC :
+        TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC;
+#else
+    int mflags = 0;
+#endif
+    if (get_mcontext(regs, &frame->sf_uc.uc_mcontext, mflags)) {
+        goto give_sigsegv;
+    }
+
+    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+        if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i])) {
+            goto give_sigsegv;
+        }
+    }
+
+    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;
+
+        if (TARGET_SIGILL == sig || TARGET_SIGFPE == sig ||
+                TARGET_SIGSEGV == sig || TARGET_SIGBUS == sig ||
+                TARGET_SIGTRAP == sig) {
+            frame->sf_si._reason._fault._trapno = tinfo->_reason._fault._trapno;
+        }
+
+        /*
+         * If si_code is one of SI_QUEUE, SI_TIMER, SI_ASYNCIO, or
+         * SI_MESGQ, then si_value contains the application-specified
+         * signal value. Otherwise, the contents of si_value are
+         * undefined.
+         */
+        if (SI_QUEUE == code || SI_TIMER == code || SI_ASYNCIO == code ||
+                SI_MESGQ == code) {
+            frame->sf_si.si_value.sival_int = tinfo->si_value.sival_int;
+        }
+
+        if (SI_TIMER == code) {
+            frame->sf_si._reason._timer._timerid =
+                tinfo->_reason._timer._timerid;
+            frame->sf_si._reason._timer._overrun =
+                tinfo->_reason._timer._overrun;
+        }
+
+#ifdef SIGPOLL
+        if (SIGPOLL == sig) {
+            frame->sf_si._reason._band = tinfo->_reason._band;
+        }
+#endif
+
+    }
+
+    if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) {
+        goto give_sigsegv;
+    }
+
+    unlock_user_struct(frame, frame_addr, 1);
+    return;
+
+give_sigsegv:
+    unlock_user_struct(frame, frame_addr, 1);
+    force_sig(TARGET_SIGSEGV);
+}
+
 void signal_init(void)
 {
     TaskState *ts = (TaskState *)thread_cpu->opaque;
-- 
2.33.1



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

* [PATCH 25/30] bsd-user/signal.c: handle_pending_signal
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (23 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 24/30] bsd-user/signal.c: setup_frame Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 11:50   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 26/30] bsd-user/signal.c: tswap_siginfo Warner Losh
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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   |  2 +
 bsd-user/signal.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index e8c417c7c33..011fdfebbaa 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -97,7 +97,9 @@ typedef struct TaskState {
     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 */
+    bool in_sigsuspend;
     sigset_t signal_mask;
+    sigset_t sigsuspend_mask;
 
     uint8_t stack[];
 } __attribute__((aligned(16))) TaskState;
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 8e1427553da..934528d5fb0 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -649,6 +649,102 @@ void signal_init(void)
     }
 }
 
+static void handle_pending_signal(CPUArchState *cpu_env, int sig,
+                                  struct emulated_sigtable *k)
+{
+    CPUState *cpu = env_cpu(cpu_env);
+    TaskState *ts = cpu->opaque;
+    struct qemu_sigqueue *q;
+    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(cpu_env, sig);
+
+    /* Dequeue signal. */
+    q = k->first;
+    k->first = q->next;
+    if (!k->first) {
+        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, &q->info);
+    }
+
+    if (handler == TARGET_SIG_DFL) {
+        /*
+         * default handler : ignore some signal. The other are job
+         * control or fatal.
+         */
+        if (TARGET_SIGTSTP == sig || TARGET_SIGTTIN == sig ||
+                TARGET_SIGTTOU == sig) {
+            kill(getpid(), SIGSTOP);
+        } else if (TARGET_SIGCHLD != sig && TARGET_SIGURG != sig &&
+            TARGET_SIGINFO != sig &&
+            TARGET_SIGWINCH != sig && TARGET_SIGCONT != sig) {
+            force_sig(sig);
+        }
+    } else if (TARGET_SIG_IGN == handler) {
+        /* ignore sig */
+    } else if (TARGET_SIG_ERR == handler) {
+        force_sig(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;
+        qemu_sigorset(&ts->signal_mask, blocked_set, &set);
+        ts->in_sigsuspend = false;
+        sigprocmask(SIG_SETMASK, &ts->signal_mask, NULL);
+
+        /* XXX VM86 on x86 ??? */
+
+        code = q->info.si_code;
+        /* prepare the stack frame of the virtual CPU */
+        if (sa->sa_flags & TARGET_SA_SIGINFO) {
+            tswap_siginfo(&tinfo, &q->info);
+            setup_frame(sig, code, sa, &target_old_set, &tinfo, cpu_env);
+        } else {
+            setup_frame(sig, code, sa, &target_old_set, NULL, cpu_env);
+        }
+        if (sa->sa_flags & TARGET_SA_RESETHAND) {
+            sa->_sa_handler = TARGET_SIG_DFL;
+        }
+    }
+    if (q != &k->info) {
+        free_sigqueue(cpu_env, q);
+    }
+}
+
 void process_pending_signals(CPUArchState *cpu_env)
 {
 }
-- 
2.33.1



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

* [PATCH 26/30] bsd-user/signal.c: tswap_siginfo
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (24 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 25/30] bsd-user/signal.c: handle_pending_signal Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 11:54   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 27/30] bsd-user/signal.c: process_pending_signals Warner Losh
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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 | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 934528d5fb0..c954d0f4f37 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -197,6 +197,40 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
     }
 }
 
+static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
+{
+    int sig, code;
+
+    sig = info->si_signo;
+    code = info->si_code;
+    tinfo->si_signo = tswap32(sig);
+    tinfo->si_errno = tswap32(info->si_errno);
+    tinfo->si_code = tswap32(info->si_code);
+    tinfo->si_pid = tswap32(info->si_pid);
+    tinfo->si_uid = tswap32(info->si_uid);
+    tinfo->si_status = tswap32(info->si_status);
+    tinfo->si_addr = tswapal(info->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;
+    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig ||
+            SIGTRAP == sig) {
+        tinfo->_reason._fault._trapno = tswap32(info->_reason._fault._trapno);
+    }
+#ifdef SIGPOLL
+    if (SIGPOLL == sig) {
+        tinfo->_reason._poll._band = tswap32(info->_reason._poll._band);
+    }
+#endif
+    if (SI_TIMER == code) {
+        tinfo->_reason._timer._timerid = tswap32(info->_reason._timer._timerid);
+        tinfo->_reason._timer._overrun = tswap32(info->_reason._timer._overrun);
+    }
+}
+
 /* 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] 105+ messages in thread

* [PATCH 27/30] bsd-user/signal.c: process_pending_signals
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (25 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 26/30] bsd-user/signal.c: tswap_siginfo Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 11:55   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn Warner Losh
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, 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 | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index c954d0f4f37..1dd6dbb4ee1 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -781,6 +781,40 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
 
 void process_pending_signals(CPUArchState *cpu_env)
 {
+    CPUState *cpu = env_cpu(cpu_env);
+    int sig;
+    sigset_t *blocked_set, set;
+    struct emulated_sigtable *k;
+    TaskState *ts = cpu->opaque;
+
+    while (qatomic_read(&ts->signal_pending)) {
+        /* FIXME: This is not threadsafe. */
+
+        sigfillset(&set);
+        sigprocmask(SIG_SETMASK, &set, 0);
+
+        k = ts->sigtab;
+        blocked_set = ts->in_sigsuspend ?
+            &ts->sigsuspend_mask : &ts->signal_mask;
+        for (sig = 1; sig <= TARGET_NSIG; sig++, k++) {
+            if (k->pending &&
+                !sigismember(blocked_set, target_to_host_signal(sig))) {
+                handle_pending_signal(cpu_env, sig, k);
+            }
+        }
+
+        /*
+         * 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] 105+ messages in thread

* [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (26 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 27/30] bsd-user/signal.c: process_pending_signals Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 12:12   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 29/30] bsd-user/signal.c: implement do_sigaction Warner Losh
  2022-01-09 16:19 ` [PATCH 30/30] bsd-user/signal.c: do_sigaltstack Warner Losh
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, Warner Losh

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

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/qemu.h   |  3 +--
 bsd-user/signal.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 011fdfebbaa..b8c64ca0e5b 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -219,14 +219,13 @@ 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);
 int target_to_host_signal(int sig);
 int host_to_target_signal(int sig);
 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
+long do_sigreturn(CPUArchState *regs, abi_ulong addr);
 void QEMU_NORETURN force_sig(int target_sig);
 int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
 
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 1dd6dbb4ee1..d11f5eddd7e 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -640,6 +640,62 @@ give_sigsegv:
     force_sig(TARGET_SIGSEGV);
 }
 
+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;
+}
+
+long do_sigreturn(CPUArchState *regs, 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(regs, addr, &target_ucontext);
+    if (is_error(ret)) {
+        return ret;
+    }
+    trace_user_do_sigreturn(regs, 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(regs, &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);
+    }
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_EFAULT;
+}
+
 void signal_init(void)
 {
     TaskState *ts = (TaskState *)thread_cpu->opaque;
-- 
2.33.1



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

* [PATCH 29/30] bsd-user/signal.c: implement do_sigaction
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (27 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 13:13   ` Peter Maydell
  2022-01-09 16:19 ` [PATCH 30/30] bsd-user/signal.c: do_sigaltstack Warner Losh
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, Warner Losh

Implement the meat of the sigaction(2) system call with do_sigaction and
helper routiner block_signals (which is also used to implemement signal
masking so it's global).

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/qemu.h   | 21 +++++++++++++
 bsd-user/signal.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index b8c64ca0e5b..c643d6ba246 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -226,8 +226,29 @@ int host_to_target_signal(int sig);
 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
 long do_sigreturn(CPUArchState *regs, abi_ulong addr);
+int do_sigaction(int sig, const struct target_sigaction *act,
+                struct target_sigaction *oact);
 void QEMU_NORETURN force_sig(int target_sig);
 int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
+/**
+ * block_signals: block all signals while handling this guest syscall
+ *
+ * Block all signals, and arrange that the signal mask is returned to
+ * its correct value for the guest before we resume execution of guest code.
+ * If this function returns non-zero, then the caller should immediately
+ * return -TARGET_ERESTARTSYS to the main loop, which will take the pending
+ * signal and restart execution of the syscall.
+ * If block_signals() returns zero, then the caller can continue with
+ * emulation of the system call knowing that no signals can be taken
+ * (and therefore that no race conditions will result).
+ * This should only be called once, because if it is called a second time
+ * it will always return non-zero. (Think of it like a mutex that can't
+ * be recursively locked.)
+ * Signals will be unblocked again by process_pending_signals().
+ *
+ * Return value: non-zero if there was a pending signal, zero if not.
+ */
+int block_signals(void); /* Returns non zero if signal pending */
 
 /* mmap.c */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index d11f5eddd7e..f055d1db407 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -231,6 +231,22 @@ static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
     }
 }
 
+int block_signals(void)
+{
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+    sigset_t set;
+
+    /*
+     * It's OK to block everything including SIGSEGV, because we won't run any
+     * further guest code before unblocking signals in
+     * process_pending_signals().
+     */
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, 0);
+
+    return qatomic_xchg(&ts->signal_pending, 1);
+}
+
 /* Returns 1 if given signal should dump core if not handled. */
 static int core_dump_signal(int sig)
 {
@@ -534,6 +550,66 @@ static int fatal_signal(int sig)
     }
 }
 
+/* do_sigaction() return host values and errnos */
+int do_sigaction(int sig, const struct target_sigaction *act,
+        struct target_sigaction *oact)
+{
+    struct target_sigaction *k;
+    struct sigaction act1;
+    int host_sig;
+    int ret = 0;
+
+    if (sig < 1 || sig > TARGET_NSIG || TARGET_SIGKILL == sig ||
+            TARGET_SIGSTOP == sig) {
+        return -EINVAL;
+    }
+
+    if (block_signals()) {
+        return -TARGET_ERESTART;
+    }
+
+    k = &sigact_table[sig - 1];
+    if (oact) {
+        oact->_sa_handler = tswapal(k->_sa_handler);
+        oact->sa_flags = tswap32(k->sa_flags);
+        oact->sa_mask = k->sa_mask;
+    }
+    if (act) {
+        /* XXX: this is most likely not threadsafe. */
+        k->_sa_handler = tswapal(act->_sa_handler);
+        k->sa_flags = tswap32(act->sa_flags);
+        k->sa_mask = act->sa_mask;
+
+        /* Update the host signal state. */
+        host_sig = target_to_host_signal(sig);
+        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
+            memset(&act1, 0, sizeof(struct sigaction));
+            sigfillset(&act1.sa_mask);
+            act1.sa_flags = SA_SIGINFO;
+            if (k->sa_flags & TARGET_SA_RESTART) {
+                act1.sa_flags |= SA_RESTART;
+            }
+            /*
+             *  Note: It is important to update the host kernel signal mask to
+             *  avoid getting unexpected interrupted system calls.
+             */
+            if (k->_sa_handler == TARGET_SIG_IGN) {
+                act1.sa_sigaction = (void *)SIG_IGN;
+            } else if (k->_sa_handler == TARGET_SIG_DFL) {
+                if (fatal_signal(sig)) {
+                    act1.sa_sigaction = host_signal_handler;
+                } else {
+                    act1.sa_sigaction = (void *)SIG_DFL;
+                }
+            } else {
+                act1.sa_sigaction = host_signal_handler;
+            }
+            ret = sigaction(host_sig, &act1, NULL);
+        }
+    }
+    return ret;
+}
+
 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
         CPUArchState *regs, size_t frame_size)
 {
-- 
2.33.1



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

* [PATCH 30/30] bsd-user/signal.c: do_sigaltstack
  2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
                   ` (28 preceding siblings ...)
  2022-01-09 16:19 ` [PATCH 29/30] bsd-user/signal.c: implement do_sigaction Warner Losh
@ 2022-01-09 16:19 ` Warner Losh
  2022-01-14 13:18   ` Peter Maydell
  29 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-09 16:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kyle Evans, Stacey Son, Warner Losh

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

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 | 66 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index c643d6ba246..fcdea460ed2 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -226,6 +226,7 @@ int host_to_target_signal(int sig);
 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
 long do_sigreturn(CPUArchState *regs, abi_ulong addr);
+abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
 int do_sigaction(int sig, const struct target_sigaction *act,
                 struct target_sigaction *oact);
 void QEMU_NORETURN force_sig(int target_sig);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index f055d1db407..e5e5e28c60c 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -528,6 +528,72 @@ 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)
+{
+    int ret;
+    target_stack_t oss;
+
+    if (uoss_addr) {
+        /* Save current signal stack params */
+        oss.ss_sp = tswapl(target_sigaltstack_used.ss_sp);
+        oss.ss_size = tswapl(target_sigaltstack_used.ss_size);
+        oss.ss_flags = tswapl(sas_ss_flags(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(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;
+            }
+        }
+
+        target_sigaltstack_used.ss_sp = ss.ss_sp;
+        target_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;
+}
+
 static int fatal_signal(int sig)
 {
 
-- 
2.33.1



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

* Re: [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user
  2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
@ 2022-01-13 15:47   ` Peter Maydell
  2022-01-23 21:30   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 15:47 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:23, Warner Losh <imp@bsdimp.com> wrote:
>
> Move the EXCP_ATOMIC case to match linux-user/arm/cpu_loop.c:cpu_loop
> ordering.
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  bsd-user/arm/target_arch_cpu.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault
  2022-01-09 16:18 ` [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault Warner Losh
@ 2022-01-13 16:43   ` Peter Maydell
  2022-01-23 21:36   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 16:43 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:23, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

> +/*
> + * 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);
> +}

In the linux-user implementation of this function, we pass in an extra
argument to queue_signal(), which is a QEMU_SI_* value (in this case
QEMU_SI_FAULT). The reason we do this is that the siginfo_t struct,
at least on Linux, is a pain: it has a union, and which field of the
union is the valid one is awkward to determine. Within the real
Linux kernel, the high bits of si_code are used to track what field
of the union is live, but those are masked out before handing the
signal to userspace. The effect is that QEMU sometimes has to
deal with siginfo_t structures where it knows exactly which field
of the union is valid because it generated the structure itself,
and sometimes with ones it got from guest userspace where it
has to make a best-guess. linux-user code deals with that using
the QEMU_SI_* codes: when we generate a siginfo_t ourselves and
know what field of the union is valid, we put the QEMU_SI_* into
the top part of si_code, and later when we need to byteswap it
for the guest we use tswap_siginfo(), which uses that to make a
known-correct choice. When we have to byteswap a siginfo_t which
we got from guest userspace, we use host_to_target_siginfo_noswap(),
which makes a best-guess based on things like the signal number.
And when we hand a siginfo_t to guest userspace, we mask out the
top part of si_code again, like the real kernel.

I'm not sure how the BSDs handle this, but at the moment in
this patchset you add both a host_to_target_siginfo_noswap()
(patch 16) and a tswap_siginfo(), but you've given them both
the guess-which-union-field-is-valid logic.

You don't need to address this in this patch series, but I wanted
to lay out the logic of why linux-user is doing things the
way it does so you can determine whether bsd-user needs to do
the same or not. (That might depend on which BSD: judging by
the target_siginfo definitions in bsd_user, freebsd puts
si_pid/si_uid in top-level struct fields, but netbsd and
openbsd put them in sub-fields of the union the same way
Linux does. For eg a SIGSEGV sent via kill() you want to swap
the pid/uid fields, but for a SIGSEGV generated by QEMU
you want to swap the si_addr. The other thing to check is
to what extent the BSD kernel ABI lets userspace spoof the
si_code field in a siginfo_t: Linux's rt_sigqueueinfo syscall
is quite lax in this regard.)

Anyway, for this patch:
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv
  2022-01-09 16:18 ` [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
@ 2022-01-13 17:00   ` Peter Maydell
  2022-01-23 21:38   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:00 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:23, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

thanks
-- PMM


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

* Re: [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus
  2022-01-09 16:18 ` [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
@ 2022-01-13 17:00   ` Peter Maydell
  2022-01-23 21:38   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:00 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

thanks
-- PMM


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

* Re: [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  2022-01-09 16:18 ` [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
@ 2022-01-13 17:13   ` Peter Maydell
  2022-01-14  6:33     ` Warner Losh
  2022-01-23 21:40   ` Richard Henderson
  1 sibling, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:13 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
>
> 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).
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  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;
> -                    }
> -                }

So the previous code was implementing BKPT as a way to do
a syscall (added in commit 8d450c9a30). Was that just a mistake ?

>                  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 */

Looks like it now matches the freebsd kernel behaviour, anyway.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-09 16:18 ` [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
@ 2022-01-13 17:15   ` Peter Maydell
  2022-01-14  6:38     ` Warner Losh
  2022-01-23 21:43   ` Richard Henderson
  1 sibling, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:15 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
>
> The code has moved in FreeBSD since the emulator was started, update the
> comment to reflect that change. Remove now-redundant comment saying the
> same thing (but incorrectly).
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  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];

Commit message says we're updating one comment and deleting a
second one; code only does an update, no delete ?

-- PMM


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

* Re: [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-09 16:19 ` [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
@ 2022-01-13 17:19   ` Peter Maydell
  2022-01-23 22:07     ` Richard Henderson
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:19 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:27, Warner Losh <imp@bsdimp.com> wrote:
>
> 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.
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  bsd-user/arm/target_arch_cpu.h | 18 ++++++------------
>  1 file changed, 6 insertions(+), 12 deletions(-)
>
> diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
> index 905f13aa1b9..996a361e3fe 100644
> --- a/bsd-user/arm/target_arch_cpu.h
> +++ b/bsd-user/arm/target_arch_cpu.h
> @@ -51,18 +51,12 @@ 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();
> +             */
> +            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->regs[15]);
>              break;

Do you want to keep the TODO comment ?

Either way,
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

(Looks like FreeBSD sends SIGILL/ILL_ILLADR for UNDEF where the PC
is misaligned and we're not in Thumb mode, but that's a pretty oddball
corner case so not really worth emulating.)

thanks
-- PMM


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

* Re: [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-09 16:19 ` [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
@ 2022-01-13 17:40   ` Peter Maydell
  2022-01-14 18:13     ` Warner Losh
  2022-01-24  1:12   ` Richard Henderson
  1 sibling, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:40 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
>
> Update for the richer set of data faults that are now possible. Copied
> largely from linux-user/arm/cpu_loop.c
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  bsd-user/arm/target_arch_cpu.h | 44 ++++++++++++++++++++++++++--------
>  1 file changed, 34 insertions(+), 10 deletions(-)
>
> diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
> index 996a361e3fe..51e592bcfe7 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);
>
> @@ -143,15 +142,40 @@ 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: /* Permision fault, level 1 */
> +            case 0xf: /* Permision fault, level 2 */

"Permission" (I see we have this typo in linux-user).

> +                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();
> +            }

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation
  2022-01-09 16:19 ` [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
@ 2022-01-13 17:44   ` Peter Maydell
  2022-01-14 18:27     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 17:44 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> 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>
> ---
>  bsd-user/qemu.h   |  2 ++
>  bsd-user/signal.c | 11 +++++++++++
>  2 files changed, 13 insertions(+)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 1b3b974afe9..334f8b1d715 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -210,6 +210,8 @@ 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);
> +int target_to_host_signal(int sig);
> +int host_to_target_signal(int sig);
>
>  /* mmap.c */
>  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 844dfa19095..7ea86149981 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,16 @@
>   * fork.
>   */
>
> +int host_to_target_signal(int sig)
> +{
> +    return sig;
> +}
> +
> +int target_to_host_signal(int sig)
> +{
> +    return sig;
> +}
> +

This could use a comment:

/*
 * For the BSDs signal numbers are always the same regardless of
 * CPU architecture, so (unlike Linux) these functions are just
 * the identity mapping.
 */

(assuming that is correct, of course!)

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 10/30] bsd-user/signal.c: Implement signal_init()
  2022-01-09 16:19 ` [PATCH 10/30] bsd-user/signal.c: Implement signal_init() Warner Losh
@ 2022-01-13 19:28   ` Peter Maydell
  2022-01-14 18:51     ` Warner Losh
  2022-01-24  1:38   ` Richard Henderson
  1 sibling, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:28 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>
> ---
>  bsd-user/qemu.h   |  1 +
>  bsd-user/signal.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+)

> +static struct target_sigaction sigact_table[TARGET_NSIG];




>  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);
> +
> +    /*
> +     * Set all host signal handlers. ALL signals are blocked during the
> +     * handlers to serialize them.
> +     */
> +    memset(sigact_table, 0, sizeof(sigact_table));

Do you need this memset()? sigact_table is a global, so it's
zero-initialized on startup, and this function is only called once.
The (otherwise basically identical) Linux version of this function
doesn't have it.

> +
> +    sigfillset(&act.sa_mask);
> +    act.sa_sigaction = host_signal_handler;
> +    act.sa_flags = SA_SIGINFO;
> +
> +    for (i = 1; i <= TARGET_NSIG; i++) {
> +        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);
> +        }
> +    }
>  }

Otherwise

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_*
  2022-01-09 16:19 ` [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
@ 2022-01-13 19:32   ` Peter Maydell
  2022-01-17  3:53     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:32 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:33, Warner Losh <imp@bsdimp.com> 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>

> +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 which we don't have access to here.  We assume that uc
> +     * is part of a trapframe and reach around to get to the si_info that's in
> +     * the sigframe just before it, though this may be unwise.
> +     */

Yeah, that's pretty nasty. But this function is passed a
siginfo_t pointer -- isn't that the one you need ?

> +    siginfo_t *si;
> +    si = &((siginfo_t *)uc)[-1];
> +    uint32_t fsr = si->si_trapno;
> +
> +    return extract32(fsr, 11, 1);
> +}

thanks
-- PMM


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

* Re: [PATCH 12/30] bsd-user/host/i386/host-signal.h: Implement host_signal_*
  2022-01-09 16:19 ` [PATCH 12/30] bsd-user/host/i386/host-signal.h: " Warner Losh
@ 2022-01-13 19:33   ` Peter Maydell
  2022-01-24  1:49   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:33 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

thanks
-- PMM


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

* Re: [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
  2022-01-09 16:19 ` [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: " Warner Losh
@ 2022-01-13 19:33   ` Peter Maydell
  2022-01-24  1:52   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:33 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:37, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

thanks
-- PMM


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

* Re: [PATCH 14/30] bsd-user: Add host signals to the build
  2022-01-09 16:19 ` [PATCH 14/30] bsd-user: Add host signals to the build Warner Losh
@ 2022-01-13 19:35   ` Peter Maydell
  2022-01-24  1:56   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:35 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:32, Warner Losh <imp@bsdimp.com> wrote:
>
> Start to add the host signal functionality to the build.
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  bsd-user/meson.build | 1 +
>  bsd-user/signal.c    | 1 +
>  meson.build          | 1 +
>  3 files changed, 3 insertions(+)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 15/30] bsd-user: Add trace events for bsd-usr
  2022-01-09 16:19 ` [PATCH 15/30] bsd-user: Add trace events for bsd-usr Warner Losh
@ 2022-01-13 19:37   ` Peter Maydell
  2022-01-24  1:57   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:37 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:36, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

Typo in subject: should be 'bsd-user', not 'bsd-usr'.
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-09 16:19 ` [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
@ 2022-01-13 19:43   ` Peter Maydell
  2022-01-15  6:19     ` Warner Losh
  2022-01-24  2:05   ` Richard Henderson
  1 sibling, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:43 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:41, Warner Losh <imp@bsdimp.com> 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 | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 7168d851be8..3fe8b2d9898 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -43,6 +43,43 @@ int target_to_host_signal(int sig)
>      return sig;
>  }
>
> +/* Siginfo conversion. */
> +static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
> +        const siginfo_t *info)
> +{
> +    int sig, code;
> +
> +    sig = host_to_target_signal(info->si_signo);
> +    /* XXX should have host_to_target_si_code() */
> +    code = tswap32(info->si_code);
> +    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 */
> +    tinfo->si_value.sival_ptr =
> +        (abi_ulong)(unsigned long)info->si_value.sival_ptr;
> +    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig ||

Don't use yoda-conditions, please. sig == SIGILL, etc.

> +            SIGTRAP == sig) {
> +        tinfo->_reason._fault._trapno = info->_reason._fault._trapno;
> +    }
> +#ifdef SIGPOLL
> +    if (SIGPOLL == sig) {
> +        tinfo->_reason._poll._band = info->_reason._poll._band;
> +    }
> +#endif
> +    if (SI_TIMER == code) {
> +        int timerid;
> +
> +        timerid = info->_reason._timer._timerid;
> +        tinfo->_reason._timer._timerid = timerid;
> +        tinfo->_reason._timer._overrun = info->_reason._timer._overrun;
> +    }
> +}

I think this will only compile on FreeBSD (the other BSDs having
notably different target_siginfo_t structs); I guess we're OK
with that ?

I also commented on the general setup linux-user has for this
function back in patch 2; I'll let you figure out whether what
you have here is the right thing for BSD.

-- PMM


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

* Re: [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall
  2022-01-09 16:19 ` [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
@ 2022-01-13 19:44   ` Peter Maydell
  2022-01-24  2:09   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 19:44 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, qemu-devel

On Sun, 9 Jan 2022 at 16:32, Warner Losh <imp@bsdimp.com> wrote:
>
> Signed-off-by: Kyle Evans <kevans@freebsd.org>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  bsd-user/qemu.h   |  2 ++
>  bsd-user/signal.c | 12 ++++++++++++
>  2 files changed, 14 insertions(+)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler
  2022-01-09 16:19 ` [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler Warner Losh
@ 2022-01-13 20:17   ` Peter Maydell
  2022-01-16 20:52     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:17 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:40, Warner Losh <imp@bsdimp.com> 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(+)
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index b1331f63d61..a6e07277fb2 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -142,6 +142,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)
>  {
> +    CPUState *cpu = thread_cpu;
> +    CPUArchState *env = cpu->env_ptr;
> +    int sig;
> +    target_siginfo_t tinfo;
> +    ucontext_t *uc = puc;
> +    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. */
> +    sig = host_to_target_signal(host_sig);
> +    if (sig < 1 || sig > TARGET_NSIG) {
> +        return;
> +    }
> +    trace_user_host_signal(cpu, host_sig, sig);
> +
> +    host_to_target_siginfo_noswap(&tinfo, info);
> +
> +    queue_signal(env, sig, &tinfo);       /* XXX how to cope with failure? */

queue_signal() can't fail, so there is nothing to cope with.
(Your bsd-user version even has the right 'void' type --
linux-user's returns 1 always and we never look at the return
value, so we should really switch that to void return too.)

> +    /*
> +     * Linux does something else here -> the queue signal may be wrong, but
> +     * maybe not.  And then it does the rewind_if_in_safe_syscall
> +     */

I think you have here a bit of a mix of linux-user's current design
and some older (broken) version. This is how linux-user works today:

 * queue_signal() is a little bit misnamed, because there is no
   "queue" here: there can only be at most one "queued" signal,
   and it lives in the TaskState struct (which is user-only specific
   information that hangs off the guest CPU struct) as the
   TaskState::sync_signal field. The reason
   we only have one at once is that queue_signal() is used only
   for signals generated by QEMU itself by calling queue_signal()
   directly or indirectly from the cpu_loop() code. The cpu loop
   always calls process_pending_signals() at the end of its loop,
   which will pick up a queued signal. We never call queue_signal()
   twice in a row before getting back to process_pending_signals(),
   so there's only ever at most one thing in the "queue".
 * for all signals we get from the host except SIGSEGV/SIGBUS,
   we track whether there's a host signal pending in the
   TaskState::sigtab[] array (which is indexed by signal number).
   We block all host signals except SIGSEGV/SIGBUS before calling
   cpu_exit(), so we know we're not going to get more than one
   of these at once (and it won't clash with a queue_signal()
   signal either, as those use the sync_signal field, not the
   sigtab[]).
 * for host-sent non-spoofed (ie not sent via 'kill()') SIGSEGV/SIGBUS,
   we know this was caused by a bit of generated code, so we just
   use cpu_loop_exit_restore() to turn this into an EXCP_INTERRUPT
   at the right guest PC

I feel fairly strongly that you definitely want to use the same
design as current linux-user does for signals:
 * getting this right is pretty tricky, and even if we get two
   different designs to both have the same semantics it's going
   to be pretty confusing
 * we thought quite hard about the linux-user code at the time
   and it's definitely less buggy than the previous design
 * It's much easier to review the bsd-user code as "yes this is
   doing the same thing linux-user does" than working through
   a different approach from first principles

I don't have as strong an opinion on whether we should try to get
it into the tree that way from the start, or to put in whatever
you have currently and then fix it later. (More accurately,
I would prefer to review patches which use the same design
as linux-user but if that's going to be massively painful/slow
for you to get something upstream doing it that way around
I can probably live with the other approach...)

> +    /*
> +     * 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.
> +     XXXX Should this be in queue_signal?

No, because queue_signal() is called for lots of ways to pend
a signal, most of which aren't real host signals.

> +     */
> +    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)

thanks
-- PMM


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

* Re: [PATCH 19/30] bsd-user/strace.c: print_taken_signal
  2022-01-09 16:19 ` [PATCH 19/30] bsd-user/strace.c: print_taken_signal Warner Losh
@ 2022-01-13 20:20   ` Peter Maydell
  2022-01-24  2:45   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:20 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:46, Warner Losh <imp@bsdimp.com> wrote:
>
> 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>

thanks
-- PMM


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

* Re: [PATCH 20/30] bsd-user/signal.c: core_dump_signal
  2022-01-09 16:19 ` [PATCH 20/30] bsd-user/signal.c: core_dump_signal Warner Losh
@ 2022-01-13 20:22   ` Peter Maydell
  2022-01-13 20:28     ` Warner Losh
  2022-01-24  3:01   ` Richard Henderson
  1 sibling, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:22 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:48, Warner Losh <imp@bsdimp.com> wrote:
>
> Returns 1 for signals that cause core files.
>
> 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 | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index a6e07277fb2..824535be8b8 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -92,6 +92,23 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
>      }
>  }
>
> +/* 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;
> +    }
> +}

Code is fine, but since this is a static function with no callers
the compiler is going to emit a warning about that. It's a small
function, so the easiest thing is just to squash this into the
following patch which is what adds the code that calls it.

thanks
-- PMM


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

* Re: [PATCH 20/30] bsd-user/signal.c: core_dump_signal
  2022-01-13 20:22   ` Peter Maydell
@ 2022-01-13 20:28     ` Warner Losh
  2022-01-13 20:40       ` Peter Maydell
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-13 20:28 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 1:22 PM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:48, Warner Losh <imp@bsdimp.com> wrote:
> >
> > Returns 1 for signals that cause core files.
> >
> > 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 | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> >
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index a6e07277fb2..824535be8b8 100644
> > --- a/bsd-user/signal.c
> > +++ b/bsd-user/signal.c
> > @@ -92,6 +92,23 @@ static inline void
> host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
> >      }
> >  }
> >
> > +/* 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;
> > +    }
> > +}
>
> Code is fine, but since this is a static function with no callers
> the compiler is going to emit a warning about that. It's a small
> function, so the easiest thing is just to squash this into the
> following patch which is what adds the code that calls it.
>

Sure thing. I'm still trying to get a feel for right-sizing the chunking...
Since the warning didn't fail the compile, I thought it would be OK,
but can easily fold this in with the first patch to use it.

Warner

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

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

* Re: [PATCH 21/30] bsd-user/signal.c: force_sig
  2022-01-09 16:19 ` [PATCH 21/30] bsd-user/signal.c: force_sig Warner Losh
@ 2022-01-13 20:29   ` Peter Maydell
  2022-01-13 20:53     ` Peter Maydell
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:29 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:44, Warner Losh <imp@bsdimp.com> wrote:
>
> Force delivering a signal and generating a core file.
>
> 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       | 59 +++++++++++++++++++++++++++++++++++++++++
>  bsd-user/syscall_defs.h |  1 +
>  3 files changed, 61 insertions(+)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 7c54a933eb8..e12617f5d69 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -223,6 +223,7 @@ 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);
>  int target_to_host_signal(int sig);
>  int host_to_target_signal(int sig);
> +void QEMU_NORETURN force_sig(int target_sig);
>
>  /* mmap.c */
>  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 824535be8b8..97f42f9c45e 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -109,6 +109,65 @@ static int core_dump_signal(int sig)
>      }
>  }
>
> +/* Abort execution with signal. */
> +void QEMU_NORETURN force_sig(int target_sig)

In linux-user we call this dump_core_and_abort(), which is
a name that better describes what it's actually doing.

(Today's linux-user's force_sig() does what the Linux kernel's
function of that name does -- it's a wrapper around
queue_signal() which delivers a signal to the guest with
.si_code = SI_KERNEL , si_pid = si_uid = 0.
Whether you want one of those or not depends on what BSD
kernels do in that kind of "we have to kill this process"
situation.)

> +{
> +    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"
>

-- PMM


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

* Re: [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal
  2022-01-09 16:19 ` [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal Warner Losh
@ 2022-01-13 20:37   ` Peter Maydell
  2022-01-17 16:22     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:37 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:51, Warner Losh <imp@bsdimp.com> wrote:
>
> Fill in queue signal implementation, as well as routines allocate and
> delete elements of the signal queue.

See reply to patch 18 for why you probably don't want to do this.

> Signed-off-by: Stacey Son <sson@FreeBSD.org>
> Signed-off-by: Kyle Evans <kevans@freebsd.org>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---


> +    /*
> +     * FreeBSD signals are always queued.  Linux only queues real time signals.
> +     * XXX this code is not thread safe.  "What lock protects ts->sigtab?"
> +     */

ts->sigtab shouldn't need a lock, because it is per-thread,
like all of TaskState. (The TaskState structure is pointed
to by the CPUState 'opaque' field. CPUStates are per-thread;
the TaskState for a new thread's new CPUState is allocated
and initialized as part of the emulating of whatever the
"create new thread" syscall is. For Linux this is in
do_fork() for the CLONE_VM case. The TaskState for the
initial thread is allocated in main.c.) We do need to deal
with the fact that ts->sigtab can be updated by a signal
handler (which always runs in the thread corresponding to
that guest CPU): the linux-user process_pending_signals()
has been written with that in mind.

thanks
-- PMM


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

* Re: [PATCH 20/30] bsd-user/signal.c: core_dump_signal
  2022-01-13 20:28     ` Warner Losh
@ 2022-01-13 20:40       ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:40 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, QEMU Developers

On Thu, 13 Jan 2022 at 20:28, Warner Losh <imp@bsdimp.com> wrote:
> On Thu, Jan 13, 2022 at 1:22 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>> Code is fine, but since this is a static function with no callers
>> the compiler is going to emit a warning about that. It's a small
>> function, so the easiest thing is just to squash this into the
>> following patch which is what adds the code that calls it.
>
>
> Sure thing. I'm still trying to get a feel for right-sizing the chunking...
> Since the warning didn't fail the compile, I thought it would be OK,
> but can easily fold this in with the first patch to use it.

Ah yes, we don't currently default-enable -Werror for BSD hosts
in configure (only for Linux and for mingw32). So in this particular
case it doesn't matter much, but we might as well do it the way we would
for code that's not BSD-specific.

thanks
-- PMM


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

* Re: [PATCH 21/30] bsd-user/signal.c: force_sig
  2022-01-13 20:29   ` Peter Maydell
@ 2022-01-13 20:53     ` Peter Maydell
  2022-01-13 23:04       ` Kyle Evans
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-13 20:53 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Thu, 13 Jan 2022 at 20:29, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Sun, 9 Jan 2022 at 16:44, Warner Losh <imp@bsdimp.com> wrote:
> >
> > Force delivering a signal and generating a core file.

> > +/* Abort execution with signal. */
> > +void QEMU_NORETURN force_sig(int target_sig)
>
> In linux-user we call this dump_core_and_abort(), which is
> a name that better describes what it's actually doing.
>
> (Today's linux-user's force_sig() does what the Linux kernel's
> function of that name does -- it's a wrapper around
> queue_signal() which delivers a signal to the guest with
> .si_code = SI_KERNEL , si_pid = si_uid = 0.
> Whether you want one of those or not depends on what BSD
> kernels do in that kind of "we have to kill this process"
> situation.)

It looks like the FreeBSD kernel uses sigexit() as its equivalent
function to Linux's force_sig(), incidentally. Not sure if
you/we would prefer the bsd-user code to follow the naming that
FreeBSD's kernel uses or the naming linux-user takes from
the Linux kernel.

-- PMM


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

* Re: [PATCH 21/30] bsd-user/signal.c: force_sig
  2022-01-13 20:53     ` Peter Maydell
@ 2022-01-13 23:04       ` Kyle Evans
  2022-01-18 22:27         ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Kyle Evans @ 2022-01-13 23:04 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Stacey Son, QEMU Developers, Warner Losh

On Thu, Jan 13, 2022 at 2:53 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Thu, 13 Jan 2022 at 20:29, Peter Maydell <peter.maydell@linaro.org> wrote:
> >
> > On Sun, 9 Jan 2022 at 16:44, Warner Losh <imp@bsdimp.com> wrote:
> > >
> > > Force delivering a signal and generating a core file.
>
> > > +/* Abort execution with signal. */
> > > +void QEMU_NORETURN force_sig(int target_sig)
> >
> > In linux-user we call this dump_core_and_abort(), which is
> > a name that better describes what it's actually doing.
> >
> > (Today's linux-user's force_sig() does what the Linux kernel's
> > function of that name does -- it's a wrapper around
> > queue_signal() which delivers a signal to the guest with
> > .si_code = SI_KERNEL , si_pid = si_uid = 0.
> > Whether you want one of those or not depends on what BSD
> > kernels do in that kind of "we have to kill this process"
> > situation.)
>
> It looks like the FreeBSD kernel uses sigexit() as its equivalent
> function to Linux's force_sig(), incidentally. Not sure if
> you/we would prefer the bsd-user code to follow the naming that
> FreeBSD's kernel uses or the naming linux-user takes from
> the Linux kernel.
>

My $.02: let's go with linux-inherited linux-user names and drop in a
comment with the FreeBSD name, if they're functionally similar enough
(in general, not just for this specific case). My gut feeling is that
it'll be more useful in the long run if we can more quickly identify
parallels between the two, so changes affecting linux-user that may
benefit bsd-user are more easily identified and exchanged (and
vice-versa).

Thanks,

Kyle Evans


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

* Re: [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  2022-01-13 17:13   ` Peter Maydell
@ 2022-01-14  6:33     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-14  6:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, QEMU Developers

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

On Thu, Jan 13, 2022 at 10:13 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
> >
> > 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).
> >
> > Signed-off-by: Warner Losh <imp@bsdimp.com>
> > ---
> >  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;
> > -                    }
> > -                }
>
> So the previous code was implementing BKPT as a way to do
> a syscall (added in commit 8d450c9a30). Was that just a mistake ?
>

I did some digging and I'm at a loss for why this code was ever here.


> >                  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
> */
>
> Looks like it now matches the freebsd kernel behaviour, anyway.
>

Yea. That's why I went ahead and made the change rather than slavishly
carry it
over for something weird I couldn't find out about... I think it's an old
mistake...
I'll update the commit message to specifically note it.


> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>
> thanks
> -- PMM
>

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

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

* Re: [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-13 17:15   ` Peter Maydell
@ 2022-01-14  6:38     ` Warner Losh
  2022-01-14 10:22       ` Peter Maydell
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-14  6:38 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, QEMU Developers

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

On Thu, Jan 13, 2022 at 10:15 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
> >
> > The code has moved in FreeBSD since the emulator was started, update the
> > comment to reflect that change. Remove now-redundant comment saying the
> > same thing (but incorrectly).
> >
> > Signed-off-by: Warner Losh <imp@bsdimp.com>
> > ---
> >  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];
>
> Commit message says we're updating one comment and deleting a
> second one; code only does an update, no delete ?
>

Commit is right, commit message is wrong. I'll fix the commit message. I got
this confused with part 8 where I kinda sorta did something similar (but not
that similar).

Warner

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

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

* Re: [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-14  6:38     ` Warner Losh
@ 2022-01-14 10:22       ` Peter Maydell
  2022-01-17  4:12         ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 10:22 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, QEMU Developers

On Fri, 14 Jan 2022 at 06:38, Warner Losh <imp@bsdimp.com> wrote:
>
>
>
> On Thu, Jan 13, 2022 at 10:15 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
>> >
>> > The code has moved in FreeBSD since the emulator was started, update the
>> > comment to reflect that change. Remove now-redundant comment saying the
>> > same thing (but incorrectly).
>> >
>> > Signed-off-by: Warner Losh <imp@bsdimp.com>
>> > ---
>> >  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];
>>
>> Commit message says we're updating one comment and deleting a
>> second one; code only does an update, no delete ?
>
>
> Commit is right, commit message is wrong. I'll fix the commit message. I got
> this confused with part 8 where I kinda sorta did something similar (but not
> that similar).

(Maybe you had in mind the similar comment that used to be a few lines
above this one and which you removed in patch 5?)

With a fixed commit message:
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines.
  2022-01-09 16:19 ` [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines Warner Losh
@ 2022-01-14 11:13   ` Peter Maydell
  2022-01-22 16:44     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 11:13 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:53, Warner Losh <imp@bsdimp.com> wrote:
>
> target_sigemptyset: resets a set to having no bits set
> qemu_sigorset:      computes the or of two sets
> 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/qemu.h   |  3 ++
>  bsd-user/signal.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 92 insertions(+)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index e12617f5d69..e8c417c7c33 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -223,7 +223,10 @@ 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);
>  int target_to_host_signal(int sig);
>  int host_to_target_signal(int sig);
> +void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
> +void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
>  void QEMU_NORETURN force_sig(int target_sig);
> +int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
>
>  /* mmap.c */
>  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 93c3b3c5033..8dadc9a39a7 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);
> +
>
>  int host_to_target_signal(int sig)
>  {
> @@ -43,6 +46,44 @@ int target_to_host_signal(int sig)
>      return sig;
>  }
>
> +static inline void target_sigemptyset(target_sigset_t *set)
> +{
> +    memset(set, 0, sizeof(*set));
> +}
> +
> +#include <signal.h>

Don't include system headers halfway through the file like this,
please : put the #include at the top of the file with the others.

> +
> +int
> +qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
> +{
> +    sigset_t work;
> +    int i;
> +
> +    sigemptyset(&work);
> +    for (i = 1; i < NSIG; ++i) {
> +        if (sigismember(left, i) || sigismember(right, i)) {
> +            sigaddset(&work, i);
> +        }
> +    }
> +
> +    *dest = work;
> +    return 0;
> +}

FreeBSD's manpage says it has a native sigorset() --
https://www.freebsd.org/cgi/man.cgi?query=sigemptyset&sektion=3&apropos=0&manpath=freebsd
can you just use that ?

> +
> +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)
>  {
> @@ -55,6 +96,54 @@ static inline void rewind_if_in_safe_syscall(void *puc)
>      }
>  }
>
> +static void host_to_target_sigset_internal(target_sigset_t *d,
> +        const sigset_t *s)
> +{
> +    int i;
> +
> +    target_sigemptyset(d);
> +    for (i = 1; i <= TARGET_NSIG; i++) {

i here is iterating through host signal numbers, not target
numbers, so TARGET_NSIG isn't the right upper bound.
On Linux we iterate from 1 to _NSIG-1; on BSD I think
you may want (i = 0; i < NSIG; i++), but you should check that.

> +        if (sigismember(s, i)) {
> +            target_sigaddset(d, host_to_target_signal(i));
> +        }
> +    }
> +}

These functions are a little odd when you compare them to their
linux-user equivalents, because they're both written
with a sort of abstraction between host and target signal
numbers (they call host_to_target_signal() and
target_to_host_signal()) but also written with baked-in
assumptions that the mapping is basically 1:1 (they don't
have the code that handles the possibility that the
target signal isn't representable as a host signal or
vice-versa). But assuming the BSDs don't change their
signal numbering across architectures, this is fine.

thanks
-- PMM


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

* Re: [PATCH 24/30] bsd-user/signal.c: setup_frame
  2022-01-09 16:19 ` [PATCH 24/30] bsd-user/signal.c: setup_frame Warner Losh
@ 2022-01-14 11:40   ` Peter Maydell
  2022-01-17  6:58     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 11:40 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:36, Warner Losh <imp@bsdimp.com> 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/signal.c | 166 ++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 144 insertions(+), 22 deletions(-)
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 8dadc9a39a7..8e1427553da 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -30,11 +30,27 @@
>   * fork.
>   */
>
> +static target_stack_t target_sigaltstack_used = {
> +    .ss_sp = 0,
> +    .ss_size = 0,
> +    .ss_flags = TARGET_SS_DISABLE,
> +};

sigaltstacks are per-thread, so this needs to be in the TaskState,
not global. (We fixed this in linux-user in commit 5bfce0b74fbd5d5
in 2019: the change is relatively small.)

> +
>  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);
>
> +static inline int on_sig_stack(unsigned long sp)
> +{
> +    return sp - target_sigaltstack_used.ss_sp < target_sigaltstack_used.ss_size;
> +}
> +
> +static inline int sas_ss_flags(unsigned long sp)
> +{
> +    return target_sigaltstack_used.ss_size == 0 ? SS_DISABLE : on_sig_stack(sp)
> +        ? SS_ONSTACK : 0;
> +}
>
>  int host_to_target_signal(int sig)
>  {
> @@ -336,28 +352,6 @@ void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
>      return;
>  }
>
> -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;
> -    }
> -}

There wasn't any need to move this function, I think ?

> -
>  /*
>   * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
>   * 'force' part is handled in process_pending_signals().
> @@ -484,6 +478,134 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
>      cpu_exit(thread_cpu);
>  }
>
> +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;
> +    }
> +}
> +
> +static inline abi_ulong get_sigframe(struct target_sigaction *ka,
> +        CPUArchState *regs, size_t frame_size)
> +{
> +    abi_ulong sp;
> +
> +    /* Use default user stack */
> +    sp = get_sp_from_cpustate(regs);
> +
> +    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
> +        sp = target_sigaltstack_used.ss_sp +
> +            target_sigaltstack_used.ss_size;
> +    }
> +
> +#if defined(TARGET_MIPS) || defined(TARGET_ARM)
> +    return (sp - frame_size) & ~7;
> +#elif defined(TARGET_AARCH64)
> +    return (sp - frame_size) & ~15;
> +#else
> +    return sp - frame_size;
> +#endif

We don't need to do it in this patchseries, but you should strongly
consider pulling the architecture-specifics out in a way that
avoids this kind of ifdef ladder.

> +}
> +
> +/* compare to mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c sendsig() */
> +static void setup_frame(int sig, int code, struct target_sigaction *ka,
> +    target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *regs)
> +{
> +    struct target_sigframe *frame;
> +    abi_ulong frame_addr;
> +    int i;
> +
> +    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
> +    trace_user_setup_frame(regs, frame_addr);
> +    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
> +        goto give_sigsegv;

FreeBSD for Arm (haven't checked other BSDs or other archs)
gives a SIGILL for the "can't write signal frame to stack"
case, I think:
https://github.com/freebsd/freebsd-src/blob/main/sys/arm/arm/exec_machdep.c#L316
I don't understand why they picked SIGILL, SIGSEGV seems much more
logical to me, but we should follow the kernel behaviour.

> +    }
> +
> +    memset(frame, 0, sizeof(*frame));
> +#if defined(TARGET_MIPS)
> +    int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC :
> +        TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC;
> +#else
> +    int mflags = 0;
> +#endif
> +    if (get_mcontext(regs, &frame->sf_uc.uc_mcontext, mflags)) {
> +        goto give_sigsegv;

The FreeBSD kernel get_mcontext() can't fail -- why can ours ?
(This matters because SIGSEGV may not be the right response to
whatever the failure case is.)

> +    }
> +
> +    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
> +        if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i])) {
> +            goto give_sigsegv;

__get_user() and __put_user() in QEMU can't fail, so you don't
need to check for errors here, unlike the non-double-underscore
versions. At some point you might want to take the current linux-user
versions of these user-access functions/macros: it looks like bsd-user
has an older version which doesn't handle the case where the guest
has looser alignment restrictions than the host. The new ones
actually expand to do { ... } while(0) statements which won't
be valid inside an if() condition.

(Historical note: the reason QEMU's __put_user/__get_user ever had
return values at all is that the linux-user code was copy-and-pasted
from the Linux kernel. In the Linux kernel handling of writing
data to userspace is/was error-checked on every write, whereas
QEMU does the "is this writable" test once with the lock_user
function and then can assume all the writes to that area succeed.
But we still started with a lot of copy-pasted code that was doing
unnecessary checks on __put_user and __get_user return values.
FreeBSD seems to handle write-checking in yet a third way, by
assembling the struct in kernel-space and checking for writability
once at the end when it copies the whole block out to userspace.)

> +        }
> +    }
> +
> +    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;
> +
> +        if (TARGET_SIGILL == sig || TARGET_SIGFPE == sig ||
> +                TARGET_SIGSEGV == sig || TARGET_SIGBUS == sig ||
> +                TARGET_SIGTRAP == sig) {
> +            frame->sf_si._reason._fault._trapno = tinfo->_reason._fault._trapno;
> +        }
> +
> +        /*
> +         * If si_code is one of SI_QUEUE, SI_TIMER, SI_ASYNCIO, or
> +         * SI_MESGQ, then si_value contains the application-specified
> +         * signal value. Otherwise, the contents of si_value are
> +         * undefined.
> +         */
> +        if (SI_QUEUE == code || SI_TIMER == code || SI_ASYNCIO == code ||
> +                SI_MESGQ == code) {
> +            frame->sf_si.si_value.sival_int = tinfo->si_value.sival_int;
> +        }
> +
> +        if (SI_TIMER == code) {
> +            frame->sf_si._reason._timer._timerid =
> +                tinfo->_reason._timer._timerid;
> +            frame->sf_si._reason._timer._overrun =
> +                tinfo->_reason._timer._overrun;
> +        }
> +
> +#ifdef SIGPOLL
> +        if (SIGPOLL == sig) {
> +            frame->sf_si._reason._band = tinfo->_reason._band;
> +        }
> +#endif

This seems to be yet a third set of the logic for handling
target_siginfo_t's union, to go along with tswap_siginfo() and
host_to_target_siginfo_noswap(), except that the logic here is
different. linux-user calls tswap_siginfo() in its signal-frame
setup code.

> +
> +    }
> +
> +    if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) {
> +        goto give_sigsegv;
> +    }

set_sigtramp_args() can't fail. (Not sure why it has a non-void
return type.)

> +
> +    unlock_user_struct(frame, frame_addr, 1);
> +    return;
> +
> +give_sigsegv:
> +    unlock_user_struct(frame, frame_addr, 1);
> +    force_sig(TARGET_SIGSEGV);
> +}
> +
>  void signal_init(void)
>  {
>      TaskState *ts = (TaskState *)thread_cpu->opaque;
> --
> 2.33.1

thanks
-- PMM


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

* Re: [PATCH 25/30] bsd-user/signal.c: handle_pending_signal
  2022-01-09 16:19 ` [PATCH 25/30] bsd-user/signal.c: handle_pending_signal Warner Losh
@ 2022-01-14 11:50   ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 11:50 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:47, Warner Losh <imp@bsdimp.com> 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>


> +static void handle_pending_signal(CPUArchState *cpu_env, int sig,
> +                                  struct emulated_sigtable *k)
> +{
> +    CPUState *cpu = env_cpu(cpu_env);
> +    TaskState *ts = cpu->opaque;
> +    struct qemu_sigqueue *q;
> +    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(cpu_env, sig);
> +
> +    /* Dequeue signal. */
> +    q = k->first;
> +    k->first = q->next;
> +    if (!k->first) {
> +        k->pending = 0;
> +    }

(The dequeue simplifies if you follow linux-user's way of handling
"queueing" a signal.)

> +
> +    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, &q->info);
> +    }
> +
> +    if (handler == TARGET_SIG_DFL) {
> +        /*
> +         * default handler : ignore some signal. The other are job
> +         * control or fatal.
> +         */
> +        if (TARGET_SIGTSTP == sig || TARGET_SIGTTIN == sig ||
> +                TARGET_SIGTTOU == sig) {
> +            kill(getpid(), SIGSTOP);
> +        } else if (TARGET_SIGCHLD != sig && TARGET_SIGURG != sig &&
> +            TARGET_SIGINFO != sig &&
> +            TARGET_SIGWINCH != sig && TARGET_SIGCONT != sig) {
> +            force_sig(sig);
> +        }
> +    } else if (TARGET_SIG_IGN == handler) {

Avoid the yoda-conditionals, please.

> +        /* ignore sig */
> +    } else if (TARGET_SIG_ERR == handler) {
> +        force_sig(sig);

Note that if you follow linux-user and my suggestion on
patch 21, these force_sig() calls become calls to
dump_core_and_abort(), unlike the one in setup_frame(),
which should be a "queue this signal". (The difference is
that here we know the process is definitely going to die,
because it has no valid handler for a fatal signal. In
setup_frame() the process might be able to continue, if it
has a signal handler for the SIGILL or SIGSEGV or whatever.)

> +    } 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;
> +        qemu_sigorset(&ts->signal_mask, blocked_set, &set);
> +        ts->in_sigsuspend = false;
> +        sigprocmask(SIG_SETMASK, &ts->signal_mask, NULL);
> +
> +        /* XXX VM86 on x86 ??? */
> +
> +        code = q->info.si_code;
> +        /* prepare the stack frame of the virtual CPU */
> +        if (sa->sa_flags & TARGET_SA_SIGINFO) {
> +            tswap_siginfo(&tinfo, &q->info);

Oh, you're doing the tswap_siginfo() here. If you really want to
do that, then the setup_frame() should be able to do a simple
structure-copy I think and doesn't need the logic to figure out
which union fields are relevant. But putting the tswap_siginfo()
inside setup_frame() would match where linux-user does it.

> +            setup_frame(sig, code, sa, &target_old_set, &tinfo, cpu_env);
> +        } else {
> +            setup_frame(sig, code, sa, &target_old_set, NULL, cpu_env);
> +        }
> +        if (sa->sa_flags & TARGET_SA_RESETHAND) {
> +            sa->_sa_handler = TARGET_SIG_DFL;
> +        }
> +    }
> +    if (q != &k->info) {
> +        free_sigqueue(cpu_env, q);
> +    }
> +}
> +
>  void process_pending_signals(CPUArchState *cpu_env)
>  {
>  }
> --
> 2.33.1

thanks
-- PMM


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

* Re: [PATCH 26/30] bsd-user/signal.c: tswap_siginfo
  2022-01-09 16:19 ` [PATCH 26/30] bsd-user/signal.c: tswap_siginfo Warner Losh
@ 2022-01-14 11:54   ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 11:54 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:56, Warner Losh <imp@bsdimp.com> 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 | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 934528d5fb0..c954d0f4f37 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -197,6 +197,40 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
>      }
>  }
>
> +static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
> +{
> +    int sig, code;
> +
> +    sig = info->si_signo;
> +    code = info->si_code;
> +    tinfo->si_signo = tswap32(sig);
> +    tinfo->si_errno = tswap32(info->si_errno);
> +    tinfo->si_code = tswap32(info->si_code);
> +    tinfo->si_pid = tswap32(info->si_pid);
> +    tinfo->si_uid = tswap32(info->si_uid);
> +    tinfo->si_status = tswap32(info->si_status);
> +    tinfo->si_addr = tswapal(info->si_addr);

This implicitly assumes FreeBSD target_siginfo_t, because
(a) all the field names are different on eg NetBSD
(b) if, like NetBSD, the pid and uid fields are inside the same
union as the addr, you can't just swap all of them unconditionally
but need different logic to handle them as part of the "which bit
of the union is valid" code.

FreeBSD-only is fine for now, but you might want to add a comment.

> +    /*
> +     * 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;
> +    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig ||
> +            SIGTRAP == sig) {
> +        tinfo->_reason._fault._trapno = tswap32(info->_reason._fault._trapno);
> +    }
> +#ifdef SIGPOLL
> +    if (SIGPOLL == sig) {
> +        tinfo->_reason._poll._band = tswap32(info->_reason._poll._band);
> +    }
> +#endif
> +    if (SI_TIMER == code) {
> +        tinfo->_reason._timer._timerid = tswap32(info->_reason._timer._timerid);
> +        tinfo->_reason._timer._overrun = tswap32(info->_reason._timer._overrun);
> +    }
> +}

You had a call to this already in the previous patch, which presumably
means that it didn't compile at that point in the series, so this
patch should be moved earlier.

My reply to patch 2 has the higher-level commentary about handling
of target_siginfo_t.

thanks
-- PMM


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

* Re: [PATCH 27/30] bsd-user/signal.c: process_pending_signals
  2022-01-09 16:19 ` [PATCH 27/30] bsd-user/signal.c: process_pending_signals Warner Losh
@ 2022-01-14 11:55   ` Peter Maydell
  2022-01-17  2:09     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 11:55 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:57, Warner Losh <imp@bsdimp.com> 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 | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index c954d0f4f37..1dd6dbb4ee1 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -781,6 +781,40 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
>
>  void process_pending_signals(CPUArchState *cpu_env)

I won't review this, because I favour using the logic that
linux-user does here.

-- PMM


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

* Re: [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn
  2022-01-09 16:19 ` [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn Warner Losh
@ 2022-01-14 12:12   ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 12:12 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 17:00, 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>
> ---
>  bsd-user/qemu.h   |  3 +--
>  bsd-user/signal.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+), 2 deletions(-)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 011fdfebbaa..b8c64ca0e5b 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -219,14 +219,13 @@ 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);
>  int target_to_host_signal(int sig);
>  int host_to_target_signal(int sig);
>  void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
>  void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
> +long do_sigreturn(CPUArchState *regs, abi_ulong addr);

Please always call CPUArchState* arguments 'env'.

>  void QEMU_NORETURN force_sig(int target_sig);
>  int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
>
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 1dd6dbb4ee1..d11f5eddd7e 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -640,6 +640,62 @@ give_sigsegv:
>      force_sig(TARGET_SIGSEGV);
>  }
>
> +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);

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.)

-- PMM


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

* Re: [PATCH 29/30] bsd-user/signal.c: implement do_sigaction
  2022-01-09 16:19 ` [PATCH 29/30] bsd-user/signal.c: implement do_sigaction Warner Losh
@ 2022-01-14 13:13   ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 13:13 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 16:32, 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>
> ---
>  bsd-user/qemu.h   | 21 +++++++++++++
>  bsd-user/signal.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 97 insertions(+)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index b8c64ca0e5b..c643d6ba246 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -226,8 +226,29 @@ int host_to_target_signal(int sig);
>  void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
>  void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
>  long do_sigreturn(CPUArchState *regs, abi_ulong addr);
> +int do_sigaction(int sig, const struct target_sigaction *act,
> +                struct target_sigaction *oact);
>  void QEMU_NORETURN force_sig(int target_sig);
>  int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
> +/**
> + * block_signals: block all signals while handling this guest syscall
> + *
> + * Block all signals, and arrange that the signal mask is returned to
> + * its correct value for the guest before we resume execution of guest code.
> + * If this function returns non-zero, then the caller should immediately
> + * return -TARGET_ERESTARTSYS to the main loop, which will take the pending
> + * signal and restart execution of the syscall.
> + * If block_signals() returns zero, then the caller can continue with
> + * emulation of the system call knowing that no signals can be taken
> + * (and therefore that no race conditions will result).
> + * This should only be called once, because if it is called a second time
> + * it will always return non-zero. (Think of it like a mutex that can't
> + * be recursively locked.)
> + * Signals will be unblocked again by process_pending_signals().
> + *
> + * Return value: non-zero if there was a pending signal, zero if not.
> + */
> +int block_signals(void); /* Returns non zero if signal pending */
>
>  /* mmap.c */
>  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index d11f5eddd7e..f055d1db407 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -231,6 +231,22 @@ static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info)
>      }
>  }
>
> +int block_signals(void)
> +{
> +    TaskState *ts = (TaskState *)thread_cpu->opaque;
> +    sigset_t set;
> +
> +    /*
> +     * It's OK to block everything including SIGSEGV, because we won't run any
> +     * further guest code before unblocking signals in
> +     * process_pending_signals().
> +     */
> +    sigfillset(&set);
> +    sigprocmask(SIG_SETMASK, &set, 0);

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()?

> +
> +    return qatomic_xchg(&ts->signal_pending, 1);
> +}
> +
>  /* Returns 1 if given signal should dump core if not handled. */
>  static int core_dump_signal(int sig)
>  {
> @@ -534,6 +550,66 @@ static int fatal_signal(int sig)
>      }
>  }
>
> +/* do_sigaction() return host values and errnos */
> +int do_sigaction(int sig, const struct target_sigaction *act,
> +        struct target_sigaction *oact)
> +{
> +    struct target_sigaction *k;
> +    struct sigaction act1;
> +    int host_sig;
> +    int ret = 0;
> +
> +    if (sig < 1 || sig > TARGET_NSIG || TARGET_SIGKILL == sig ||
> +            TARGET_SIGSTOP == sig) {

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.)

> +        return -EINVAL;
> +    }
> +
> +    if (block_signals()) {
> +        return -TARGET_ERESTART;

Are we returning host errnos, or target errnos ?
(The linux-user version of this function has been a bit
confused about this in the past; I suspect you've picked up
fragments of it from different points in time.)

> +    }
> +
> +    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;
> +}

-- PMM


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

* Re: [PATCH 30/30] bsd-user/signal.c: do_sigaltstack
  2022-01-09 16:19 ` [PATCH 30/30] bsd-user/signal.c: do_sigaltstack Warner Losh
@ 2022-01-14 13:18   ` Peter Maydell
  2022-01-22 22:20     ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 13:18 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, qemu-devel

On Sun, 9 Jan 2022 at 17:08, Warner Losh <imp@bsdimp.com> wrote:
>
> Implement the meat of the sigaltstack(2) system call with do_sigaltstack.
>
> 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 | 66 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 67 insertions(+)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index c643d6ba246..fcdea460ed2 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -226,6 +226,7 @@ int host_to_target_signal(int sig);
>  void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
>  void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
>  long do_sigreturn(CPUArchState *regs, abi_ulong addr);
> +abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
>  int do_sigaction(int sig, const struct target_sigaction *act,
>                  struct target_sigaction *oact);
>  void QEMU_NORETURN force_sig(int target_sig);
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index f055d1db407..e5e5e28c60c 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -528,6 +528,72 @@ 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)
> +{
> +    int ret;
> +    target_stack_t oss;
> +
> +    if (uoss_addr) {
> +        /* Save current signal stack params */
> +        oss.ss_sp = tswapl(target_sigaltstack_used.ss_sp);
> +        oss.ss_size = tswapl(target_sigaltstack_used.ss_size);
> +        oss.ss_flags = tswapl(sas_ss_flags(sp));
> +    }

This will need some minor changes to work with the sigaltstack
info being per-thread and in the TaskState struct.

-- PMM


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

* Re: [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-13 17:40   ` Peter Maydell
@ 2022-01-14 18:13     ` Warner Losh
  2022-01-14 18:21       ` Peter Maydell
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-14 18:13 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, QEMU Developers

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

On Thu, Jan 13, 2022 at 10:40 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
> >
> > Update for the richer set of data faults that are now possible. Copied
> > largely from linux-user/arm/cpu_loop.c
> >
> > Signed-off-by: Warner Losh <imp@bsdimp.com>
> > ---
> >  bsd-user/arm/target_arch_cpu.h | 44 ++++++++++++++++++++++++++--------
> >  1 file changed, 34 insertions(+), 10 deletions(-)
> >
> > diff --git a/bsd-user/arm/target_arch_cpu.h
> b/bsd-user/arm/target_arch_cpu.h
> > index 996a361e3fe..51e592bcfe7 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);
> >
> > @@ -143,15 +142,40 @@ 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: /* Permision fault, level 1 */
> > +            case 0xf: /* Permision fault, level 2 */
>
> "Permission" (I see we have this typo in linux-user).
>

Fixed. Also, if you can, please cc me if you'd like on 'back ported' fixes
into linux-user when you post them
for review that arise from this. It helps me keep track and not miss them
in this rather high volume mailing
list.


> > +                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();
> > +            }
>
> Otherwise
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>

Thanks!

Warner

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

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

* Re: [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-14 18:13     ` Warner Losh
@ 2022-01-14 18:21       ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-14 18:21 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, QEMU Developers

On Fri, 14 Jan 2022 at 18:14, Warner Losh <imp@bsdimp.com> wrote:
>
>
>
> On Thu, Jan 13, 2022 at 10:40 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
>> >
>> > Update for the richer set of data faults that are now possible. Copied
>> > largely from linux-user/arm/cpu_loop.c
>> >
>> > Signed-off-by: Warner Losh <imp@bsdimp.com>

>> "Permission" (I see we have this typo in linux-user).
>
>
> Fixed. Also, if you can, please cc me if you'd like on 'back ported' fixes into linux-user when you post them
> for review that arise from this. It helps me keep track and not miss them in this rather high volume mailing
> list.

Sure, I can do that. Already posted this afternoon:
https://patchew.org/QEMU/20220114153732.3767229-1-peter.maydell@linaro.org/
https://patchew.org/QEMU/20220114155032.3767771-1-peter.maydell@linaro.org/

and I forgot about the 'permision' typo or I'd have folded it into
that 'nits' series, so I'll post that in a moment...

-- PMM


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

* Re: [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation
  2022-01-13 17:44   ` Peter Maydell
@ 2022-01-14 18:27     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-14 18:27 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 10:45 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> 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>
> > ---
> >  bsd-user/qemu.h   |  2 ++
> >  bsd-user/signal.c | 11 +++++++++++
> >  2 files changed, 13 insertions(+)
> >
> > diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> > index 1b3b974afe9..334f8b1d715 100644
> > --- a/bsd-user/qemu.h
> > +++ b/bsd-user/qemu.h
> > @@ -210,6 +210,8 @@ 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);
> > +int target_to_host_signal(int sig);
> > +int host_to_target_signal(int sig);
> >
> >  /* mmap.c */
> >  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index 844dfa19095..7ea86149981 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,16 @@
> >   * fork.
> >   */
> >
> > +int host_to_target_signal(int sig)
> > +{
> > +    return sig;
> > +}
> > +
> > +int target_to_host_signal(int sig)
> > +{
> > +    return sig;
> > +}
> > +
>
> This could use a comment:
>
> /*
>  * For the BSDs signal numbers are always the same regardless of
>  * CPU architecture, so (unlike Linux) these functions are just
>  * the identity mapping.
>  */
>
> (assuming that is correct, of course!)
>

It's true enough. Even though there's code to run FooBSD on BarBSD,
that code doesn't work (at all really) today. It would take some doing to
get that working, so I've added a comment that the encoding might not
be the same in that case, but otherwise is the same.

This is issue is one I'm deferring doing anything on until I can get things
upstreamed... It's a bit of a mess if you aren't on FreeBSD, but neither the
NetBSD nor OpenBSD communities are using bsd-user because it's so
broken and incomplete in implementing their ABIs.


> Otherwise
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>

Thanks!

Warner

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

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

* Re: [PATCH 10/30] bsd-user/signal.c: Implement signal_init()
  2022-01-13 19:28   ` Peter Maydell
@ 2022-01-14 18:51     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-14 18:51 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 12:28 PM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
> >
> > 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>
> > ---
> >  bsd-user/qemu.h   |  1 +
> >  bsd-user/signal.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 69 insertions(+)
>
> > +static struct target_sigaction sigact_table[TARGET_NSIG];
>
>
>
>
> >  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);
> > +
> > +    /*
> > +     * Set all host signal handlers. ALL signals are blocked during the
> > +     * handlers to serialize them.
> > +     */
> > +    memset(sigact_table, 0, sizeof(sigact_table));
>
> Do you need this memset()? sigact_table is a global, so it's
> zero-initialized on startup, and this function is only called once.
> The (otherwise basically identical) Linux version of this function
> doesn't have it.
>

Yea, that looks bogus. I'll remove it.


> > +
> > +    sigfillset(&act.sa_mask);
> > +    act.sa_sigaction = host_signal_handler;
> > +    act.sa_flags = SA_SIGINFO;
> > +
> > +    for (i = 1; i <= TARGET_NSIG; i++) {
> > +        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);
> > +        }
> > +    }
> >  }
>
> Otherwise
>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>

thanks!

Warner

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

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

* Re: [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-13 19:43   ` Peter Maydell
@ 2022-01-15  6:19     ` Warner Losh
  2022-01-15 11:08       ` Peter Maydell
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-15  6:19 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 12:43 PM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:41, Warner Losh <imp@bsdimp.com> 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 | 37 +++++++++++++++++++++++++++++++++++++
> >  1 file changed, 37 insertions(+)
> >
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index 7168d851be8..3fe8b2d9898 100644
> > --- a/bsd-user/signal.c
> > +++ b/bsd-user/signal.c
> > @@ -43,6 +43,43 @@ int target_to_host_signal(int sig)
> >      return sig;
> >  }
> >
> > +/* Siginfo conversion. */
> > +static inline void host_to_target_siginfo_noswap(target_siginfo_t
> *tinfo,
> > +        const siginfo_t *info)
> > +{
> > +    int sig, code;
> > +
> > +    sig = host_to_target_signal(info->si_signo);
> > +    /* XXX should have host_to_target_si_code() */
> > +    code = tswap32(info->si_code);
> > +    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 */
> > +    tinfo->si_value.sival_ptr =
> > +        (abi_ulong)(unsigned long)info->si_value.sival_ptr;
> > +    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS ==
> sig ||
>
> Don't use yoda-conditions, please. sig == SIGILL, etc.
>
> > +            SIGTRAP == sig) {
> > +        tinfo->_reason._fault._trapno = info->_reason._fault._trapno;
> > +    }
> > +#ifdef SIGPOLL
> > +    if (SIGPOLL == sig) {
> > +        tinfo->_reason._poll._band = info->_reason._poll._band;
> > +    }
> > +#endif
> > +    if (SI_TIMER == code) {
> > +        int timerid;
> > +
> > +        timerid = info->_reason._timer._timerid;
> > +        tinfo->_reason._timer._timerid = timerid;
> > +        tinfo->_reason._timer._overrun = info->_reason._timer._overrun;
> > +    }
> > +}
>
> I think this will only compile on FreeBSD (the other BSDs having
> notably different target_siginfo_t structs); I guess we're OK
> with that ?
>

Yes. bsd-user fork does not compile on the other BSDs. There's too many
things missing, and too few places where specific code is in place. I'm
thinking
that it won't be possible to implement running NetBSD binaries on FreeBSD
or vice versa since they are so different. OpenBSD and NetBSD are a lot
closer to each other, with fewer critical differences in areas like
threads, so
it may be possible there. There's a lot of rework that's needed in this area
to take what's even in bsd-user fork and make it work on NetBSD or
OpenBSD, exactly for reasons like this. I've been ignoring the elephant
in the room for a while now, ever since I realized this fundamental
shift.


> I also commented on the general setup linux-user has for this
> function back in patch 2; I'll let you figure out whether what
> you have here is the right thing for BSD.
>

Yea. I'm still thinking through what you said there (and elsewhere). These
issues may be the root cause of some regressions in arm binaries between
6.1 and 6.2 as I tried to adopt the sigsegv/sigbus changes.

I need to work through those things in our development branch before trying
to fold them into this series. And I'm not yet sure the right way to do
that because
many of the things are likely to be largish changes that may be tough to
manage
keeping this patch series in sync. So I'm going to do all the trivial style
and
tiny bug things first, then tackle this more fundamental issue. I've thought
about it enough to understand that the code in this patch series has some
conceptual mistakes that must be addressed. Having this very detailed
feedback
is quite helpful in laying out the path for me to fix these issues (even if
I don't
ultimately do everything like linux-user, I'll know why it's different
rather than
the current situation where there's much inherited code and the best answer
I could give is 'well linux-user was like that 5 years ago and we needed to
make
these hacks to make things work' which is completely unsatisfying to give
and
to hear.

Warner

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

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

* Re: [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-15  6:19     ` Warner Losh
@ 2022-01-15 11:08       ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-15 11:08 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, QEMU Developers

On Sat, 15 Jan 2022 at 06:19, Warner Losh <imp@bsdimp.com> wrote:
> I need to work through those things in our development branch before trying
> to fold them into this series. And I'm not yet sure the right way to do that because
> many of the things are likely to be largish changes that may be tough to manage
> keeping this patch series in sync. So I'm going to do all the trivial style and
> tiny bug things first, then tackle this more fundamental issue. I've thought
> about it enough to understand that the code in this patch series has some
> conceptual mistakes that must be addressed. Having this very detailed feedback
> is quite helpful in laying out the path for me to fix these issues (even if I don't
> ultimately do everything like linux-user, I'll know why it's different rather than
> the current situation where there's much inherited code and the best answer
> I could give is 'well linux-user was like that 5 years ago and we needed to make
> these hacks to make things work' which is completely unsatisfying to give and
> to hear.

Mmm. To the extent that the signal handling code you have in your out-of-tree
branch is "this is what FreeBSD is shipping to users and it works more-or-less",
maybe we should just accept that upstream with (with comments noting that
it's got issues/is based on an older linux-user) and then update it to
match today's
linux-user as a second round of patching? If we have a definite path to
eventually getting to the right place, I don't want to insist that you update
all this stuff in your branch first before we let it land upstream if that's
going to burden you with massively more work.

-- PMM


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

* Re: [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler
  2022-01-13 20:17   ` Peter Maydell
@ 2022-01-16 20:52     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-16 20:52 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 1:17 PM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:40, Warner Losh <imp@bsdimp.com> 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(+)
> >
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index b1331f63d61..a6e07277fb2 100644
> > --- a/bsd-user/signal.c
> > +++ b/bsd-user/signal.c
> > @@ -142,6 +142,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)
> >  {
> > +    CPUState *cpu = thread_cpu;
> > +    CPUArchState *env = cpu->env_ptr;
> > +    int sig;
> > +    target_siginfo_t tinfo;
> > +    ucontext_t *uc = puc;
> > +    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. */
> > +    sig = host_to_target_signal(host_sig);
> > +    if (sig < 1 || sig > TARGET_NSIG) {
> > +        return;
> > +    }
> > +    trace_user_host_signal(cpu, host_sig, sig);
> > +
> > +    host_to_target_siginfo_noswap(&tinfo, info);
> > +
> > +    queue_signal(env, sig, &tinfo);       /* XXX how to cope with
> failure? */
>
> queue_signal() can't fail, so there is nothing to cope with.
> (Your bsd-user version even has the right 'void' type --
> linux-user's returns 1 always and we never look at the return
> value, so we should really switch that to void return too.)
>

Submitted a patch to that last bit. I'll remove this comment in the rework
I'm doing.


> > +    /*
> > +     * Linux does something else here -> the queue signal may be wrong,
> but
> > +     * maybe not.  And then it does the rewind_if_in_safe_syscall
> > +     */
>
> I think you have here a bit of a mix of linux-user's current design
> and some older (broken) version. This is how linux-user works today:
>

Yes. I think we forked bsd-user from linux-user around 2015 and the old
design dropped signal queueing in 2016 if I'm reading git log correctly.


>  * queue_signal() is a little bit misnamed, because there is no
>    "queue" here: there can only be at most one "queued" signal,
>    and it lives in the TaskState struct (which is user-only specific
>    information that hangs off the guest CPU struct) as the
>    TaskState::sync_signal field. The reason
>    we only have one at once is that queue_signal() is used only
>    for signals generated by QEMU itself by calling queue_signal()
>    directly or indirectly from the cpu_loop() code. The cpu loop
>    always calls process_pending_signals() at the end of its loop,
>    which will pick up a queued signal. We never call queue_signal()
>    twice in a row before getting back to process_pending_signals(),
>    so there's only ever at most one thing in the "queue".
>  * for all signals we get from the host except SIGSEGV/SIGBUS,
>    we track whether there's a host signal pending in the
>    TaskState::sigtab[] array (which is indexed by signal number).
>    We block all host signals except SIGSEGV/SIGBUS before calling
>    cpu_exit(), so we know we're not going to get more than one
>    of these at once (and it won't clash with a queue_signal()
>    signal either, as those use the sync_signal field, not the
>    sigtab[]).
>  * for host-sent non-spoofed (ie not sent via 'kill()') SIGSEGV/SIGBUS,
>    we know this was caused by a bit of generated code, so we just
>    use cpu_loop_exit_restore() to turn this into an EXCP_INTERRUPT
>    at the right guest PC
>
> I feel fairly strongly that you definitely want to use the same
> design as current linux-user does for signals:
>  * getting this right is pretty tricky, and even if we get two
>    different designs to both have the same semantics it's going
>    to be pretty confusing
>  * we thought quite hard about the linux-user code at the time
>    and it's definitely less buggy than the previous design
>  * It's much easier to review the bsd-user code as "yes this is
>    doing the same thing linux-user does" than working through
>    a different approach from first principles
>

I agree. I like that design better than what's in bsd-user today and
seems simpler to implement and get right. I'd add a 4th bullet point
"It's easier to share code, either directly or via copying"


> I don't have as strong an opinion on whether we should try to get
> it into the tree that way from the start, or to put in whatever
> you have currently and then fix it later. (More accurately,
> I would prefer to review patches which use the same design
> as linux-user but if that's going to be massively painful/slow
> for you to get something upstream doing it that way around
> I can probably live with the other approach...)
>

I'm going to start down that path and see if I can rework the patches
and see if it solves some of the regressions we've seen in bsd-user
between 6.1 and 6.2 as the signal stuff was reworked in linux-user
to cope better with sigsegv and sigbus. If that works out OK, then
I'll move forward with adjusting the fork and reflect that back into
this patch series.


> > +    /*
> > +     * 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.
> > +     XXXX Should this be in queue_signal?
>
> No, because queue_signal() is called for lots of ways to pend
> a signal, most of which aren't real host signals.
>

OK. I now agree after reading the code.


> > +     */
> > +    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)
>
> thanks
>

Thank you for the insight and places to focus on making this code better.
It's
a bit hard to discover all this just from reading code in any sane amount
of time
and it is both quite helpful and much appreciated.

Warner

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

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

* Re: [PATCH 27/30] bsd-user/signal.c: process_pending_signals
  2022-01-14 11:55   ` Peter Maydell
@ 2022-01-17  2:09     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-17  2:09 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Fri, Jan 14, 2022 at 4:55 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:57, Warner Losh <imp@bsdimp.com> 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 | 34 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> >
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index c954d0f4f37..1dd6dbb4ee1 100644
> > --- a/bsd-user/signal.c
> > +++ b/bsd-user/signal.c
> > @@ -781,6 +781,40 @@ static void handle_pending_signal(CPUArchState
> *cpu_env, int sig,
> >
> >  void process_pending_signals(CPUArchState *cpu_env)
>
> I won't review this, because I favour using the logic that
> linux-user does here.
>

I've rewritten it to use that, I believe (I'll check that belief before
v2), so likely a good call.

Warner

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

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

* Re: [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_*
  2022-01-13 19:32   ` Peter Maydell
@ 2022-01-17  3:53     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-17  3:53 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, QEMU Developers

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

On Thu, Jan 13, 2022 at 12:32 PM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:33, Warner Losh <imp@bsdimp.com> 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>
>
> > +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 which we don't have access to here.  We assume
> that uc
> > +     * is part of a trapframe and reach around to get to the si_info
> that's in
> > +     * the sigframe just before it, though this may be unwise.
> > +     */
>
> Yeah, that's pretty nasty. But this function is passed a
> siginfo_t pointer -- isn't that the one you need ?
>

Doh! I feel stupid now... You're right. This is a lot easier than I
thought. I'll fix that.

Warner


> > +    siginfo_t *si;
> > +    si = &((siginfo_t *)uc)[-1];
> > +    uint32_t fsr = si->si_trapno;
> > +
> > +    return extract32(fsr, 11, 1);
> > +}
>
> thanks
> -- PMM
>

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

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

* Re: [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-14 10:22       ` Peter Maydell
@ 2022-01-17  4:12         ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-17  4:12 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, QEMU Developers

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

On Fri, Jan 14, 2022 at 3:22 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Fri, 14 Jan 2022 at 06:38, Warner Losh <imp@bsdimp.com> wrote:
> >
> >
> >
> > On Thu, Jan 13, 2022 at 10:15 AM Peter Maydell <peter.maydell@linaro.org>
> wrote:
> >>
> >> On Sun, 9 Jan 2022 at 16:26, Warner Losh <imp@bsdimp.com> wrote:
> >> >
> >> > The code has moved in FreeBSD since the emulator was started, update
> the
> >> > comment to reflect that change. Remove now-redundant comment saying
> the
> >> > same thing (but incorrectly).
> >> >
> >> > Signed-off-by: Warner Losh <imp@bsdimp.com>
> >> > ---
> >> >  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];
> >>
> >> Commit message says we're updating one comment and deleting a
> >> second one; code only does an update, no delete ?
> >
> >
> > Commit is right, commit message is wrong. I'll fix the commit message. I
> got
> > this confused with part 8 where I kinda sorta did something similar (but
> not
> > that similar).
>
> (Maybe you had in mind the similar comment that used to be a few lines
> above this one and which you removed in patch 5?)
>

I think that's where I got confused.

Warner


> With a fixed commit message:
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>
> thanks
> -- PMM
>

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

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

* Re: [PATCH 24/30] bsd-user/signal.c: setup_frame
  2022-01-14 11:40   ` Peter Maydell
@ 2022-01-17  6:58     ` Warner Losh
  2022-01-17  7:24       ` Warner Losh
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-17  6:58 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Fri, Jan 14, 2022 at 4:40 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:36, Warner Losh <imp@bsdimp.com> 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/signal.c | 166 ++++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 144 insertions(+), 22 deletions(-)
> >
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index 8dadc9a39a7..8e1427553da 100644
> > --- a/bsd-user/signal.c
> > +++ b/bsd-user/signal.c
> > @@ -30,11 +30,27 @@
> >   * fork.
> >   */
> >
> > +static target_stack_t target_sigaltstack_used = {
> > +    .ss_sp = 0,
> > +    .ss_size = 0,
> > +    .ss_flags = TARGET_SS_DISABLE,
> > +};
>
> sigaltstacks are per-thread, so this needs to be in the TaskState,
> not global. (We fixed this in linux-user in commit 5bfce0b74fbd5d5
> in 2019: the change is relatively small.)
>

Done. I saw go mentioned, which I know doesn't work today, so it's
a good step in that direction...


> > +
> >  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);
> >
> > +static inline int on_sig_stack(unsigned long sp)
> > +{
> > +    return sp - target_sigaltstack_used.ss_sp <
> target_sigaltstack_used.ss_size;
> > +}
> > +
> > +static inline int sas_ss_flags(unsigned long sp)
> > +{
> > +    return target_sigaltstack_used.ss_size == 0 ? SS_DISABLE :
> on_sig_stack(sp)
> > +        ? SS_ONSTACK : 0;
> > +}
> >
> >  int host_to_target_signal(int sig)
> >  {
> > @@ -336,28 +352,6 @@ void queue_signal(CPUArchState *env, int sig,
> target_siginfo_t *info)
> >      return;
> >  }
> >
> > -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;
> > -    }
> > -}
>
> There wasn't any need to move this function, I think ?
>

No, there was some other conflict during rebase getting the patch train
ready that I thought I'd cleaned up, but this was fallout from that which
I overlooked. I've undone it...


> > -
> >  /*
> >   * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
> >   * 'force' part is handled in process_pending_signals().
> > @@ -484,6 +478,134 @@ static void host_signal_handler(int host_sig,
> siginfo_t *info, void *puc)
> >      cpu_exit(thread_cpu);
> >  }
> >
> > +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;
> > +    }
> > +}
> > +
> > +static inline abi_ulong get_sigframe(struct target_sigaction *ka,
> > +        CPUArchState *regs, size_t frame_size)
> > +{
> > +    abi_ulong sp;
> > +
> > +    /* Use default user stack */
> > +    sp = get_sp_from_cpustate(regs);
> > +
> > +    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
> > +        sp = target_sigaltstack_used.ss_sp +
> > +            target_sigaltstack_used.ss_size;
> > +    }
> > +
> > +#if defined(TARGET_MIPS) || defined(TARGET_ARM)
> > +    return (sp - frame_size) & ~7;
> > +#elif defined(TARGET_AARCH64)
> > +    return (sp - frame_size) & ~15;
> > +#else
> > +    return sp - frame_size;
> > +#endif
>
> We don't need to do it in this patchseries, but you should strongly
> consider pulling the architecture-specifics out in a way that
> avoids this kind of ifdef ladder.
>

Totally agreed. I debated fixing this before I started this patch
run, but I decided to pick my battles... I'll fix this in a follow up.


> > +}
> > +
> > +/* compare to mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c
> sendsig() */
>

Two dead architectures... I've updated the comments...  and the filename
which
they live in...


> > +static void setup_frame(int sig, int code, struct target_sigaction *ka,
> > +    target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *regs)
> > +{
> > +    struct target_sigframe *frame;
> > +    abi_ulong frame_addr;
> > +    int i;
> > +
> > +    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
> > +    trace_user_setup_frame(regs, frame_addr);
> > +    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
> > +        goto give_sigsegv;
>
> FreeBSD for Arm (haven't checked other BSDs or other archs)
> gives a SIGILL for the "can't write signal frame to stack"
> case, I think:
>
> https://github.com/freebsd/freebsd-src/blob/main/sys/arm/arm/exec_machdep.c#L316
> I don't understand why they picked SIGILL, SIGSEGV seems much more
> logical to me, but we should follow the kernel behaviour.
>

This is a good thing to find. I'm going to have to study all the
architectures, but
the first 5 I looked at all returned SIGILL, so this code has to change to
reflect
that...


> > +    }
> > +
> > +    memset(frame, 0, sizeof(*frame));
> > +#if defined(TARGET_MIPS)
> > +    int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC :
> > +        TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC;
> > +#else
> > +    int mflags = 0;
> > +#endif
> > +    if (get_mcontext(regs, &frame->sf_uc.uc_mcontext, mflags)) {
> > +        goto give_sigsegv;
>
> The FreeBSD kernel get_mcontext() can't fail -- why can ours ?
> (This matters because SIGSEGV may not be the right response to
> whatever the failure case is.)
>

    if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size !=
sizeof(target_mcontext_vfp_t)) {

is what I try to validate, but looking at the kernel code it does NOT
return vfp, so that
check is bogus. I need to remove it (I'd added as part of a prior review
without fully
checking before I made the change, to be honest).


> > +    }
> > +
> > +    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
> > +        if (__put_user(set->__bits[i],
> &frame->sf_uc.uc_sigmask.__bits[i])) {
> > +            goto give_sigsegv;
>
> __get_user() and __put_user() in QEMU can't fail, so you don't
> need to check for errors here, unlike the non-double-underscore
> versions. At some point you might want to take the current linux-user
> versions of these user-access functions/macros: it looks like bsd-user
> has an older version which doesn't handle the case where the guest
> has looser alignment restrictions than the host. The new ones
> actually expand to do { ... } while(0) statements which won't
> be valid inside an if() condition.
>

OK. I'll make a sweep in addition to fixing this.


> (Historical note: the reason QEMU's __put_user/__get_user ever had
> return values at all is that the linux-user code was copy-and-pasted
> from the Linux kernel. In the Linux kernel handling of writing
> data to userspace is/was error-checked on every write, whereas
> QEMU does the "is this writable" test once with the lock_user
> function and then can assume all the writes to that area succeed.
> But we still started with a lot of copy-pasted code that was doing
> unnecessary checks on __put_user and __get_user return values.
> FreeBSD seems to handle write-checking in yet a third way, by
> assembling the struct in kernel-space and checking for writability
> once at the end when it copies the whole block out to userspace.)
>

We're nothing if not creative... But this is old school Unix which started
doing this in V7 which started doing it for stat and ftime system calls...


> > +        }
> > +    }
> > +
> > +    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;
> > +
> > +        if (TARGET_SIGILL == sig || TARGET_SIGFPE == sig ||
> > +                TARGET_SIGSEGV == sig || TARGET_SIGBUS == sig ||
> > +                TARGET_SIGTRAP == sig) {
> > +            frame->sf_si._reason._fault._trapno =
> tinfo->_reason._fault._trapno;
> > +        }
> > +
> > +        /*
> > +         * If si_code is one of SI_QUEUE, SI_TIMER, SI_ASYNCIO, or
> > +         * SI_MESGQ, then si_value contains the application-specified
> > +         * signal value. Otherwise, the contents of si_value are
> > +         * undefined.
> > +         */
> > +        if (SI_QUEUE == code || SI_TIMER == code || SI_ASYNCIO == code
> ||
> > +                SI_MESGQ == code) {
> > +            frame->sf_si.si_value.sival_int = tinfo->si_value.sival_int;
> > +        }
> > +
> > +        if (SI_TIMER == code) {
> > +            frame->sf_si._reason._timer._timerid =
> > +                tinfo->_reason._timer._timerid;
> > +            frame->sf_si._reason._timer._overrun =
> > +                tinfo->_reason._timer._overrun;
> > +        }
> > +
> > +#ifdef SIGPOLL
> > +        if (SIGPOLL == sig) {
> > +            frame->sf_si._reason._band = tinfo->_reason._band;
> > +        }
> > +#endif
>
> This seems to be yet a third set of the logic for handling
> target_siginfo_t's union, to go along with tswap_siginfo() and
> host_to_target_siginfo_noswap(), except that the logic here is
> different. linux-user calls tswap_siginfo() in its signal-frame
> setup code.
>

Yea, I need to get that sorted out as well.. It's my biggest remaining
item to resolve (except maybe for the comments for do_* you made,
I've not yet completely digested them when I saw they were more
than reviewed by).


> > +
> > +    }
> > +
> > +    if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) {
> > +        goto give_sigsegv;
> > +    }
>
> set_sigtramp_args() can't fail. (Not sure why it has a non-void
> return type.)
>

OK. I'll fix this as well.


> > +
> > +    unlock_user_struct(frame, frame_addr, 1);
> > +    return;
> > +
> > +give_sigsegv:
> > +    unlock_user_struct(frame, frame_addr, 1);
> > +    force_sig(TARGET_SIGSEGV);
> > +}
> > +
> >  void signal_init(void)
> >  {
> >      TaskState *ts = (TaskState *)thread_cpu->opaque;
> > --
> > 2.33.1
>
> thanks
>

No, thank you. This is quite helpful and got me to look at a number of new
places and understand some historic background.

Warmer -- PMM

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

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

* Re: [PATCH 24/30] bsd-user/signal.c: setup_frame
  2022-01-17  6:58     ` Warner Losh
@ 2022-01-17  7:24       ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-17  7:24 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Sun, Jan 16, 2022 at 11:58 PM Warner Losh <imp@bsdimp.com> wrote:

> > +    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
>> > +        goto give_sigsegv;
>>
>> FreeBSD for Arm (haven't checked other BSDs or other archs)
>> gives a SIGILL for the "can't write signal frame to stack"
>> case, I think:
>>
>> https://github.com/freebsd/freebsd-src/blob/main/sys/arm/arm/exec_machdep.c#L316
>> I don't understand why they picked SIGILL, SIGSEGV seems much more
>> logical to me, but we should follow the kernel behaviour.
>>
>
> This is a good thing to find. I'm going to have to study all the
> architectures, but
> the first 5 I looked at all returned SIGILL, so this code has to change to
> reflect
> that...
>

Sorry to follow up my own message, but  this dates to 4.1BSD (4BSD sent a
SIGKILL),
but it's not present in V7, 32V or 3BSD.

So it's very old-school BSD behavior, dating from 1981 :)

Warner

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

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

* Re: [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal
  2022-01-13 20:37   ` Peter Maydell
@ 2022-01-17 16:22     ` Warner Losh
  2022-01-17 16:33       ` Peter Maydell
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-17 16:22 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 1:37 PM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:51, Warner Losh <imp@bsdimp.com> wrote:
> >
> > Fill in queue signal implementation, as well as routines allocate and
> > delete elements of the signal queue.
>
> See reply to patch 18 for why you probably don't want to do this.
>

I've kept the former bits (implementing queue_signal() function), but
removed
the rest.


> > Signed-off-by: Stacey Son <sson@FreeBSD.org>
> > Signed-off-by: Kyle Evans <kevans@freebsd.org>
> > Signed-off-by: Warner Losh <imp@bsdimp.com>
> > ---
>
>
> > +    /*
> > +     * FreeBSD signals are always queued.  Linux only queues real time
> signals.
> > +     * XXX this code is not thread safe.  "What lock protects
> ts->sigtab?"
> > +     */
>
> ts->sigtab shouldn't need a lock, because it is per-thread,
> like all of TaskState. (The TaskState structure is pointed
> to by the CPUState 'opaque' field. CPUStates are per-thread;
> the TaskState for a new thread's new CPUState is allocated
> and initialized as part of the emulating of whatever the
> "create new thread" syscall is. For Linux this is in
> do_fork() for the CLONE_VM case. The TaskState for the
> initial thread is allocated in main.c.) We do need to deal
> with the fact that ts->sigtab can be updated by a signal
> handler (which always runs in the thread corresponding to
> that guest CPU): the linux-user process_pending_signals()
> has been written with that in mind.
>

Gotcha. That makes sense. Any reason that atomics aren't used
for this between the different routines?

Warner

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

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

* Re: [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal
  2022-01-17 16:22     ` Warner Losh
@ 2022-01-17 16:33       ` Peter Maydell
  0 siblings, 0 replies; 105+ messages in thread
From: Peter Maydell @ 2022-01-17 16:33 UTC (permalink / raw)
  To: Warner Losh; +Cc: Kyle Evans, Stacey Son, QEMU Developers

On Mon, 17 Jan 2022 at 16:22, Warner Losh <imp@bsdimp.com> wrote:
> On Thu, Jan 13, 2022 at 1:37 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>> > +    /*
>> > +     * FreeBSD signals are always queued.  Linux only queues real time signals.
>> > +     * XXX this code is not thread safe.  "What lock protects ts->sigtab?"
>> > +     */
>>
>> ts->sigtab shouldn't need a lock, because it is per-thread,
>> like all of TaskState. (The TaskState structure is pointed
>> to by the CPUState 'opaque' field. CPUStates are per-thread;
>> the TaskState for a new thread's new CPUState is allocated
>> and initialized as part of the emulating of whatever the
>> "create new thread" syscall is. For Linux this is in
>> do_fork() for the CLONE_VM case. The TaskState for the
>> initial thread is allocated in main.c.) We do need to deal
>> with the fact that ts->sigtab can be updated by a signal
>> handler (which always runs in the thread corresponding to
>> that guest CPU): the linux-user process_pending_signals()
>> has been written with that in mind.
>
>
> Gotcha. That makes sense. Any reason that atomics aren't used
> for this between the different routines?

We use atomics in some places, eg the qatomic_read()/qatomic_set()
of ts->signal_pending in process_pending_signals. We deal with
some other races by blocking signals. sigtab's a cmplex
data structure, so simply making accesses to its individual
fields atomic isn't sufficient, and the more usual approach of
taking a lock doesn't work when the thing being protected against
is code running in a signal handler.

It's also quite possible that we missed some places
where we should be being stricter about using the atomic
accessors -- if you spot anything like that let us know.

thanks
-- PMM


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

* Re: [PATCH 21/30] bsd-user/signal.c: force_sig
  2022-01-13 23:04       ` Kyle Evans
@ 2022-01-18 22:27         ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-18 22:27 UTC (permalink / raw)
  To: Kyle Evans; +Cc: Peter Maydell, Stacey Son, QEMU Developers

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

On Thu, Jan 13, 2022 at 4:04 PM Kyle Evans <kevans@freebsd.org> wrote:

> On Thu, Jan 13, 2022 at 2:53 PM Peter Maydell <peter.maydell@linaro.org>
> wrote:
> >
> > On Thu, 13 Jan 2022 at 20:29, Peter Maydell <peter.maydell@linaro.org>
> wrote:
> > >
> > > On Sun, 9 Jan 2022 at 16:44, Warner Losh <imp@bsdimp.com> wrote:
> > > >
> > > > Force delivering a signal and generating a core file.
> >
> > > > +/* Abort execution with signal. */
> > > > +void QEMU_NORETURN force_sig(int target_sig)
> > >
> > > In linux-user we call this dump_core_and_abort(), which is
> > > a name that better describes what it's actually doing.
> > >
> > > (Today's linux-user's force_sig() does what the Linux kernel's
> > > function of that name does -- it's a wrapper around
> > > queue_signal() which delivers a signal to the guest with
> > > .si_code = SI_KERNEL , si_pid = si_uid = 0.
> > > Whether you want one of those or not depends on what BSD
> > > kernels do in that kind of "we have to kill this process"
> > > situation.)
> >
> > It looks like the FreeBSD kernel uses sigexit() as its equivalent
> > function to Linux's force_sig(), incidentally. Not sure if
> > you/we would prefer the bsd-user code to follow the naming that
> > FreeBSD's kernel uses or the naming linux-user takes from
> > the Linux kernel.
> >
>
> My $.02: let's go with linux-inherited linux-user names and drop in a
> comment with the FreeBSD name, if they're functionally similar enough
> (in general, not just for this specific case). My gut feeling is that
> it'll be more useful in the long run if we can more quickly identify
> parallels between the two, so changes affecting linux-user that may
> benefit bsd-user are more easily identified and exchanged (and
> vice-versa).
>

OK. I've updated the patches to do the renaming. There was  one bad call
to force_sig (do_sigreturn should just return EFAULT instead of generating
a core). I've also fixed the SIGILL on BSD as well. The rest all look like
they
should be renamed. None look like they were copied from linux-user and
should
be the linux version :).

Warner

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

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

* Re: [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines.
  2022-01-14 11:13   ` Peter Maydell
@ 2022-01-22 16:44     ` Warner Losh
  2022-01-22 18:00       ` Kyle Evans
  0 siblings, 1 reply; 105+ messages in thread
From: Warner Losh @ 2022-01-22 16:44 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Fri, Jan 14, 2022 at 4:14 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 16:53, Warner Losh <imp@bsdimp.com> wrote:
> >
> > target_sigemptyset: resets a set to having no bits set
> > qemu_sigorset:      computes the or of two sets
> > 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/qemu.h   |  3 ++
> >  bsd-user/signal.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 92 insertions(+)
> >
> > diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> > index e12617f5d69..e8c417c7c33 100644
> > --- a/bsd-user/qemu.h
> > +++ b/bsd-user/qemu.h
> > @@ -223,7 +223,10 @@ 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);
> >  int target_to_host_signal(int sig);
> >  int host_to_target_signal(int sig);
> > +void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
> > +void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
> >  void QEMU_NORETURN force_sig(int target_sig);
> > +int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t
> *right);
> >
> >  /* mmap.c */
> >  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index 93c3b3c5033..8dadc9a39a7 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);
> > +
> >
> >  int host_to_target_signal(int sig)
> >  {
> > @@ -43,6 +46,44 @@ int target_to_host_signal(int sig)
> >      return sig;
> >  }
> >
> > +static inline void target_sigemptyset(target_sigset_t *set)
> > +{
> > +    memset(set, 0, sizeof(*set));
> > +}
> > +
> > +#include <signal.h>
>
> Don't include system headers halfway through the file like this,
> please : put the #include at the top of the file with the others.
>

Yea, this isn't even needed, so I just removed it.


> > +
> > +int
> > +qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t
> *right)
> > +{
> > +    sigset_t work;
> > +    int i;
> > +
> > +    sigemptyset(&work);
> > +    for (i = 1; i < NSIG; ++i) {
> > +        if (sigismember(left, i) || sigismember(right, i)) {
> > +            sigaddset(&work, i);
> > +        }
> > +    }
> > +
> > +    *dest = work;
> > +    return 0;
> > +}
>
> FreeBSD's manpage says it has a native sigorset() --
>
> https://www.freebsd.org/cgi/man.cgi?query=sigemptyset&sektion=3&apropos=0&manpath=freebsd
> can you just use that ?
>

Yes.


> > +
> > +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)
> >  {
> > @@ -55,6 +96,54 @@ static inline void rewind_if_in_safe_syscall(void
> *puc)
> >      }
> >  }
> >
> > +static void host_to_target_sigset_internal(target_sigset_t *d,
> > +        const sigset_t *s)
> > +{
> > +    int i;
> > +
> > +    target_sigemptyset(d);
> > +    for (i = 1; i <= TARGET_NSIG; i++) {
>
> i here is iterating through host signal numbers, not target
> numbers, so TARGET_NSIG isn't the right upper bound.
> On Linux we iterate from 1 to _NSIG-1; on BSD I think
> you may want (i = 0; i < NSIG; i++), but you should check that.
>

You're correct. The values are the same, but logically NSIG is more correct.


> > +        if (sigismember(s, i)) {
> > +            target_sigaddset(d, host_to_target_signal(i));
> > +        }
> > +    }
> > +}
>
> These functions are a little odd when you compare them to their
> linux-user equivalents, because they're both written
> with a sort of abstraction between host and target signal
> numbers (they call host_to_target_signal() and
> target_to_host_signal()) but also written with baked-in
> assumptions that the mapping is basically 1:1 (they don't
> have the code that handles the possibility that the
> target signal isn't representable as a host signal or
> vice-versa). But assuming the BSDs don't change their
> signal numbering across architectures, this is fine.
>

I can assume that, at least for now, so I've just added a comment
about that.

Warner

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

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

* Re: [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines.
  2022-01-22 16:44     ` Warner Losh
@ 2022-01-22 18:00       ` Kyle Evans
  0 siblings, 0 replies; 105+ messages in thread
From: Kyle Evans @ 2022-01-22 18:00 UTC (permalink / raw)
  To: Warner Losh; +Cc: Peter Maydell, Stacey Son, QEMU Developers

On Sat, Jan 22, 2022 at 10:44 AM Warner Losh <imp@bsdimp.com> wrote:
>
>
>
> On Fri, Jan 14, 2022 at 4:14 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On Sun, 9 Jan 2022 at 16:53, Warner Losh <imp@bsdimp.com> wrote:
>> >
>> > target_sigemptyset: resets a set to having no bits set
>> > qemu_sigorset:      computes the or of two sets
>> > 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/qemu.h   |  3 ++
>> >  bsd-user/signal.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
>> >  2 files changed, 92 insertions(+)
>> >
>> > diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
>> > index e12617f5d69..e8c417c7c33 100644
>> > --- a/bsd-user/qemu.h
>> > +++ b/bsd-user/qemu.h
>> > @@ -223,7 +223,10 @@ 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);
>> >  int target_to_host_signal(int sig);
>> >  int host_to_target_signal(int sig);
>> > +void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
>> > +void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
>> >  void QEMU_NORETURN force_sig(int target_sig);
>> > +int qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right);
>> >
>> >  /* mmap.c */
>> >  int target_mprotect(abi_ulong start, abi_ulong len, int prot);
>> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
>> > index 93c3b3c5033..8dadc9a39a7 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);
>> > +
>> >
>> >  int host_to_target_signal(int sig)
>> >  {
>> > @@ -43,6 +46,44 @@ int target_to_host_signal(int sig)
>> >      return sig;
>> >  }
>> >
>> > +static inline void target_sigemptyset(target_sigset_t *set)
>> > +{
>> > +    memset(set, 0, sizeof(*set));
>> > +}
>> > +
>> > +#include <signal.h>
>>
>> Don't include system headers halfway through the file like this,
>> please : put the #include at the top of the file with the others.
>
>
> Yea, this isn't even needed, so I just removed it.
>
>>
>> > +
>> > +int
>> > +qemu_sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
>> > +{
>> > +    sigset_t work;
>> > +    int i;
>> > +
>> > +    sigemptyset(&work);
>> > +    for (i = 1; i < NSIG; ++i) {
>> > +        if (sigismember(left, i) || sigismember(right, i)) {
>> > +            sigaddset(&work, i);
>> > +        }
>> > +    }
>> > +
>> > +    *dest = work;
>> > +    return 0;
>> > +}
>>
>> FreeBSD's manpage says it has a native sigorset() --
>> https://www.freebsd.org/cgi/man.cgi?query=sigemptyset&sektion=3&apropos=0&manpath=freebsd
>> can you just use that ?
>
>
> Yes.
>

For some added context, I added sigorset() to libc after 11.3/12.1 in
response to bsd-user using it, then forgot to remove the transition
aide after they went EoL.

Thanks,

Kyle Evans


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

* Re: [PATCH 30/30] bsd-user/signal.c: do_sigaltstack
  2022-01-14 13:18   ` Peter Maydell
@ 2022-01-22 22:20     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-22 22:20 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Fri, Jan 14, 2022 at 6:18 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Sun, 9 Jan 2022 at 17:08, Warner Losh <imp@bsdimp.com> wrote:
> >
> > Implement the meat of the sigaltstack(2) system call with do_sigaltstack.
> >
> > 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 | 66 +++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 67 insertions(+)
> >
> > diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> > index c643d6ba246..fcdea460ed2 100644
> > --- a/bsd-user/qemu.h
> > +++ b/bsd-user/qemu.h
> > @@ -226,6 +226,7 @@ int host_to_target_signal(int sig);
> >  void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
> >  void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
> >  long do_sigreturn(CPUArchState *regs, abi_ulong addr);
> > +abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
> abi_ulong sp);
> >  int do_sigaction(int sig, const struct target_sigaction *act,
> >                  struct target_sigaction *oact);
> >  void QEMU_NORETURN force_sig(int target_sig);
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index f055d1db407..e5e5e28c60c 100644
> > --- a/bsd-user/signal.c
> > +++ b/bsd-user/signal.c
> > @@ -528,6 +528,72 @@ 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)
> > +{
> > +    int ret;
> > +    target_stack_t oss;
> > +
> > +    if (uoss_addr) {
> > +        /* Save current signal stack params */
> > +        oss.ss_sp = tswapl(target_sigaltstack_used.ss_sp);
> > +        oss.ss_size = tswapl(target_sigaltstack_used.ss_size);
> > +        oss.ss_flags = tswapl(sas_ss_flags(sp));
> > +    }
>
> This will need some minor changes to work with the sigaltstack
> info being per-thread and in the TaskState struct.
>

Yes. Moving it into the TaskState was easy and got rid if the global.
Thanks for that suggestion earlier in the patch series.

Warrner

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

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

* Re: [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user
  2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
  2022-01-13 15:47   ` Peter Maydell
@ 2022-01-23 21:30   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 21:30 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:18 AM, Warner Losh wrote:
> Move the EXCP_ATOMIC case to match linux-user/arm/cpu_loop.c:cpu_loop
> ordering.
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/arm/target_arch_cpu.h | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)

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

r~


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

* Re: [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault
  2022-01-09 16:18 ` [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault Warner Losh
  2022-01-13 16:43   ` Peter Maydell
@ 2022-01-23 21:36   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 21:36 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:18 AM, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal-common.h | 14 ++++++++++++++
>   bsd-user/signal.c        | 18 ++++++++++++++++++
>   2 files changed, 32 insertions(+)
>   create mode 100644 bsd-user/signal-common.h

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

r~


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

* Re: [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv
  2022-01-09 16:18 ` [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
  2022-01-13 17:00   ` Peter Maydell
@ 2022-01-23 21:38   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 21:38 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:18 AM, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 15 ++++++++++++---
>   1 file changed, 12 insertions(+), 3 deletions(-)

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

r~


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

* Re: [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus
  2022-01-09 16:18 ` [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
  2022-01-13 17:00   ` Peter Maydell
@ 2022-01-23 21:38   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 21:38 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:18 AM, Warner Losh wrote:
> 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>
> ---
>   bsd-user/signal.c | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)

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

r~


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

* Re: [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together
  2022-01-09 16:18 ` [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
  2022-01-13 17:13   ` Peter Maydell
@ 2022-01-23 21:40   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 21:40 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:18 AM, Warner Losh wrote:
> 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).
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/arm/target_arch_cpu.h | 23 +++--------------------
>   1 file changed, 3 insertions(+), 20 deletions(-)

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

r~


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

* Re: [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer
  2022-01-09 16:18 ` [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
  2022-01-13 17:15   ` Peter Maydell
@ 2022-01-23 21:43   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 21:43 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:18 AM, Warner Losh wrote:
> The code has moved in FreeBSD since the emulator was started, update the
> comment to reflect that change. Remove now-redundant comment saying the
> same thing (but incorrectly).
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/arm/target_arch_cpu.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

With commit message updated, as discussed upthread,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF
  2022-01-13 17:19   ` Peter Maydell
@ 2022-01-23 22:07     ` Richard Henderson
  0 siblings, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-23 22:07 UTC (permalink / raw)
  To: Peter Maydell, Warner Losh; +Cc: Kyle Evans, qemu-devel

On 1/14/22 4:19 AM, Peter Maydell wrote:
> On Sun, 9 Jan 2022 at 16:27, Warner Losh <imp@bsdimp.com> wrote:
>>
>> 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.
>>
>> Signed-off-by: Warner Losh <imp@bsdimp.com>
>> ---
>>   bsd-user/arm/target_arch_cpu.h | 18 ++++++------------
>>   1 file changed, 6 insertions(+), 12 deletions(-)
>>
>> diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
>> index 905f13aa1b9..996a361e3fe 100644
>> --- a/bsd-user/arm/target_arch_cpu.h
>> +++ b/bsd-user/arm/target_arch_cpu.h
>> @@ -51,18 +51,12 @@ 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();
>> +             */
>> +            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->regs[15]);
>>               break;
> 
> Do you want to keep the TODO comment ?
> 
> Either way,
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 
> (Looks like FreeBSD sends SIGILL/ILL_ILLADR for UNDEF where the PC
> is misaligned and we're not in Thumb mode, but that's a pretty oddball
> corner case so not really worth emulating.)

For qemu, that case will never happen: we'll raise EXCP_PREFETCH_ABORT with fsr=1 
(Alignment).  The freebsd kernel might have this code because the behaviour with real hw 
is CONSTRAINED UNPREDICTABLE (iirc).

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

r~


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

* Re: [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults
  2022-01-09 16:19 ` [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
  2022-01-13 17:40   ` Peter Maydell
@ 2022-01-24  1:12   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  1:12 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:19 AM, Warner Losh wrote:
> Update for the richer set of data faults that are now possible. Copied
> largely from linux-user/arm/cpu_loop.c
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/arm/target_arch_cpu.h | 44 ++++++++++++++++++++++++++--------
>   1 file changed, 34 insertions(+), 10 deletions(-)

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

r~


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

* Re: [PATCH 10/30] bsd-user/signal.c: Implement signal_init()
  2022-01-09 16:19 ` [PATCH 10/30] bsd-user/signal.c: Implement signal_init() Warner Losh
  2022-01-13 19:28   ` Peter Maydell
@ 2022-01-24  1:38   ` Richard Henderson
  2022-01-24 21:35     ` Warner Losh
  1 sibling, 1 reply; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  1:38 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:19 AM, Warner Losh wrote:
> 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>
> ---
>   bsd-user/qemu.h   |  1 +
>   bsd-user/signal.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 69 insertions(+)
> 
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 334f8b1d715..0e0b8db708b 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -97,6 +97,7 @@ typedef struct TaskState {
>       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 */
> +    sigset_t signal_mask;
>   
>       uint8_t stack[];
>   } __attribute__((aligned(16))) TaskState;
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 7ea86149981..b2c91c39379 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);
> +
>   int host_to_target_signal(int sig)
>   {
>       return sig;
> @@ -47,6 +50,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().
> @@ -64,8 +89,51 @@ 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);
> +
> +    /*
> +     * Set all host signal handlers. ALL signals are blocked during the
> +     * handlers to serialize them.
> +     */
> +    memset(sigact_table, 0, sizeof(sigact_table));
> +
> +    sigfillset(&act.sa_mask);
> +    act.sa_sigaction = host_signal_handler;
> +    act.sa_flags = SA_SIGINFO;
> +
> +    for (i = 1; i <= TARGET_NSIG; i++) {
> +        host_sig = target_to_host_signal(i);
> +        sigaction(host_sig, NULL, &oact);

Missing test for CONFIG_GPROF + SIGPROF.  Otherwise,

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

r~


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

* Re: [PATCH 12/30] bsd-user/host/i386/host-signal.h: Implement host_signal_*
  2022-01-09 16:19 ` [PATCH 12/30] bsd-user/host/i386/host-signal.h: " Warner Losh
  2022-01-13 19:33   ` Peter Maydell
@ 2022-01-24  1:49   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  1:49 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:19 AM, Warner Losh wrote:
> 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>
> ---
>   bsd-user/host/i386/host-signal.h | 37 ++++++++++++++++++++++++++++++++
>   1 file changed, 37 insertions(+)
>   create mode 100644 bsd-user/host/i386/host-signal.h

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

r~


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

* Re: [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*
  2022-01-09 16:19 ` [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: " Warner Losh
  2022-01-13 19:33   ` Peter Maydell
@ 2022-01-24  1:52   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  1:52 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:19 AM, Warner Losh wrote:
> 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>
> ---
>   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

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

r~


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

* Re: [PATCH 14/30] bsd-user: Add host signals to the build
  2022-01-09 16:19 ` [PATCH 14/30] bsd-user: Add host signals to the build Warner Losh
  2022-01-13 19:35   ` Peter Maydell
@ 2022-01-24  1:56   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  1:56 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:19 AM, Warner Losh wrote:
> Start to add the host signal functionality to the build.
> 
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/meson.build | 1 +
>   bsd-user/signal.c    | 1 +
>   meson.build          | 1 +
>   3 files changed, 3 insertions(+)

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

r~


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

* Re: [PATCH 15/30] bsd-user: Add trace events for bsd-usr
  2022-01-09 16:19 ` [PATCH 15/30] bsd-user: Add trace events for bsd-usr Warner Losh
  2022-01-13 19:37   ` Peter Maydell
@ 2022-01-24  1:57   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  1:57 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:19 AM, Warner Losh wrote:
> 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>
> ---
>   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

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

r~


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

* Re: [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-09 16:19 ` [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
  2022-01-13 19:43   ` Peter Maydell
@ 2022-01-24  2:05   ` Richard Henderson
  2022-01-24 21:45     ` Warner Losh
  1 sibling, 1 reply; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  2:05 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:19 AM, Warner Losh wrote:
> +static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
> +        const siginfo_t *info)
> +{
> +    int sig, code;
> +
> +    sig = host_to_target_signal(info->si_signo);

You now have a target signo, so...

> +    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig ||
> +            SIGTRAP == sig) {

... you need TARGET_SIGFOO in the comparision.

Though, really, I think the categorization that Peter suggested is a better way to 
structure this.


r~


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

* Re: [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall
  2022-01-09 16:19 ` [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
  2022-01-13 19:44   ` Peter Maydell
@ 2022-01-24  2:09   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  2:09 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans

On 1/10/22 3:19 AM, Warner Losh wrote:
> Signed-off-by: Kyle Evans<kevans@freebsd.org>
> Signed-off-by: Warner Losh<imp@bsdimp.com>
> ---
>   bsd-user/qemu.h   |  2 ++
>   bsd-user/signal.c | 12 ++++++++++++
>   2 files changed, 14 insertions(+)

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

r~


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

* Re: [PATCH 19/30] bsd-user/strace.c: print_taken_signal
  2022-01-09 16:19 ` [PATCH 19/30] bsd-user/strace.c: print_taken_signal Warner Losh
  2022-01-13 20:20   ` Peter Maydell
@ 2022-01-24  2:45   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  2:45 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:19 AM, Warner Losh wrote:
> 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>
> ---
>   bsd-user/qemu.h   | 10 +++++
>   bsd-user/strace.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 107 insertions(+)

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

r~


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

* Re: [PATCH 20/30] bsd-user/signal.c: core_dump_signal
  2022-01-09 16:19 ` [PATCH 20/30] bsd-user/signal.c: core_dump_signal Warner Losh
  2022-01-13 20:22   ` Peter Maydell
@ 2022-01-24  3:01   ` Richard Henderson
  1 sibling, 0 replies; 105+ messages in thread
From: Richard Henderson @ 2022-01-24  3:01 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: Kyle Evans, Stacey Son

On 1/10/22 3:19 AM, Warner Losh wrote:
> Returns 1 for signals that cause core files.
> 
> 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 | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)

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

r~


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

* Re: [PATCH 10/30] bsd-user/signal.c: Implement signal_init()
  2022-01-24  1:38   ` Richard Henderson
@ 2022-01-24 21:35     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-24 21:35 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Sun, Jan 23, 2022 at 6:38 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/10/22 3:19 AM, Warner Losh wrote:
> > 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>
> > ---
> >   bsd-user/qemu.h   |  1 +
> >   bsd-user/signal.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
> >   2 files changed, 69 insertions(+)
> >
> > diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> > index 334f8b1d715..0e0b8db708b 100644
> > --- a/bsd-user/qemu.h
> > +++ b/bsd-user/qemu.h
> > @@ -97,6 +97,7 @@ typedef struct TaskState {
> >       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 */
> > +    sigset_t signal_mask;
> >
> >       uint8_t stack[];
> >   } __attribute__((aligned(16))) TaskState;
> > diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> > index 7ea86149981..b2c91c39379 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);
> > +
> >   int host_to_target_signal(int sig)
> >   {
> >       return sig;
> > @@ -47,6 +50,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().
> > @@ -64,8 +89,51 @@ 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);
> > +
> > +    /*
> > +     * Set all host signal handlers. ALL signals are blocked during the
> > +     * handlers to serialize them.
> > +     */
> > +    memset(sigact_table, 0, sizeof(sigact_table));
> > +
> > +    sigfillset(&act.sa_mask);
> > +    act.sa_sigaction = host_signal_handler;
> > +    act.sa_flags = SA_SIGINFO;
> > +
> > +    for (i = 1; i <= TARGET_NSIG; i++) {
> > +        host_sig = target_to_host_signal(i);
> > +        sigaction(host_sig, NULL, &oact);
>
> Missing test for CONFIG_GPROF + SIGPROF.  Otherwise,
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>

Gotcha. Will add.

Warner

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

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

* Re: [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap
  2022-01-24  2:05   ` Richard Henderson
@ 2022-01-24 21:45     ` Warner Losh
  0 siblings, 0 replies; 105+ messages in thread
From: Warner Losh @ 2022-01-24 21:45 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Kyle Evans, Stacey Son, QEMU Developers

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

On Sun, Jan 23, 2022 at 7:05 PM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 1/10/22 3:19 AM, Warner Losh wrote:
> > +static inline void host_to_target_siginfo_noswap(target_siginfo_t
> *tinfo,
> > +        const siginfo_t *info)
> > +{
> > +    int sig, code;
> > +
> > +    sig = host_to_target_signal(info->si_signo);
>
> You now have a target signo, so...
>
> > +    if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS ==
> sig ||
> > +            SIGTRAP == sig) {
>
> ... you need TARGET_SIGFOO in the comparision.
>
> Though, really, I think the categorization that Peter suggested is a
> better way to
> structure this.
>

How about both? Both is good? I've reworked based on Peter's suggestion, but
still have a need to be careful about target vs host signal numbers.
Thanks! I'd overlooked it.

Warner

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

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

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

Thread overview: 105+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-09 16:18 [PATCH 00/30] bsd-user: upstream our signal implementation Warner Losh
2022-01-09 16:18 ` [PATCH 01/30] bsd-user/arm/target_arch_cpu.h: Move EXCP_ATOMIC to match linux-user Warner Losh
2022-01-13 15:47   ` Peter Maydell
2022-01-23 21:30   ` Richard Henderson
2022-01-09 16:18 ` [PATCH 02/30] bsd-user/signal.c: implement force_sig_fault Warner Losh
2022-01-13 16:43   ` Peter Maydell
2022-01-23 21:36   ` Richard Henderson
2022-01-09 16:18 ` [PATCH 03/30] bsd-user/signal.c: Implement cpu_loop_exit_sigsegv Warner Losh
2022-01-13 17:00   ` Peter Maydell
2022-01-23 21:38   ` Richard Henderson
2022-01-09 16:18 ` [PATCH 04/30] bsd-user/signal.c: implement cpu_loop_exit_sigbus Warner Losh
2022-01-13 17:00   ` Peter Maydell
2022-01-23 21:38   ` Richard Henderson
2022-01-09 16:18 ` [PATCH 05/30] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together Warner Losh
2022-01-13 17:13   ` Peter Maydell
2022-01-14  6:33     ` Warner Losh
2022-01-23 21:40   ` Richard Henderson
2022-01-09 16:18 ` [PATCH 06/30] bsd-user/arm/target_arch_cpu.h: Correct code pointer Warner Losh
2022-01-13 17:15   ` Peter Maydell
2022-01-14  6:38     ` Warner Losh
2022-01-14 10:22       ` Peter Maydell
2022-01-17  4:12         ` Warner Losh
2022-01-23 21:43   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 07/30] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF Warner Losh
2022-01-13 17:19   ` Peter Maydell
2022-01-23 22:07     ` Richard Henderson
2022-01-09 16:19 ` [PATCH 08/30] bsd-user/arm/target_arch_cpu.h: Implement data faults Warner Losh
2022-01-13 17:40   ` Peter Maydell
2022-01-14 18:13     ` Warner Losh
2022-01-14 18:21       ` Peter Maydell
2022-01-24  1:12   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 09/30] bsd-user/signal.c: implement abstract target / host signal translation Warner Losh
2022-01-13 17:44   ` Peter Maydell
2022-01-14 18:27     ` Warner Losh
2022-01-09 16:19 ` [PATCH 10/30] bsd-user/signal.c: Implement signal_init() Warner Losh
2022-01-13 19:28   ` Peter Maydell
2022-01-14 18:51     ` Warner Losh
2022-01-24  1:38   ` Richard Henderson
2022-01-24 21:35     ` Warner Losh
2022-01-09 16:19 ` [PATCH 11/30] bsd-user/host/arm/host-signal.h: Implement host_signal_* Warner Losh
2022-01-13 19:32   ` Peter Maydell
2022-01-17  3:53     ` Warner Losh
2022-01-09 16:19 ` [PATCH 12/30] bsd-user/host/i386/host-signal.h: " Warner Losh
2022-01-13 19:33   ` Peter Maydell
2022-01-24  1:49   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: " Warner Losh
2022-01-13 19:33   ` Peter Maydell
2022-01-24  1:52   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 14/30] bsd-user: Add host signals to the build Warner Losh
2022-01-13 19:35   ` Peter Maydell
2022-01-24  1:56   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 15/30] bsd-user: Add trace events for bsd-usr Warner Losh
2022-01-13 19:37   ` Peter Maydell
2022-01-24  1:57   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 16/30] bsd-user/signal.c: host_to_target_siginfo_noswap Warner Losh
2022-01-13 19:43   ` Peter Maydell
2022-01-15  6:19     ` Warner Losh
2022-01-15 11:08       ` Peter Maydell
2022-01-24  2:05   ` Richard Henderson
2022-01-24 21:45     ` Warner Losh
2022-01-09 16:19 ` [PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall Warner Losh
2022-01-13 19:44   ` Peter Maydell
2022-01-24  2:09   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 18/30] bsd-user/signal.c: Implement host_signal_handler Warner Losh
2022-01-13 20:17   ` Peter Maydell
2022-01-16 20:52     ` Warner Losh
2022-01-09 16:19 ` [PATCH 19/30] bsd-user/strace.c: print_taken_signal Warner Losh
2022-01-13 20:20   ` Peter Maydell
2022-01-24  2:45   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 20/30] bsd-user/signal.c: core_dump_signal Warner Losh
2022-01-13 20:22   ` Peter Maydell
2022-01-13 20:28     ` Warner Losh
2022-01-13 20:40       ` Peter Maydell
2022-01-24  3:01   ` Richard Henderson
2022-01-09 16:19 ` [PATCH 21/30] bsd-user/signal.c: force_sig Warner Losh
2022-01-13 20:29   ` Peter Maydell
2022-01-13 20:53     ` Peter Maydell
2022-01-13 23:04       ` Kyle Evans
2022-01-18 22:27         ` Warner Losh
2022-01-09 16:19 ` [PATCH 22/30] bsd-user/signal.c: Fill in queue_signal Warner Losh
2022-01-13 20:37   ` Peter Maydell
2022-01-17 16:22     ` Warner Losh
2022-01-17 16:33       ` Peter Maydell
2022-01-09 16:19 ` [PATCH 23/30] bsd-user/signal.c: sigset manipulation routines Warner Losh
2022-01-14 11:13   ` Peter Maydell
2022-01-22 16:44     ` Warner Losh
2022-01-22 18:00       ` Kyle Evans
2022-01-09 16:19 ` [PATCH 24/30] bsd-user/signal.c: setup_frame Warner Losh
2022-01-14 11:40   ` Peter Maydell
2022-01-17  6:58     ` Warner Losh
2022-01-17  7:24       ` Warner Losh
2022-01-09 16:19 ` [PATCH 25/30] bsd-user/signal.c: handle_pending_signal Warner Losh
2022-01-14 11:50   ` Peter Maydell
2022-01-09 16:19 ` [PATCH 26/30] bsd-user/signal.c: tswap_siginfo Warner Losh
2022-01-14 11:54   ` Peter Maydell
2022-01-09 16:19 ` [PATCH 27/30] bsd-user/signal.c: process_pending_signals Warner Losh
2022-01-14 11:55   ` Peter Maydell
2022-01-17  2:09     ` Warner Losh
2022-01-09 16:19 ` [PATCH 28/30] bsd-user/signal.c: implement do_sigreturn Warner Losh
2022-01-14 12:12   ` Peter Maydell
2022-01-09 16:19 ` [PATCH 29/30] bsd-user/signal.c: implement do_sigaction Warner Losh
2022-01-14 13:13   ` Peter Maydell
2022-01-09 16:19 ` [PATCH 30/30] bsd-user/signal.c: do_sigaltstack Warner Losh
2022-01-14 13:18   ` Peter Maydell
2022-01-22 22:20     ` Warner Losh

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.