All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV
@ 2021-09-18 18:44 Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 01/41] accel/tcg: Split out adjust_signal_pc Richard Henderson
                   ` (41 more replies)
  0 siblings, 42 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Based-on: 20210915174951.1852266-1-richard.henderson@linaro.org
("linux-user/nios2: trap and kuser fixes")

... which itself is

Based-on: 20210813131809.28655-1-peter.maydell@linaro.org
("linux-user: Clean up siginfo_t handling for arm, aarch64")
... for force_sig_fault().

and in turn based on my current tcg-next pull, for has_work changes.

For avoidance of doubt:
https://gitlab.com/rth7680/qemu/-/commits/lu-hostsig-2

Only 4 of 20 targets need any special code for correctly
signalling SIGSEGV, and the host-level code is reduced as well.

Dropped the rfc, but still seeking feedback the factorization.


r~


Richard Henderson (41):
  accel/tcg: Split out adjust_signal_pc
  accel/tcg: Move clear_helper_retaddr to cpu loop
  accel/tcg: Split out handle_sigsegv_accerr_write
  accel/tcg: Fold cpu_exit_tb_from_sighandler into caller
  configure: Merge riscv32 and riscv64 host architectures
  linux-user: Reorg handling for SIGSEGV
  linux-user/host/x86: Populate host_signal.h
  linux-user/host/ppc: Populate host_signal.h
  linux-user/host/alpha: Populate host_signal.h
  linux-user/host/sparc: Populate host_signal.h
  linux-user/host/arm: Populate host_signal.h
  linux-user/host/aarch64: Populate host_signal.h
  linux-user/host/s390: Populate host_signal.h
  linux-user/host/mips: Populate host_signal.h
  linux-user/host/riscv: Populate host_signal.h
  target/arm: Fixup comment re handle_cpu_signal
  linux-user/host/riscv: Improve host_signal_write
  linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER
  hw/core: Add TCGCPUOps.record_sigsegv
  linux-user: Add raise_sigsegv
  target/alpha: Make alpha_cpu_tlb_fill sysemu only
  target/arm: Use raise_sigsegv for mte tag lookup
  target/arm: Implement arm_cpu_record_sigsegv
  target/cris: Make cris_cpu_tlb_fill sysemu only
  target/hexagon: Remove hexagon_cpu_tlb_fill
  target/hppa: Make hppa_cpu_tlb_fill sysemu only
  target/i386: Implement x86_cpu_record_sigsegv
  target/m68k: Make m68k_cpu_tlb_fill sysemu only
  target/microblaze: Make mb_cpu_tlb_fill sysemu only
  target/mips: Make mips_cpu_tlb_fill sysemu only
  target/nios2: Make nios2_cpu_tlb_fill sysemu only
  linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE
  target/openrisc: Make openrisc_cpu_tlb_fill sysemu only
  target/ppc: Implement ppc_cpu_record_sigsegv
  target/riscv: Make riscv_cpu_tlb_fill sysemu only
  target/s390x: Use probe_access_flags in s390_probe_access
  target/s390x: Implement s390_cpu_record_sigsegv
  target/sh4: Make sh4_cpu_tlb_fill sysemu only
  target/sparc: Make sparc_cpu_tlb_fill sysemu only
  target/xtensa: Make xtensa_cpu_tlb_fill sysemu only
  accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu

 configure                                     |   8 +-
 meson.build                                   |   4 +-
 include/exec/exec-all.h                       |  41 +-
 include/hw/core/tcg-cpu-ops.h                 |  48 +-
 linux-user/host/aarch64/host-signal.h         |  73 ++
 linux-user/host/alpha/host-signal.h           |  41 +
 linux-user/host/arm/host-signal.h             |  29 +
 linux-user/host/i386/host-signal.h            |  24 +
 linux-user/host/mips/host-signal.h            |  61 ++
 linux-user/host/ppc/host-signal.h             |  24 +
 linux-user/host/ppc64/host-signal.h           |   1 +
 linux-user/host/riscv/host-signal.h           |  57 ++
 linux-user/host/{riscv64 => riscv}/hostdep.h  |   4 +-
 linux-user/host/riscv32/hostdep.h             |  11 -
 linux-user/host/s390/host-signal.h            |  92 ++
 linux-user/host/s390x/host-signal.h           |   1 +
 linux-user/host/sparc/host-signal.h           |  53 ++
 linux-user/host/sparc64/host-signal.h         |   1 +
 linux-user/host/x32/host-signal.h             |   1 +
 linux-user/host/x86_64/host-signal.h          |  24 +
 target/alpha/cpu.h                            |   7 +-
 target/arm/internals.h                        |   6 +
 target/cris/cpu.h                             |   8 +-
 target/hppa/cpu.h                             |   2 +-
 target/i386/tcg/helper-tcg.h                  |   6 +
 target/microblaze/cpu.h                       |   8 +-
 target/mips/tcg/tcg-internal.h                |   7 +-
 target/openrisc/cpu.h                         |   7 +-
 target/ppc/cpu.h                              |   3 -
 target/ppc/internal.h                         |   9 +
 target/s390x/s390x-internal.h                 |  13 +-
 target/sh4/cpu.h                              |   6 +-
 target/xtensa/cpu.h                           |   2 +-
 accel/tcg/cpu-exec.c                          |   3 +-
 accel/tcg/user-exec.c                         | 832 ++----------------
 linux-user/alpha/cpu_loop.c                   |   8 -
 linux-user/cris/cpu_loop.c                    |  10 -
 linux-user/hexagon/cpu_loop.c                 |  24 +-
 linux-user/hppa/cpu_loop.c                    |  16 -
 linux-user/m68k/cpu_loop.c                    |  10 -
 linux-user/microblaze/cpu_loop.c              |  10 -
 linux-user/mips/cpu_loop.c                    |  11 -
 linux-user/nios2/cpu_loop.c                   |  10 -
 linux-user/openrisc/cpu_loop.c                |  18 +-
 linux-user/riscv/cpu_loop.c                   |   7 -
 linux-user/s390x/cpu_loop.c                   |  14 +-
 linux-user/sh4/cpu_loop.c                     |   8 -
 linux-user/signal.c                           | 117 ++-
 linux-user/sparc/cpu_loop.c                   |  25 -
 linux-user/xtensa/cpu_loop.c                  |   9 -
 target/alpha/cpu.c                            |   2 +-
 target/alpha/helper.c                         |  13 +-
 target/arm/cpu.c                              |   6 +-
 target/arm/cpu_tcg.c                          |   6 +-
 target/arm/mte_helper.c                       |   6 +-
 target/arm/sve_helper.c                       |   2 +-
 target/arm/tlb_helper.c                       |  36 +-
 target/cris/cpu.c                             |   4 +-
 target/cris/helper.c                          |  18 -
 target/hexagon/cpu.c                          |  23 -
 target/hppa/cpu.c                             |   2 +-
 target/hppa/mem_helper.c                      |  15 -
 target/i386/tcg/tcg-cpu.c                     |   3 +-
 target/i386/tcg/user/excp_helper.c            |  23 +-
 target/m68k/cpu.c                             |   2 +-
 target/m68k/helper.c                          |   6 +-
 target/microblaze/cpu.c                       |   2 +-
 target/microblaze/helper.c                    |  13 +-
 target/mips/cpu.c                             |   2 +-
 target/mips/tcg/user/tlb_helper.c             |  59 --
 target/nios2/cpu.c                            |   2 +-
 target/nios2/helper.c                         |   8 -
 target/openrisc/cpu.c                         |   2 +-
 target/openrisc/mmu.c                         |   8 -
 target/ppc/cpu_init.c                         |   6 +-
 target/ppc/user_only_helper.c                 |  15 +-
 target/riscv/cpu.c                            |   2 +-
 target/riscv/cpu_helper.c                     |  21 +-
 target/s390x/cpu.c                            |   6 +-
 target/s390x/tcg/excp_helper.c                |  18 +-
 target/s390x/tcg/mem_helper.c                 |  18 +-
 target/sh4/cpu.c                              |   2 +-
 target/sh4/helper.c                           |   9 +-
 target/sparc/cpu.c                            |   2 +-
 target/sparc/mmu_helper.c                     |  25 -
 target/xtensa/cpu.c                           |   2 +-
 target/xtensa/helper.c                        |  22 +-
 .../{riscv64 => riscv}/safe-syscall.inc.S     |   0
 target/cris/meson.build                       |   7 +-
 target/hppa/meson.build                       |   6 +-
 target/mips/tcg/meson.build                   |   3 -
 target/mips/tcg/user/meson.build              |   3 -
 target/openrisc/meson.build                   |   2 +-
 target/sparc/meson.build                      |   2 +-
 94 files changed, 910 insertions(+), 1338 deletions(-)
 create mode 100644 linux-user/host/aarch64/host-signal.h
 create mode 100644 linux-user/host/alpha/host-signal.h
 create mode 100644 linux-user/host/arm/host-signal.h
 create mode 100644 linux-user/host/i386/host-signal.h
 create mode 100644 linux-user/host/mips/host-signal.h
 create mode 100644 linux-user/host/ppc/host-signal.h
 create mode 100644 linux-user/host/ppc64/host-signal.h
 create mode 100644 linux-user/host/riscv/host-signal.h
 rename linux-user/host/{riscv64 => riscv}/hostdep.h (94%)
 delete mode 100644 linux-user/host/riscv32/hostdep.h
 create mode 100644 linux-user/host/s390/host-signal.h
 create mode 100644 linux-user/host/s390x/host-signal.h
 create mode 100644 linux-user/host/sparc/host-signal.h
 create mode 100644 linux-user/host/sparc64/host-signal.h
 create mode 100644 linux-user/host/x32/host-signal.h
 create mode 100644 linux-user/host/x86_64/host-signal.h
 delete mode 100644 target/mips/tcg/user/tlb_helper.c
 rename linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S (100%)
 delete mode 100644 target/mips/tcg/user/meson.build

-- 
2.25.1



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

* [PATCH v2 01/41] accel/tcg: Split out adjust_signal_pc
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop Richard Henderson
                   ` (40 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, Philippe Mathieu-Daudé

Split out a function to adjust the raw signal pc into a
value that could be passed to cpu_restore_state.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Adjust pc in place; return MMUAccessType.
---
 include/exec/exec-all.h | 10 ++++++++++
 accel/tcg/user-exec.c   | 41 +++++++++++++++++++++++++----------------
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 9d5987ba04..e54f8e5d65 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -663,6 +663,16 @@ static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env,
     return addr;
 }
 
+/**
+ * adjust_signal_pc:
+ * @pc: raw pc from the host signal ucontext_t.
+ * @is_write: host memory operation was write, or read-modify-write.
+ *
+ * Alter @pc as required for unwinding.  Return the type of the
+ * guest memory access -- host reads may be for guest execution.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
+
 /**
  * cpu_signal_handler
  * @signum: host signal number
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 8fed542622..cef025d001 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -57,18 +57,11 @@ static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu,
     cpu_loop_exit_noexc(cpu);
 }
 
-/* 'pc' is the host PC at which the exception was raised. 'address' is
-   the effective address of the memory exception. 'is_write' is 1 if a
-   write caused the exception and otherwise 0'. 'old_set' is the
-   signal set which should be restored */
-static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
-                                    int is_write, sigset_t *old_set)
+/*
+ * Adjust the pc to pass to cpu_restore_state; return the memop type.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
 {
-    CPUState *cpu = current_cpu;
-    CPUClass *cc;
-    unsigned long address = (unsigned long)info->si_addr;
-    MMUAccessType access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
-
     switch (helper_retaddr) {
     default:
         /*
@@ -77,7 +70,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
          * pointer into the generated code that will unwind to the
          * correct guest pc.
          */
-        pc = helper_retaddr;
+        *pc = helper_retaddr;
         break;
 
     case 0:
@@ -97,7 +90,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
          * Therefore, adjust to compensate for what will be done later
          * by cpu_restore_state_from_tb.
          */
-        pc += GETPC_ADJ;
+        *pc += GETPC_ADJ;
         break;
 
     case 1:
@@ -113,12 +106,28 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
          *
          * Like tb_gen_code, release the memory lock before cpu_loop_exit.
          */
-        pc = 0;
-        access_type = MMU_INST_FETCH;
         mmap_unlock();
-        break;
+        *pc = 0;
+        return MMU_INST_FETCH;
     }
 
+    return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
+}
+
+/*
+ * 'pc' is the host PC at which the exception was raised.
+ * 'address' is the effective address of the memory exception.
+ * 'is_write' is 1 if a write caused the exception and otherwise 0.
+ * 'old_set' is the signal set which should be restored.
+ */
+static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
+                                    int is_write, sigset_t *old_set)
+{
+    CPUState *cpu = current_cpu;
+    CPUClass *cc;
+    unsigned long address = (unsigned long)info->si_addr;
+    MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
+
     /* For synchronous signals we expect to be coming from the vCPU
      * thread (so current_cpu should be valid) and either from running
      * code or during translation which can fault as we cross pages.
-- 
2.25.1



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

* [PATCH v2 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 01/41] accel/tcg: Split out adjust_signal_pc Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-19 19:35   ` Warner Losh
  2021-09-18 18:44 ` [PATCH v2 03/41] accel/tcg: Split out handle_sigsegv_accerr_write Richard Henderson
                   ` (39 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Currently there are only two places that require we reset this
value before exiting to the main loop, but that will change.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 accel/tcg/cpu-exec.c  | 3 ++-
 accel/tcg/user-exec.c | 2 --
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 5fd1ed3422..410588d08a 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -451,6 +451,7 @@ void cpu_exec_step_atomic(CPUState *cpu)
          * memory.
          */
 #ifndef CONFIG_SOFTMMU
+        clear_helper_retaddr();
         tcg_debug_assert(!have_mmap_lock());
 #endif
         if (qemu_mutex_iothread_locked()) {
@@ -460,7 +461,6 @@ void cpu_exec_step_atomic(CPUState *cpu)
         qemu_plugin_disable_mem_helpers(cpu);
     }
 
-
     /*
      * As we start the exclusive region before codegen we must still
      * be in the region if we longjump out of either the codegen or
@@ -905,6 +905,7 @@ int cpu_exec(CPUState *cpu)
 #endif
 
 #ifndef CONFIG_SOFTMMU
+        clear_helper_retaddr();
         tcg_debug_assert(!have_mmap_lock());
 #endif
         if (qemu_mutex_iothread_locked()) {
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index cef025d001..e94f1fed00 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -175,7 +175,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
              * currently executing TB was modified and must be exited
              * immediately.  Clear helper_retaddr for next execution.
              */
-            clear_helper_retaddr();
             cpu_exit_tb_from_sighandler(cpu, old_set);
             /* NORETURN */
 
@@ -193,7 +192,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
      * an exception.  Undo signal and retaddr state prior to longjmp.
      */
     sigprocmask(SIG_SETMASK, old_set, NULL);
-    clear_helper_retaddr();
 
     cc = CPU_GET_CLASS(cpu);
     cc->tcg_ops->tlb_fill(cpu, address, 0, access_type,
-- 
2.25.1



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

* [PATCH v2 03/41] accel/tcg: Split out handle_sigsegv_accerr_write
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 01/41] accel/tcg: Split out adjust_signal_pc Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 04/41] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller Richard Henderson
                   ` (38 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, Philippe Mathieu-Daudé

This is the major portion of handle_cpu_signal which is specific
to tcg, handling the page protections for the translations.
Most of the rest will migrate to linux-user/ shortly.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Pass guest address to handle_sigsegv_accerr_write.
---
 include/exec/exec-all.h |  12 +++++
 accel/tcg/user-exec.c   | 103 ++++++++++++++++++++++++----------------
 2 files changed, 74 insertions(+), 41 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e54f8e5d65..5f94d799aa 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -673,6 +673,18 @@ static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env,
  */
 MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
 
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @host_addr: the host address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+                                 uintptr_t host_pc, abi_ptr guest_addr);
+
 /**
  * cpu_signal_handler
  * @signum: host signal number
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e94f1fed00..6f4fc01b60 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -114,6 +114,54 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
     return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
 }
 
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @guest_addr: the guest address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ *
+ * Note that it is important that we don't call page_unprotect() unless
+ * this is really a "write to nonwriteable page" fault, because
+ * page_unprotect() assumes that if it is called for an access to
+ * a page that's writeable this means we had two threads racing and
+ * another thread got there first and already made the page writeable;
+ * so we will retry the access. If we were to call page_unprotect()
+ * for some other kind of fault that should really be passed to the
+ * guest, we'd end up in an infinite loop of retrying the faulting access.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+                                 uintptr_t host_pc, abi_ptr guest_addr)
+{
+    switch (page_unprotect(guest_addr, host_pc)) {
+    case 0:
+        /*
+         * Fault not caused by a page marked unwritable to protect
+         * cached translations, must be the guest binary's problem.
+         */
+        return false;
+    case 1:
+        /*
+         * Fault caused by protection of cached translation; TBs
+         * invalidated, so resume execution.  Retain helper_retaddr
+         * for a possible second fault.
+         */
+        return true;
+    case 2:
+        /*
+         * Fault caused by protection of cached translation, and the
+         * currently executing TB was modified and must be exited
+         * immediately.  Clear helper_retaddr for next execution.
+         */
+        cpu_exit_tb_from_sighandler(cpu, old_set);
+        /* NORETURN */
+    default:
+        g_assert_not_reached();
+    }
+}
+
 /*
  * 'pc' is the host PC at which the exception was raised.
  * 'address' is the effective address of the memory exception.
@@ -125,8 +173,9 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
 {
     CPUState *cpu = current_cpu;
     CPUClass *cc;
-    unsigned long address = (unsigned long)info->si_addr;
+    unsigned long host_addr = (unsigned long)info->si_addr;
     MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
+    abi_ptr guest_addr;
 
     /* For synchronous signals we expect to be coming from the vCPU
      * thread (so current_cpu should be valid) and either from running
@@ -143,49 +192,21 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
 
 #if defined(DEBUG_SIGNAL)
     printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-           pc, address, is_write, *(unsigned long *)old_set);
+           pc, host_addr, is_write, *(unsigned long *)old_set);
 #endif
-    /* XXX: locking issue */
-    /* Note that it is important that we don't call page_unprotect() unless
-     * this is really a "write to nonwriteable page" fault, because
-     * page_unprotect() assumes that if it is called for an access to
-     * a page that's writeable this means we had two threads racing and
-     * another thread got there first and already made the page writeable;
-     * so we will retry the access. If we were to call page_unprotect()
-     * for some other kind of fault that should really be passed to the
-     * guest, we'd end up in an infinite loop of retrying the faulting
-     * access.
-     */
-    if (is_write && info->si_signo == SIGSEGV && info->si_code == SEGV_ACCERR &&
-        h2g_valid(address)) {
-        switch (page_unprotect(h2g(address), pc)) {
-        case 0:
-            /* Fault not caused by a page marked unwritable to protect
-             * cached translations, must be the guest binary's problem.
-             */
-            break;
-        case 1:
-            /* Fault caused by protection of cached translation; TBs
-             * invalidated, so resume execution.  Retain helper_retaddr
-             * for a possible second fault.
-             */
-            return 1;
-        case 2:
-            /* Fault caused by protection of cached translation, and the
-             * currently executing TB was modified and must be exited
-             * immediately.  Clear helper_retaddr for next execution.
-             */
-            cpu_exit_tb_from_sighandler(cpu, old_set);
-            /* NORETURN */
-
-        default:
-            g_assert_not_reached();
-        }
-    }
 
     /* Convert forcefully to guest address space, invalid addresses
        are still valid segv ones */
-    address = h2g_nocheck(address);
+    guest_addr = h2g_nocheck(host_addr);
+
+    /* XXX: locking issue */
+    if (is_write &&
+        info->si_signo == SIGSEGV &&
+        info->si_code == SEGV_ACCERR &&
+        h2g_valid(host_addr) &&
+        handle_sigsegv_accerr_write(cpu, old_set, pc, guest_addr)) {
+        return 1;
+    }
 
     /*
      * There is no way the target can handle this other than raising
@@ -194,7 +215,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
     sigprocmask(SIG_SETMASK, old_set, NULL);
 
     cc = CPU_GET_CLASS(cpu);
-    cc->tcg_ops->tlb_fill(cpu, address, 0, access_type,
+    cc->tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
                           MMU_USER_IDX, false, pc);
     g_assert_not_reached();
 }
-- 
2.25.1



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

* [PATCH v2 04/41] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (2 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 03/41] accel/tcg: Split out handle_sigsegv_accerr_write Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures Richard Henderson
                   ` (37 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Remove the comment about siglongjmp.  We do use sigsetjmp
in the main cpu loop, but we do not save the signal mask
as most exits from the cpu loop do not require them.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 accel/tcg/user-exec.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 6f4fc01b60..de4565f13e 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -46,17 +46,6 @@ __thread uintptr_t helper_retaddr;
 
 //#define DEBUG_SIGNAL
 
-/* exit the current TB from a signal handler. The host registers are
-   restored in a state compatible with the CPU emulator
- */
-static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu,
-                                                      sigset_t *old_set)
-{
-    /* XXX: use siglongjmp ? */
-    sigprocmask(SIG_SETMASK, old_set, NULL);
-    cpu_loop_exit_noexc(cpu);
-}
-
 /*
  * Adjust the pc to pass to cpu_restore_state; return the memop type.
  */
@@ -155,7 +144,8 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
          * currently executing TB was modified and must be exited
          * immediately.  Clear helper_retaddr for next execution.
          */
-        cpu_exit_tb_from_sighandler(cpu, old_set);
+        sigprocmask(SIG_SETMASK, old_set, NULL);
+        cpu_loop_exit_noexc(cpu);
         /* NORETURN */
     default:
         g_assert_not_reached();
-- 
2.25.1



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

* [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (3 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 04/41] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-19 17:56   ` Philippe Mathieu-Daudé
  2021-09-19 22:57   ` Alistair Francis
  2021-09-18 18:44 ` [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV Richard Henderson
                   ` (36 subsequent siblings)
  41 siblings, 2 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The existing code for safe-syscall.inc.S will compile
without change for riscv32 and riscv64.  We may also
drop the meson.build stanza that merges them for tcg/.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 configure                                             |  8 ++------
 meson.build                                           |  4 +---
 linux-user/host/{riscv64 => riscv}/hostdep.h          |  4 ++--
 linux-user/host/riscv32/hostdep.h                     | 11 -----------
 linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S |  0
 5 files changed, 5 insertions(+), 22 deletions(-)
 rename linux-user/host/{riscv64 => riscv}/hostdep.h (94%)
 delete mode 100644 linux-user/host/riscv32/hostdep.h
 rename linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S (100%)

diff --git a/configure b/configure
index da2501489f..6ff037bac1 100755
--- a/configure
+++ b/configure
@@ -650,11 +650,7 @@ elif check_define __s390__ ; then
     cpu="s390"
   fi
 elif check_define __riscv ; then
-  if check_define _LP64 ; then
-    cpu="riscv64"
-  else
-    cpu="riscv32"
-  fi
+  cpu="riscv"
 elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
@@ -667,7 +663,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64)
+  ppc|ppc64|s390x|sparc64|x32|riscv)
   ;;
   ppc64le)
     ARCH="ppc64"
diff --git a/meson.build b/meson.build
index 2711cbb789..c35a230bf0 100644
--- a/meson.build
+++ b/meson.build
@@ -56,7 +56,7 @@ have_block = have_system or have_tools
 python = import('python').find_installation()
 
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
-supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
+supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
 
 cpu = host_machine.cpu_family()
@@ -271,8 +271,6 @@ if not get_option('tcg').disabled()
     tcg_arch = 'i386'
   elif config_host['ARCH'] == 'ppc64'
     tcg_arch = 'ppc'
-  elif config_host['ARCH'] in ['riscv32', 'riscv64']
-    tcg_arch = 'riscv'
   endif
   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
                         language: ['c', 'cpp', 'objc'])
diff --git a/linux-user/host/riscv64/hostdep.h b/linux-user/host/riscv/hostdep.h
similarity index 94%
rename from linux-user/host/riscv64/hostdep.h
rename to linux-user/host/riscv/hostdep.h
index 865f0fb9ff..2ba07456ae 100644
--- a/linux-user/host/riscv64/hostdep.h
+++ b/linux-user/host/riscv/hostdep.h
@@ -5,8 +5,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef RISCV64_HOSTDEP_H
-#define RISCV64_HOSTDEP_H
+#ifndef RISCV_HOSTDEP_H
+#define RISCV_HOSTDEP_H
 
 /* We have a safe-syscall.inc.S */
 #define HAVE_SAFE_SYSCALL
diff --git a/linux-user/host/riscv32/hostdep.h b/linux-user/host/riscv32/hostdep.h
deleted file mode 100644
index adf9edbf2d..0000000000
--- a/linux-user/host/riscv32/hostdep.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef RISCV32_HOSTDEP_H
-#define RISCV32_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/riscv64/safe-syscall.inc.S b/linux-user/host/riscv/safe-syscall.inc.S
similarity index 100%
rename from linux-user/host/riscv64/safe-syscall.inc.S
rename to linux-user/host/riscv/safe-syscall.inc.S
-- 
2.25.1



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

* [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (4 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-19 18:02   ` Philippe Mathieu-Daudé
                     ` (2 more replies)
  2021-09-18 18:44 ` [PATCH v2 07/41] linux-user/host/x86: Populate host_signal.h Richard Henderson
                   ` (35 subsequent siblings)
  41 siblings, 3 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Add stub host-signal.h for all linux-user hosts.
Add new code replacing cpu_signal_handler.
Full migration will happen one host at a time.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/aarch64/host-signal.h |   1 +
 linux-user/host/arm/host-signal.h     |   1 +
 linux-user/host/i386/host-signal.h    |   1 +
 linux-user/host/mips/host-signal.h    |   1 +
 linux-user/host/ppc/host-signal.h     |   1 +
 linux-user/host/ppc64/host-signal.h   |   1 +
 linux-user/host/riscv/host-signal.h   |   1 +
 linux-user/host/s390/host-signal.h    |   1 +
 linux-user/host/s390x/host-signal.h   |   1 +
 linux-user/host/sparc/host-signal.h   |   1 +
 linux-user/host/sparc64/host-signal.h |   1 +
 linux-user/host/x32/host-signal.h     |   1 +
 linux-user/host/x86_64/host-signal.h  |   1 +
 linux-user/signal.c                   | 109 ++++++++++++++++++++++----
 14 files changed, 106 insertions(+), 16 deletions(-)
 create mode 100644 linux-user/host/aarch64/host-signal.h
 create mode 100644 linux-user/host/arm/host-signal.h
 create mode 100644 linux-user/host/i386/host-signal.h
 create mode 100644 linux-user/host/mips/host-signal.h
 create mode 100644 linux-user/host/ppc/host-signal.h
 create mode 100644 linux-user/host/ppc64/host-signal.h
 create mode 100644 linux-user/host/riscv/host-signal.h
 create mode 100644 linux-user/host/s390/host-signal.h
 create mode 100644 linux-user/host/s390x/host-signal.h
 create mode 100644 linux-user/host/sparc/host-signal.h
 create mode 100644 linux-user/host/sparc64/host-signal.h
 create mode 100644 linux-user/host/x32/host-signal.h
 create mode 100644 linux-user/host/x86_64/host-signal.h

diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/aarch64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/arm/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/i386/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/mips/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/ppc/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/ppc64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/riscv/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/s390/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/s390x/host-signal.h b/linux-user/host/s390x/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/s390x/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/sparc/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/sparc64/host-signal.h b/linux-user/host/sparc64/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/sparc64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/x32/host-signal.h b/linux-user/host/x32/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/x32/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/host-signal.h
new file mode 100644
index 0000000000..f4b4d65031
--- /dev/null
+++ b/linux-user/host/x86_64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 5ea8e4584a..6f953f10d4 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -18,12 +18,15 @@
  */
 #include "qemu/osdep.h"
 #include "qemu/bitops.h"
+#include "hw/core/tcg-cpu-ops.h"
+
 #include <sys/ucontext.h>
 #include <sys/resource.h>
 
 #include "qemu.h"
 #include "trace.h"
 #include "signal-common.h"
+#include "host-signal.h"
 
 static struct target_sigaction sigact_table[TARGET_NSIG];
 
@@ -761,41 +764,115 @@ static inline void rewind_if_in_safe_syscall(void *puc)
 }
 #endif
 
-static void host_signal_handler(int host_signum, siginfo_t *info,
-                                void *puc)
+static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
 {
     CPUArchState *env = thread_cpu->env_ptr;
     CPUState *cpu = env_cpu(env);
     TaskState *ts = cpu->opaque;
-
-    int sig;
     target_siginfo_t tinfo;
     ucontext_t *uc = puc;
     struct emulated_sigtable *k;
+    int guest_sig;
 
+#ifdef HOST_SIGNAL_PLACEHOLDER
     /* the CPU emulator uses some host signals to detect exceptions,
        we forward to it some signals */
-    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
+    if ((host_sig == SIGSEGV || host_sig == SIGBUS)
         && info->si_code > 0) {
-        if (cpu_signal_handler(host_signum, info, puc))
+        if (cpu_signal_handler(host_sig, info, puc))
             return;
     }
+#else
+    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) {
+            const struct TCGCPUOps *tcg_ops;
+
+            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);
+
+            tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
+            tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
+                              MMU_USER_IDX, false, pc);
+            g_assert_not_reached();
+        } else {
+            sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
+        }
+
+        sync_sig = true;
+    }
+#endif
 
     /* get target signal number */
-    sig = host_to_target_signal(host_signum);
-    if (sig < 1 || sig > TARGET_NSIG)
+    guest_sig = host_to_target_signal(host_sig);
+    if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
         return;
-    trace_user_host_signal(env, host_signum, sig);
+    }
+    trace_user_host_signal(env, host_sig, guest_sig);
+
+    host_to_target_siginfo_noswap(&tinfo, info);
+    k = &ts->sigtab[guest_sig - 1];
+    k->info = tinfo;
+    k->pending = guest_sig;
+    ts->signal_pending = 1;
+
+#ifndef HOST_SIGNAL_PLACEHOLDER
+    /*
+     * For synchronous signals, unwind the cpu state to the faulting
+     * insn and then exit back to the main loop so that the signal
+     * is delivered immediately.
+     */
+    if (sync_sig) {
+        cpu->exception_index = EXCP_INTERRUPT;
+        cpu_loop_exit_restore(cpu, pc);
+    }
+#endif
 
     rewind_if_in_safe_syscall(puc);
 
-    host_to_target_siginfo_noswap(&tinfo, info);
-    k = &ts->sigtab[sig - 1];
-    k->info = tinfo;
-    k->pending = sig;
-    ts->signal_pending = 1;
-
-    /* Block host signals until target signal handler entered. We
+    /*
+     * 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
-- 
2.25.1



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

* [PATCH v2 07/41] linux-user/host/x86: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (5 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 08/41] linux-user/host/ppc: " Richard Henderson
                   ` (34 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/i386/host-signal.h   |  25 ++++-
 linux-user/host/x32/host-signal.h    |   2 +-
 linux-user/host/x86_64/host-signal.h |  25 ++++-
 accel/tcg/user-exec.c                | 136 +--------------------------
 4 files changed, 50 insertions(+), 138 deletions(-)

diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host-signal.h
index f4b4d65031..ccbbee5082 100644
--- a/linux-user/host/i386/host-signal.h
+++ b/linux-user/host/i386/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef I386_HOST_SIGNAL_H
+#define I386_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_EIP];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+        && (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/linux-user/host/x32/host-signal.h b/linux-user/host/x32/host-signal.h
index f4b4d65031..26800591d3 100644
--- a/linux-user/host/x32/host-signal.h
+++ b/linux-user/host/x32/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../x86_64/host-signal.h"
diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/host-signal.h
index f4b4d65031..883d2fcf65 100644
--- a/linux-user/host/x86_64/host-signal.h
+++ b/linux-user/host/x86_64/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef X86_64_HOST_SIGNAL_H
+#define X86_64_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_RIP];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+        && (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index de4565f13e..b5d06183db 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -29,19 +29,6 @@
 #include "trace/trace-root.h"
 #include "trace/mem.h"
 
-#undef EAX
-#undef ECX
-#undef EDX
-#undef EBX
-#undef ESP
-#undef EBP
-#undef ESI
-#undef EDI
-#undef EIP
-#ifdef __linux__
-#include <sys/ucontext.h>
-#endif
-
 __thread uintptr_t helper_retaddr;
 
 //#define DEBUG_SIGNAL
@@ -268,123 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__i386__)
-
-#if defined(__NetBSD__)
-#include <ucontext.h>
-#include <machine/trap.h>
-
-#define EIP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_EIP])
-#define TRAP_sig(context)    ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-#define ERROR_sig(context)   ((context)->uc_mcontext.__gregs[_REG_ERR])
-#define MASK_sig(context)    ((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP      T_PAGEFLT
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
-#include <ucontext.h>
-#include <machine/trap.h>
-
-#define EIP_sig(context)  (*((unsigned long *)&(context)->uc_mcontext.mc_eip))
-#define TRAP_sig(context)    ((context)->uc_mcontext.mc_trapno)
-#define ERROR_sig(context)   ((context)->uc_mcontext.mc_err)
-#define MASK_sig(context)    ((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP      T_PAGEFLT
-#elif defined(__OpenBSD__)
-#include <machine/trap.h>
-#define EIP_sig(context)     ((context)->sc_eip)
-#define TRAP_sig(context)    ((context)->sc_trapno)
-#define ERROR_sig(context)   ((context)->sc_err)
-#define MASK_sig(context)    ((context)->sc_mask)
-#define PAGE_FAULT_TRAP      T_PAGEFLT
-#else
-#define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
-#define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
-#define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
-#define MASK_sig(context)    ((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP      0xe
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-    ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#else
-    ucontext_t *uc = puc;
-#endif
-    unsigned long pc;
-    int trapno;
-
-#ifndef REG_EIP
-/* for glibc 2.1 */
-#define REG_EIP    EIP
-#define REG_ERR    ERR
-#define REG_TRAPNO TRAPNO
-#endif
-    pc = EIP_sig(uc);
-    trapno = TRAP_sig(uc);
-    return handle_cpu_signal(pc, info,
-                             trapno == PAGE_FAULT_TRAP ?
-                             (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc));
-}
-
-#elif defined(__x86_64__)
-
-#ifdef __NetBSD__
-#include <machine/trap.h>
-#define PC_sig(context)       _UC_MACHINE_PC(context)
-#define TRAP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-#define ERROR_sig(context)    ((context)->uc_mcontext.__gregs[_REG_ERR])
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP       T_PAGEFLT
-#elif defined(__OpenBSD__)
-#include <machine/trap.h>
-#define PC_sig(context)       ((context)->sc_rip)
-#define TRAP_sig(context)     ((context)->sc_trapno)
-#define ERROR_sig(context)    ((context)->sc_err)
-#define MASK_sig(context)     ((context)->sc_mask)
-#define PAGE_FAULT_TRAP       T_PAGEFLT
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
-#include <ucontext.h>
-#include <machine/trap.h>
-
-#define PC_sig(context)  (*((unsigned long *)&(context)->uc_mcontext.mc_rip))
-#define TRAP_sig(context)     ((context)->uc_mcontext.mc_trapno)
-#define ERROR_sig(context)    ((context)->uc_mcontext.mc_err)
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP       T_PAGEFLT
-#else
-#define PC_sig(context)       ((context)->uc_mcontext.gregs[REG_RIP])
-#define TRAP_sig(context)     ((context)->uc_mcontext.gregs[REG_TRAPNO])
-#define ERROR_sig(context)    ((context)->uc_mcontext.gregs[REG_ERR])
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP       0xe
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    unsigned long pc;
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-    ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#else
-    ucontext_t *uc = puc;
-#endif
-
-    pc = PC_sig(uc);
-    return handle_cpu_signal(pc, info,
-                             TRAP_sig(uc) == PAGE_FAULT_TRAP ?
-                             (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc));
-}
-
-#elif defined(_ARCH_PPC)
+#if defined(_ARCH_PPC)
 
 /***********************************************************************
  * signal context platform-specific definitions
@@ -895,11 +766,6 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 
     return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
 }
-
-#else
-
-#error host CPU specific signal handler needed
-
 #endif
 
 /* The softmmu versions of these helpers are in cputlb.c.  */
-- 
2.25.1



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

* [PATCH v2 08/41] linux-user/host/ppc: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (6 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 07/41] linux-user/host/x86: Populate host_signal.h Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-19 19:34   ` Warner Losh
  2021-09-18 18:44 ` [PATCH v2 09/41] linux-user/host/alpha: " Richard Henderson
                   ` (33 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/ppc/host-signal.h   | 25 ++++++++-
 linux-user/host/ppc64/host-signal.h |  2 +-
 accel/tcg/user-exec.c               | 79 +----------------------------
 3 files changed, 26 insertions(+), 80 deletions(-)

diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h
index f4b4d65031..e09756c691 100644
--- a/linux-user/host/ppc/host-signal.h
+++ b/linux-user/host/ppc/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_HOST_SIGNAL_H
+#define PPC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.regs->nip;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    return uc->uc_mcontext.regs->trap != 0x400
+        && (uc->uc_mcontext.regs->dsisr & 0x02000000);
+}
+
+#endif
diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/host-signal.h
index f4b4d65031..a353c22a90 100644
--- a/linux-user/host/ppc64/host-signal.h
+++ b/linux-user/host/ppc64/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../ppc/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b5d06183db..e9e530e2e1 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,84 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(_ARCH_PPC)
-
-/***********************************************************************
- * signal context platform-specific definitions
- * From Wine
- */
-#ifdef linux
-/* All Registers access - only for local access */
-#define REG_sig(reg_name, context)              \
-    ((context)->uc_mcontext.regs->reg_name)
-/* Gpr Registers access  */
-#define GPR_sig(reg_num, context)              REG_sig(gpr[reg_num], context)
-/* Program counter */
-#define IAR_sig(context)                       REG_sig(nip, context)
-/* Machine State Register (Supervisor) */
-#define MSR_sig(context)                       REG_sig(msr, context)
-/* Count register */
-#define CTR_sig(context)                       REG_sig(ctr, context)
-/* User's integer exception register */
-#define XER_sig(context)                       REG_sig(xer, context)
-/* Link register */
-#define LR_sig(context)                        REG_sig(link, context)
-/* Condition register */
-#define CR_sig(context)                        REG_sig(ccr, context)
-
-/* Float Registers access  */
-#define FLOAT_sig(reg_num, context)                                     \
-    (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num])
-#define FPSCR_sig(context) \
-    (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4)))
-/* Exception Registers access */
-#define DAR_sig(context)                       REG_sig(dar, context)
-#define DSISR_sig(context)                     REG_sig(dsisr, context)
-#define TRAP_sig(context)                      REG_sig(trap, context)
-#endif /* linux */
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include <ucontext.h>
-#define IAR_sig(context)               ((context)->uc_mcontext.mc_srr0)
-#define MSR_sig(context)               ((context)->uc_mcontext.mc_srr1)
-#define CTR_sig(context)               ((context)->uc_mcontext.mc_ctr)
-#define XER_sig(context)               ((context)->uc_mcontext.mc_xer)
-#define LR_sig(context)                ((context)->uc_mcontext.mc_lr)
-#define CR_sig(context)                ((context)->uc_mcontext.mc_cr)
-/* Exception Registers access */
-#define DAR_sig(context)               ((context)->uc_mcontext.mc_dar)
-#define DSISR_sig(context)             ((context)->uc_mcontext.mc_dsisr)
-#define TRAP_sig(context)              ((context)->uc_mcontext.mc_exc)
-#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    ucontext_t *uc = puc;
-#else
-    ucontext_t *uc = puc;
-#endif
-    unsigned long pc;
-    int is_write;
-
-    pc = IAR_sig(uc);
-    is_write = 0;
-#if 0
-    /* ppc 4xx case */
-    if (DSISR_sig(uc) & 0x00800000) {
-        is_write = 1;
-    }
-#else
-    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) {
-        is_write = 1;
-    }
-#endif
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__alpha__)
+#if defined(__alpha__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
                            void *puc)
-- 
2.25.1



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

* [PATCH v2 09/41] linux-user/host/alpha: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (7 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 08/41] linux-user/host/ppc: " Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-19 18:03   ` Philippe Mathieu-Daudé
  2021-09-19 18:13   ` Philippe Mathieu-Daudé
  2021-09-18 18:44 ` [PATCH v2 10/41] linux-user/host/sparc: " Richard Henderson
                   ` (32 subsequent siblings)
  41 siblings, 2 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/alpha/host-signal.h | 41 +++++++++++++++++++++++++++++
 accel/tcg/user-exec.c               | 31 +---------------------
 2 files changed, 42 insertions(+), 30 deletions(-)
 create mode 100644 linux-user/host/alpha/host-signal.h

diff --git a/linux-user/host/alpha/host-signal.h b/linux-user/host/alpha/host-signal.h
new file mode 100644
index 0000000000..b0b488e004
--- /dev/null
+++ b/linux-user/host/alpha/host-signal.h
@@ -0,0 +1,41 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ALPHA_HOST_SIGNAL_H
+#define ALPHA_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.sc_pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t *pc = uc->uc_mcontext.sc_pc;
+    uint32_t insn = *pc;
+
+    /* XXX: need kernel patch to get write flag faster */
+    switch (insn >> 26) {
+    case 0x0d: /* stw */
+    case 0x0e: /* stb */
+    case 0x0f: /* stq_u */
+    case 0x24: /* stf */
+    case 0x25: /* stg */
+    case 0x26: /* sts */
+    case 0x27: /* stt */
+    case 0x2c: /* stl */
+    case 0x2d: /* stq */
+    case 0x2e: /* stl_c */
+    case 0x2f: /* stq_c */
+        return true;
+    }
+    return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e9e530e2e1..b895b5c8bd 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,36 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__alpha__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                           void *puc)
-{
-    siginfo_t *info = pinfo;
-    ucontext_t *uc = puc;
-    uint32_t *pc = uc->uc_mcontext.sc_pc;
-    uint32_t insn = *pc;
-    int is_write = 0;
-
-    /* XXX: need kernel patch to get write flag faster */
-    switch (insn >> 26) {
-    case 0x0d: /* stw */
-    case 0x0e: /* stb */
-    case 0x0f: /* stq_u */
-    case 0x24: /* stf */
-    case 0x25: /* stg */
-    case 0x26: /* sts */
-    case 0x27: /* stt */
-    case 0x2c: /* stl */
-    case 0x2d: /* stq */
-    case 0x2e: /* stl_c */
-    case 0x2f: /* stq_c */
-        is_write = 1;
-    }
-
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-#elif defined(__sparc__)
+#if defined(__sparc__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
-- 
2.25.1



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

* [PATCH v2 10/41] linux-user/host/sparc: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (8 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 09/41] linux-user/host/alpha: " Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 11/41] linux-user/host/arm: " Richard Henderson
                   ` (31 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.
Drop the Solais code as completely unused.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/sparc/host-signal.h   | 54 ++++++++++++++++++++++-
 linux-user/host/sparc64/host-signal.h |  2 +-
 accel/tcg/user-exec.c                 | 62 +--------------------------
 3 files changed, 55 insertions(+), 63 deletions(-)

diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/host-signal.h
index f4b4d65031..232943a1db 100644
--- a/linux-user/host/sparc/host-signal.h
+++ b/linux-user/host/sparc/host-signal.h
@@ -1 +1,53 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef SPARC_HOST_SIGNAL_H
+#define SPARC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+#ifdef __arch64__
+    return uc->uc_mcontext.mc_gregs[MC_PC];
+#else
+    return uc->uc_mcontext.gregs[REG_PC];
+#endif
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+    if ((insn >> 30) == 3) {
+        switch ((insn >> 19) & 0x3f) {
+        case 0x05: /* stb */
+        case 0x15: /* stba */
+        case 0x06: /* sth */
+        case 0x16: /* stha */
+        case 0x04: /* st */
+        case 0x14: /* sta */
+        case 0x07: /* std */
+        case 0x17: /* stda */
+        case 0x0e: /* stx */
+        case 0x1e: /* stxa */
+        case 0x24: /* stf */
+        case 0x34: /* stfa */
+        case 0x27: /* stdf */
+        case 0x37: /* stdfa */
+        case 0x26: /* stqf */
+        case 0x36: /* stqfa */
+        case 0x25: /* stfsr */
+        case 0x3c: /* casa */
+        case 0x3e: /* casxa */
+            return true;
+        }
+    }
+    return false;
+}
+
+#endif
diff --git a/linux-user/host/sparc64/host-signal.h b/linux-user/host/sparc64/host-signal.h
index f4b4d65031..1191fe2d40 100644
--- a/linux-user/host/sparc64/host-signal.h
+++ b/linux-user/host/sparc64/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../sparc/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b895b5c8bd..c7d083db92 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,67 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__sparc__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    int is_write;
-    uint32_t insn;
-#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
-    uint32_t *regs = (uint32_t *)(info + 1);
-    void *sigmask = (regs + 20);
-    /* XXX: is there a standard glibc define ? */
-    unsigned long pc = regs[1];
-#else
-#ifdef __linux__
-    struct sigcontext *sc = puc;
-    unsigned long pc = sc->sigc_regs.tpc;
-    void *sigmask = (void *)sc->sigc_mask;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-    unsigned long pc = uc->sc_pc;
-    void *sigmask = (void *)(long)uc->sc_mask;
-#elif defined(__NetBSD__)
-    ucontext_t *uc = puc;
-    unsigned long pc = _UC_MACHINE_PC(uc);
-    void *sigmask = (void *)&uc->uc_sigmask;
-#endif
-#endif
-
-    /* XXX: need kernel patch to get write flag faster */
-    is_write = 0;
-    insn = *(uint32_t *)pc;
-    if ((insn >> 30) == 3) {
-        switch ((insn >> 19) & 0x3f) {
-        case 0x05: /* stb */
-        case 0x15: /* stba */
-        case 0x06: /* sth */
-        case 0x16: /* stha */
-        case 0x04: /* st */
-        case 0x14: /* sta */
-        case 0x07: /* std */
-        case 0x17: /* stda */
-        case 0x0e: /* stx */
-        case 0x1e: /* stxa */
-        case 0x24: /* stf */
-        case 0x34: /* stfa */
-        case 0x27: /* stdf */
-        case 0x37: /* stdfa */
-        case 0x26: /* stqf */
-        case 0x36: /* stqfa */
-        case 0x25: /* stfsr */
-        case 0x3c: /* casa */
-        case 0x3e: /* casxa */
-            is_write = 1;
-            break;
-        }
-    }
-    return handle_cpu_signal(pc, info, is_write, sigmask);
-}
-
-#elif defined(__arm__)
+#if defined(__arm__)
 
 #if defined(__NetBSD__)
 #include <ucontext.h>
-- 
2.25.1



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

* [PATCH v2 11/41] linux-user/host/arm: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (9 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 10/41] linux-user/host/sparc: " Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 12/41] linux-user/host/aarch64: " Richard Henderson
                   ` (30 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/arm/host-signal.h | 30 ++++++++++++++++++++-
 accel/tcg/user-exec.c             | 45 +------------------------------
 2 files changed, 30 insertions(+), 45 deletions(-)

diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-signal.h
index f4b4d65031..6932224c1c 100644
--- a/linux-user/host/arm/host-signal.h
+++ b/linux-user/host/arm/host-signal.h
@@ -1 +1,29 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ARM_HOST_SIGNAL_H
+#define ARM_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.arm_pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    /*
+     * In the FSR, bit 11 is WnR, assuming a v6 or
+     * later processor.  On v5 we will always report
+     * this as a read, which will fail later.
+     */
+    uint32_t fsr = uc->uc_mcontext.error_code;
+    return extract32(fsr, 11, 1);
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index c7d083db92..e9c29f917d 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,50 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__arm__)
-
-#if defined(__NetBSD__)
-#include <ucontext.h>
-#include <sys/siginfo.h>
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-#if defined(__NetBSD__)
-    ucontext_t *uc = puc;
-    siginfo_t *si = pinfo;
-#else
-    ucontext_t *uc = puc;
-#endif
-    unsigned long pc;
-    uint32_t fsr;
-    int is_write;
-
-#if defined(__NetBSD__)
-    pc = uc->uc_mcontext.__gregs[_REG_R15];
-#elif defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
-    pc = uc->uc_mcontext.gregs[R15];
-#else
-    pc = uc->uc_mcontext.arm_pc;
-#endif
-
-#ifdef __NetBSD__
-    fsr = si->si_trap;
-#else
-    fsr = uc->uc_mcontext.error_code;
-#endif
-    /*
-     * In the FSR, bit 11 is WnR, assuming a v6 or
-     * later processor.  On v5 we will always report
-     * this as a read, which will fail later.
-     */
-    is_write = extract32(fsr, 11, 1);
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__aarch64__)
+#if defined(__aarch64__)
 
 #if defined(__NetBSD__)
 
-- 
2.25.1



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

* [PATCH v2 12/41] linux-user/host/aarch64: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (10 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 11/41] linux-user/host/arm: " Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-18 18:44 ` [PATCH v2 13/41] linux-user/host/s390: " Richard Henderson
                   ` (29 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/aarch64/host-signal.h | 74 ++++++++++++++++++++-
 accel/tcg/user-exec.c                 | 94 +--------------------------
 2 files changed, 74 insertions(+), 94 deletions(-)

diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h
index f4b4d65031..02a55c3372 100644
--- a/linux-user/host/aarch64/host-signal.h
+++ b/linux-user/host/aarch64/host-signal.h
@@ -1 +1,73 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef AARCH64_HOST_SIGNAL_H
+#define AARCH64_HOST_SIGNAL_H
+
+/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
+#ifndef ESR_MAGIC
+#define ESR_MAGIC 0x45535201
+struct esr_context {
+    struct _aarch64_ctx head;
+    uint64_t esr;
+};
+#endif
+
+static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
+{
+    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
+}
+
+static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
+{
+    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
+}
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    struct _aarch64_ctx *hdr;
+    uint32_t insn;
+
+    /* Find the esr_context, which has the WnR bit in it */
+    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
+        if (hdr->magic == ESR_MAGIC) {
+            struct esr_context const *ec = (struct esr_context const *)hdr;
+            uint64_t esr = ec->esr;
+
+            /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
+            return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
+        }
+    }
+
+    /*
+     * Fall back to parsing instructions; will only be needed
+     * for really ancient (pre-3.16) kernels.
+     */
+    insn = *(uint32_t *)host_signal_pc(uc);
+
+    return (insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
+        || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
+        || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
+        || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
+        || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
+        || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
+        || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
+        /* Ignore bits 10, 11 & 21, controlling indexing.  */
+        || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
+        || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
+        /* Ignore bits 23 & 24, controlling indexing.  */
+        || (insn & 0x3a400000) == 0x28000000; /* C3.3.7,14-16 */
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e9c29f917d..8f4e788304 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,99 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__aarch64__)
-
-#if defined(__NetBSD__)
-
-#include <ucontext.h>
-#include <sys/siginfo.h>
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-    ucontext_t *uc = puc;
-    siginfo_t *si = pinfo;
-    unsigned long pc;
-    int is_write;
-    uint32_t esr;
-
-    pc = uc->uc_mcontext.__gregs[_REG_PC];
-    esr = si->si_trap;
-
-    /*
-     * siginfo_t::si_trap is the ESR value, for data aborts ESR.EC
-     * is 0b10010x: then bit 6 is the WnR bit
-     */
-    is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-    return handle_cpu_signal(pc, si, is_write, &uc->uc_sigmask);
-}
-
-#else
-
-#ifndef ESR_MAGIC
-/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
-#define ESR_MAGIC 0x45535201
-struct esr_context {
-    struct _aarch64_ctx head;
-    uint64_t esr;
-};
-#endif
-
-static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
-{
-    return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
-}
-
-static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
-{
-    return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
-}
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-    siginfo_t *info = pinfo;
-    ucontext_t *uc = puc;
-    uintptr_t pc = uc->uc_mcontext.pc;
-    bool is_write;
-    struct _aarch64_ctx *hdr;
-    struct esr_context const *esrctx = NULL;
-
-    /* Find the esr_context, which has the WnR bit in it */
-    for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
-        if (hdr->magic == ESR_MAGIC) {
-            esrctx = (struct esr_context const *)hdr;
-            break;
-        }
-    }
-
-    if (esrctx) {
-        /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
-        uint64_t esr = esrctx->esr;
-        is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-    } else {
-        /*
-         * Fall back to parsing instructions; will only be needed
-         * for really ancient (pre-3.16) kernels.
-         */
-        uint32_t insn = *(uint32_t *)pc;
-
-        is_write = ((insn & 0xbfff0000) == 0x0c000000   /* C3.3.1 */
-                    || (insn & 0xbfe00000) == 0x0c800000   /* C3.3.2 */
-                    || (insn & 0xbfdf0000) == 0x0d000000   /* C3.3.3 */
-                    || (insn & 0xbfc00000) == 0x0d800000   /* C3.3.4 */
-                    || (insn & 0x3f400000) == 0x08000000   /* C3.3.6 */
-                    || (insn & 0x3bc00000) == 0x39000000   /* C3.3.13 */
-                    || (insn & 0x3fc00000) == 0x3d800000   /* ... 128bit */
-                    /* Ignore bits 10, 11 & 21, controlling indexing.  */
-                    || (insn & 0x3bc00000) == 0x38000000   /* C3.3.8-12 */
-                    || (insn & 0x3fe00000) == 0x3c800000   /* ... 128bit */
-                    /* Ignore bits 23 & 24, controlling indexing.  */
-                    || (insn & 0x3a400000) == 0x28000000); /* C3.3.7,14-16 */
-    }
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-#endif
-
-#elif defined(__s390__)
+#if defined(__s390__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
-- 
2.25.1



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

* [PATCH v2 13/41] linux-user/host/s390: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (11 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 12/41] linux-user/host/aarch64: " Richard Henderson
@ 2021-09-18 18:44 ` Richard Henderson
  2021-09-19 18:07   ` Philippe Mathieu-Daudé
  2021-09-18 18:45 ` [PATCH v2 14/41] linux-user/host/mips: " Richard Henderson
                   ` (28 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/s390/host-signal.h  | 93 ++++++++++++++++++++++++++++-
 linux-user/host/s390x/host-signal.h |  2 +-
 accel/tcg/user-exec.c               | 88 +--------------------------
 3 files changed, 94 insertions(+), 89 deletions(-)

diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host-signal.h
index f4b4d65031..21f59b612a 100644
--- a/linux-user/host/s390/host-signal.h
+++ b/linux-user/host/s390/host-signal.h
@@ -1 +1,92 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef S390_HOST_SIGNAL_H
+#define S390_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.psw.addr;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
+
+    /*
+     * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
+     * of the normal 2 arguments.  The 4th argument contains the "Translation-
+     * Exception Identification for DAT Exceptions" from the hardware (aka
+     * "int_parm_long"), which does in fact contain the is_write value.
+     * The rt signal handler, as far as I can tell, does not give this value
+     * at all.  Not that we could get to it from here even if it were.
+     * So fall back to parsing instructions.  Treat read-modify-write ones as
+     * writes, which is not fully correct, but for tracking self-modifying code
+     * this is better than treating them as reads.  Checking si_addr page flags
+     * might be a viable improvement, albeit a racy one.
+     */
+    /* ??? This is not even close to complete.  */
+    switch (pinsn[0] >> 8) {
+    case 0x50: /* ST */
+    case 0x42: /* STC */
+    case 0x40: /* STH */
+    case 0xba: /* CS */
+    case 0xbb: /* CDS */
+        return true;
+    case 0xc4: /* RIL format insns */
+        switch (pinsn[0] & 0xf) {
+        case 0xf: /* STRL */
+        case 0xb: /* STGRL */
+        case 0x7: /* STHRL */
+            return true;
+        }
+        break;
+    case 0xc8: /* SSF format insns */
+        switch (pinsn[0] & 0xf) {
+        case 0x2: /* CSST */
+            return true;
+        }
+        break;
+    case 0xe3: /* RXY format insns */
+        switch (pinsn[2] & 0xff) {
+        case 0x50: /* STY */
+        case 0x24: /* STG */
+        case 0x72: /* STCY */
+        case 0x70: /* STHY */
+        case 0x8e: /* STPQ */
+        case 0x3f: /* STRVH */
+        case 0x3e: /* STRV */
+        case 0x2f: /* STRVG */
+            return true;
+        }
+        break;
+    case 0xeb: /* RSY format insns */
+        switch (pinsn[2] & 0xff) {
+        case 0x14: /* CSY */
+        case 0x30: /* CSG */
+        case 0x31: /* CDSY */
+        case 0x3e: /* CDSG */
+        case 0xe4: /* LANG */
+        case 0xe6: /* LAOG */
+        case 0xe7: /* LAXG */
+        case 0xe8: /* LAAG */
+        case 0xea: /* LAALG */
+        case 0xf4: /* LAN */
+        case 0xf6: /* LAO */
+        case 0xf7: /* LAX */
+        case 0xfa: /* LAAL */
+        case 0xf8: /* LAA */
+            return true;
+        }
+        break;
+    }
+    return false;
+}
+
+#endif
diff --git a/linux-user/host/s390x/host-signal.h b/linux-user/host/s390x/host-signal.h
index f4b4d65031..0e83f9358d 100644
--- a/linux-user/host/s390x/host-signal.h
+++ b/linux-user/host/s390x/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../s390/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 8f4e788304..0810b71ba0 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,93 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__s390__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    ucontext_t *uc = puc;
-    unsigned long pc;
-    uint16_t *pinsn;
-    int is_write = 0;
-
-    pc = uc->uc_mcontext.psw.addr;
-
-    /*
-     * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
-     * of the normal 2 arguments.  The 4th argument contains the "Translation-
-     * Exception Identification for DAT Exceptions" from the hardware (aka
-     * "int_parm_long"), which does in fact contain the is_write value.
-     * The rt signal handler, as far as I can tell, does not give this value
-     * at all.  Not that we could get to it from here even if it were.
-     * So fall back to parsing instructions.  Treat read-modify-write ones as
-     * writes, which is not fully correct, but for tracking self-modifying code
-     * this is better than treating them as reads.  Checking si_addr page flags
-     * might be a viable improvement, albeit a racy one.
-     */
-    /* ??? This is not even close to complete.  */
-    pinsn = (uint16_t *)pc;
-    switch (pinsn[0] >> 8) {
-    case 0x50: /* ST */
-    case 0x42: /* STC */
-    case 0x40: /* STH */
-    case 0xba: /* CS */
-    case 0xbb: /* CDS */
-        is_write = 1;
-        break;
-    case 0xc4: /* RIL format insns */
-        switch (pinsn[0] & 0xf) {
-        case 0xf: /* STRL */
-        case 0xb: /* STGRL */
-        case 0x7: /* STHRL */
-            is_write = 1;
-        }
-        break;
-    case 0xc8: /* SSF format insns */
-        switch (pinsn[0] & 0xf) {
-        case 0x2: /* CSST */
-            is_write = 1;
-        }
-        break;
-    case 0xe3: /* RXY format insns */
-        switch (pinsn[2] & 0xff) {
-        case 0x50: /* STY */
-        case 0x24: /* STG */
-        case 0x72: /* STCY */
-        case 0x70: /* STHY */
-        case 0x8e: /* STPQ */
-        case 0x3f: /* STRVH */
-        case 0x3e: /* STRV */
-        case 0x2f: /* STRVG */
-            is_write = 1;
-        }
-        break;
-    case 0xeb: /* RSY format insns */
-        switch (pinsn[2] & 0xff) {
-        case 0x14: /* CSY */
-        case 0x30: /* CSG */
-        case 0x31: /* CDSY */
-        case 0x3e: /* CDSG */
-        case 0xe4: /* LANG */
-        case 0xe6: /* LAOG */
-        case 0xe7: /* LAXG */
-        case 0xe8: /* LAAG */
-        case 0xea: /* LAALG */
-        case 0xf4: /* LAN */
-        case 0xf6: /* LAO */
-        case 0xf7: /* LAX */
-        case 0xfa: /* LAAL */
-        case 0xf8: /* LAA */
-            is_write = 1;
-        }
-        break;
-    }
-
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__mips__)
+#if defined(__mips__)
 
 #if defined(__misp16) || defined(__mips_micromips)
 #error "Unsupported encoding"
-- 
2.25.1



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

* [PATCH v2 14/41] linux-user/host/mips: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (12 preceding siblings ...)
  2021-09-18 18:44 ` [PATCH v2 13/41] linux-user/host/s390: " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:08   ` Philippe Mathieu-Daudé
  2021-09-18 18:45 ` [PATCH v2 15/41] linux-user/host/riscv: " Richard Henderson
                   ` (27 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/mips/host-signal.h | 62 +++++++++++++++++++++++++++++-
 accel/tcg/user-exec.c              | 52 +------------------------
 2 files changed, 62 insertions(+), 52 deletions(-)

diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host-signal.h
index f4b4d65031..9c83e51130 100644
--- a/linux-user/host/mips/host-signal.h
+++ b/linux-user/host/mips/host-signal.h
@@ -1 +1,61 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef MIPS_HOST_SIGNAL_H
+#define MIPS_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.pc;
+}
+
+#if defined(__misp16) || defined(__mips_micromips)
+#error "Unsupported encoding"
+#endif
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+    /* Detect all store instructions at program counter. */
+    switch ((insn >> 26) & 077) {
+    case 050: /* SB */
+    case 051: /* SH */
+    case 052: /* SWL */
+    case 053: /* SW */
+    case 054: /* SDL */
+    case 055: /* SDR */
+    case 056: /* SWR */
+    case 070: /* SC */
+    case 071: /* SWC1 */
+    case 074: /* SCD */
+    case 075: /* SDC1 */
+    case 077: /* SD */
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
+    case 072: /* SWC2 */
+    case 076: /* SDC2 */
+#endif
+        return true;
+    case 023: /* COP1X */
+        /*
+         * Required in all versions of MIPS64 since
+         * MIPS64r1 and subsequent versions of MIPS32r2.
+         */
+        switch (insn & 077) {
+        case 010: /* SWXC1 */
+        case 011: /* SDXC1 */
+        case 015: /* SUXC1 */
+            return true;
+        }
+        break;
+    }
+    return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 0810b71ba0..42d1ad189b 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,57 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__mips__)
-
-#if defined(__misp16) || defined(__mips_micromips)
-#error "Unsupported encoding"
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    ucontext_t *uc = puc;
-    uintptr_t pc = uc->uc_mcontext.pc;
-    uint32_t insn = *(uint32_t *)pc;
-    int is_write = 0;
-
-    /* Detect all store instructions at program counter. */
-    switch((insn >> 26) & 077) {
-    case 050: /* SB */
-    case 051: /* SH */
-    case 052: /* SWL */
-    case 053: /* SW */
-    case 054: /* SDL */
-    case 055: /* SDR */
-    case 056: /* SWR */
-    case 070: /* SC */
-    case 071: /* SWC1 */
-    case 074: /* SCD */
-    case 075: /* SDC1 */
-    case 077: /* SD */
-#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
-    case 072: /* SWC2 */
-    case 076: /* SDC2 */
-#endif
-        is_write = 1;
-        break;
-    case 023: /* COP1X */
-        /* Required in all versions of MIPS64 since
-           MIPS64r1 and subsequent versions of MIPS32r2. */
-        switch (insn & 077) {
-        case 010: /* SWXC1 */
-        case 011: /* SDXC1 */
-        case 015: /* SUXC1 */
-            is_write = 1;
-        }
-        break;
-    }
-
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__riscv)
+#if defined(__riscv)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
-- 
2.25.1



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

* [PATCH v2 15/41] linux-user/host/riscv: Populate host_signal.h
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (13 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 14/41] linux-user/host/mips: " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 16/41] target/arm: Fixup comment re handle_cpu_signal Richard Henderson
                   ` (26 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Split host_signal_pc and host_signal_write out of user-exec.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/riscv/host-signal.h |  85 +++++++++++++++++-
 accel/tcg/user-exec.c               | 134 ----------------------------
 2 files changed, 84 insertions(+), 135 deletions(-)

diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h
index f4b4d65031..5860dce7d7 100644
--- a/linux-user/host/riscv/host-signal.h
+++ b/linux-user/host/riscv/host-signal.h
@@ -1 +1,84 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef RISCV_HOST_SIGNAL_H
+#define RISCV_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+    return uc->uc_mcontext.__gregs[REG_PC];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+    /*
+     * Detect store by reading the instruction at the program
+     * counter. Note: we currently only generate 32-bit
+     * instructions so we thus only detect 32-bit stores
+     */
+    switch (((insn >> 0) & 0b11)) {
+    case 3:
+        switch (((insn >> 2) & 0b11111)) {
+        case 8:
+            switch (((insn >> 12) & 0b111)) {
+            case 0: /* sb */
+            case 1: /* sh */
+            case 2: /* sw */
+            case 3: /* sd */
+            case 4: /* sq */
+                return true;
+            default:
+                break;
+            }
+            break;
+        case 9:
+            switch (((insn >> 12) & 0b111)) {
+            case 2: /* fsw */
+            case 3: /* fsd */
+            case 4: /* fsq */
+                return true;
+            default:
+                break;
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    /* Check for compressed instructions */
+    switch (((insn >> 13) & 0b111)) {
+    case 7:
+        switch (insn & 0b11) {
+        case 0: /*c.sd */
+        case 2: /* c.sdsp */
+            return true;
+        default:
+            break;
+        }
+        break;
+    case 6:
+        switch (insn & 0b11) {
+        case 0: /* c.sw */
+        case 3: /* c.swsp */
+            return true;
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 42d1ad189b..01e7e69e7f 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -139,64 +139,6 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
     }
 }
 
-/*
- * 'pc' is the host PC at which the exception was raised.
- * 'address' is the effective address of the memory exception.
- * 'is_write' is 1 if a write caused the exception and otherwise 0.
- * 'old_set' is the signal set which should be restored.
- */
-static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
-                                    int is_write, sigset_t *old_set)
-{
-    CPUState *cpu = current_cpu;
-    CPUClass *cc;
-    unsigned long host_addr = (unsigned long)info->si_addr;
-    MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
-    abi_ptr guest_addr;
-
-    /* For synchronous signals we expect to be coming from the vCPU
-     * thread (so current_cpu should be valid) and either from running
-     * code or during translation which can fault as we cross pages.
-     *
-     * If neither is true then something has gone wrong and we should
-     * abort rather than try and restart the vCPU execution.
-     */
-    if (!cpu || !cpu->running) {
-        printf("qemu:%s received signal outside vCPU context @ pc=0x%"
-               PRIxPTR "\n",  __func__, pc);
-        abort();
-    }
-
-#if defined(DEBUG_SIGNAL)
-    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-           pc, host_addr, is_write, *(unsigned long *)old_set);
-#endif
-
-    /* Convert forcefully to guest address space, invalid addresses
-       are still valid segv ones */
-    guest_addr = h2g_nocheck(host_addr);
-
-    /* XXX: locking issue */
-    if (is_write &&
-        info->si_signo == SIGSEGV &&
-        info->si_code == SEGV_ACCERR &&
-        h2g_valid(host_addr) &&
-        handle_sigsegv_accerr_write(cpu, old_set, pc, guest_addr)) {
-        return 1;
-    }
-
-    /*
-     * There is no way the target can handle this other than raising
-     * an exception.  Undo signal and retaddr state prior to longjmp.
-     */
-    sigprocmask(SIG_SETMASK, old_set, NULL);
-
-    cc = CPU_GET_CLASS(cpu);
-    cc->tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
-                          MMU_USER_IDX, false, pc);
-    g_assert_not_reached();
-}
-
 static int probe_access_internal(CPUArchState *env, target_ulong addr,
                                  int fault_size, MMUAccessType access_type,
                                  bool nonfault, uintptr_t ra)
@@ -255,82 +197,6 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
     return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__riscv)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    ucontext_t *uc = puc;
-    greg_t pc = uc->uc_mcontext.__gregs[REG_PC];
-    uint32_t insn = *(uint32_t *)pc;
-    int is_write = 0;
-
-    /* Detect store by reading the instruction at the program
-       counter. Note: we currently only generate 32-bit
-       instructions so we thus only detect 32-bit stores */
-    switch (((insn >> 0) & 0b11)) {
-    case 3:
-        switch (((insn >> 2) & 0b11111)) {
-        case 8:
-            switch (((insn >> 12) & 0b111)) {
-            case 0: /* sb */
-            case 1: /* sh */
-            case 2: /* sw */
-            case 3: /* sd */
-            case 4: /* sq */
-                is_write = 1;
-                break;
-            default:
-                break;
-            }
-            break;
-        case 9:
-            switch (((insn >> 12) & 0b111)) {
-            case 2: /* fsw */
-            case 3: /* fsd */
-            case 4: /* fsq */
-                is_write = 1;
-                break;
-            default:
-                break;
-            }
-            break;
-        default:
-            break;
-        }
-    }
-
-    /* Check for compressed instructions */
-    switch (((insn >> 13) & 0b111)) {
-    case 7:
-        switch (insn & 0b11) {
-        case 0: /*c.sd */
-        case 2: /* c.sdsp */
-            is_write = 1;
-            break;
-        default:
-            break;
-        }
-        break;
-    case 6:
-        switch (insn & 0b11) {
-        case 0: /* c.sw */
-        case 3: /* c.swsp */
-            is_write = 1;
-            break;
-        default:
-            break;
-        }
-        break;
-    default:
-        break;
-    }
-
-    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-#endif
-
 /* The softmmu versions of these helpers are in cputlb.c.  */
 
 uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr)
-- 
2.25.1



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

* [PATCH v2 16/41] target/arm: Fixup comment re handle_cpu_signal
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (14 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 15/41] linux-user/host/riscv: " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 17/41] linux-user/host/riscv: Improve host_signal_write Richard Henderson
                   ` (25 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The named function no longer exists.
Refer to host_signal_handler instead.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/sve_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index dab5f1d1cd..07be55b7e1 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -6118,7 +6118,7 @@ DO_LDN_2(4, dd, MO_64)
  * linux-user/ in its get_user/put_user macros.
  *
  * TODO: Construct some helpers, written in assembly, that interact with
- * handle_cpu_signal to produce memory ops which can properly report errors
+ * host_signal_handler to produce memory ops which can properly report errors
  * without racing.
  */
 
-- 
2.25.1



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

* [PATCH v2 17/41] linux-user/host/riscv: Improve host_signal_write
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (15 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 16/41] target/arm: Fixup comment re handle_cpu_signal Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER Richard Henderson
                   ` (24 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Do not read 4 bytes before we determine the size of the insn.
Simplify triple switches in favor of checking major opcodes.
Include the missing cases of compact fsd and fsdsp.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/host/riscv/host-signal.h | 83 ++++++++++-------------------
 1 file changed, 28 insertions(+), 55 deletions(-)

diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h
index 5860dce7d7..ab06d70964 100644
--- a/linux-user/host/riscv/host-signal.h
+++ b/linux-user/host/riscv/host-signal.h
@@ -17,65 +17,38 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
 
 static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
 {
-    uint32_t insn = *(uint32_t *)host_signal_pc(uc);
-
     /*
-     * Detect store by reading the instruction at the program
-     * counter. Note: we currently only generate 32-bit
-     * instructions so we thus only detect 32-bit stores
+     * Detect store by reading the instruction at the program counter.
+     * Do not read more than 16 bits, because we have not yet determined
+     * the size of the instruction.
      */
-    switch (((insn >> 0) & 0b11)) {
-    case 3:
-        switch (((insn >> 2) & 0b11111)) {
-        case 8:
-            switch (((insn >> 12) & 0b111)) {
-            case 0: /* sb */
-            case 1: /* sh */
-            case 2: /* sw */
-            case 3: /* sd */
-            case 4: /* sq */
-                return true;
-            default:
-                break;
-            }
-            break;
-        case 9:
-            switch (((insn >> 12) & 0b111)) {
-            case 2: /* fsw */
-            case 3: /* fsd */
-            case 4: /* fsq */
-                return true;
-            default:
-                break;
-            }
-            break;
-        default:
-            break;
-        }
+    const uint16_t *pinsn = (const uint16_t *)host_signal_pc(uc);
+    uint16_t insn = pinsn[0];
+
+    /* 16-bit instructions */
+    switch (insn & 0xe003) {
+    case 0xa000: /* c.fsd */
+    case 0xc000: /* c.sw */
+    case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */
+    case 0xa002: /* c.fsdsp */
+    case 0xc002: /* c.swsp */
+    case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */
+        return true;
     }
 
-    /* Check for compressed instructions */
-    switch (((insn >> 13) & 0b111)) {
-    case 7:
-        switch (insn & 0b11) {
-        case 0: /*c.sd */
-        case 2: /* c.sdsp */
-            return true;
-        default:
-            break;
-        }
-        break;
-    case 6:
-        switch (insn & 0b11) {
-        case 0: /* c.sw */
-        case 3: /* c.swsp */
-            return true;
-        default:
-            break;
-        }
-        break;
-    default:
-        break;
+    /* 32-bit instructions, major opcodes */
+    switch (insn & 0x7f) {
+    case 0x23: /* store */
+    case 0x27: /* store-fp */
+        return true;
+    case 0x2f: /* amo */
+        /*
+         * The AMO function code is in bits 25-31, unread as yet.
+         * The AMO functions are LR (read), SC (write), and the
+         * rest are all read-modify-write.
+         */
+        insn = pinsn[1];
+        return (insn >> 11) != 2; /* LR */
     }
 
     return false;
-- 
2.25.1



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

* [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (16 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 17/41] linux-user/host/riscv: Improve host_signal_write Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:18   ` Philippe Mathieu-Daudé
  2021-09-19 18:59   ` Warner Losh
  2021-09-18 18:45 ` [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv Richard Henderson
                   ` (23 subsequent siblings)
  41 siblings, 2 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Now that all of the linux-user hosts have been converted
to host-signal.h, drop the compatibility code.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/exec/exec-all.h | 12 ------------
 linux-user/signal.c     | 13 -------------
 2 files changed, 25 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5f94d799aa..5dd663c153 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -685,18 +685,6 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
 bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
                                  uintptr_t host_pc, abi_ptr guest_addr);
 
-/**
- * cpu_signal_handler
- * @signum: host signal number
- * @pinfo: host siginfo_t
- * @puc: host ucontext_t
- *
- * To be called from the SIGBUS and SIGSEGV signal handler to inform the
- * virtual cpu of exceptions.  Returns true if the signal was handled by
- * the virtual CPU.
- */
-int cpu_signal_handler(int signum, void *pinfo, void *puc);
-
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 6f953f10d4..e6531fdfa0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -773,16 +773,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
     ucontext_t *uc = puc;
     struct emulated_sigtable *k;
     int guest_sig;
-
-#ifdef HOST_SIGNAL_PLACEHOLDER
-    /* the CPU emulator uses some host signals to detect exceptions,
-       we forward to it some signals */
-    if ((host_sig == SIGSEGV || host_sig == SIGBUS)
-        && info->si_code > 0) {
-        if (cpu_signal_handler(host_sig, info, puc))
-            return;
-    }
-#else
     uintptr_t pc = 0;
     bool sync_sig = false;
 
@@ -842,7 +832,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
 
         sync_sig = true;
     }
-#endif
 
     /* get target signal number */
     guest_sig = host_to_target_signal(host_sig);
@@ -857,7 +846,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
     k->pending = guest_sig;
     ts->signal_pending = 1;
 
-#ifndef HOST_SIGNAL_PLACEHOLDER
     /*
      * For synchronous signals, unwind the cpu state to the faulting
      * insn and then exit back to the main loop so that the signal
@@ -867,7 +855,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
         cpu->exception_index = EXCP_INTERRUPT;
         cpu_loop_exit_restore(cpu, pc);
     }
-#endif
 
     rewind_if_in_safe_syscall(puc);
 
-- 
2.25.1



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

* [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (17 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:22   ` Philippe Mathieu-Daudé
  2021-09-18 18:45 ` [PATCH v2 20/41] linux-user: Add raise_sigsegv Richard Henderson
                   ` (22 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Add a new user-only interface for updating cpu state before
raising a signal.  This will replace tlb_fill for user-only
and should result in less boilerplate for each guest.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 4a4c4053e3..e229a40772 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -114,6 +114,32 @@ struct TCGCPUOps {
      */
     bool (*io_recompile_replay_branch)(CPUState *cpu,
                                        const TranslationBlock *tb);
+#else
+    /**
+     * record_sigsegv:
+     * @cpu: cpu context
+     * @addr: faulting guest address
+     * @access_type: access was read/write/execute
+     * @maperr: true for invalid page, false for permission fault
+     * @ra: host pc for unwinding
+     *
+     * We are about to raise SIGSEGV with si_code set for @maperr,
+     * and si_addr set for @addr.  Record anything further needed
+     * for the signal ucontext_t.
+     *
+     * If the emulated kernel does not provide anything to the signal
+     * handler with anything besides the user context registers, and
+     * the siginfo_t, then this hook need do nothing and may be omitted.
+     * Otherwise, record the data and return; the caller will raise
+     * the signal, unwind the cpu state, and return to the main loop.
+     *
+     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
+     * so that a "normal" cpu exception can be raised.  In this case,
+     * the signal must be raised by the architecture cpu_loop.
+     */
+    void (*record_sigsegv)(CPUState *cpu, vaddr addr,
+                           MMUAccessType access_type,
+                           bool maperr, uintptr_t ra);
 #endif /* CONFIG_SOFTMMU */
 #endif /* NEED_CPU_H */
 
-- 
2.25.1



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

* [PATCH v2 20/41] linux-user: Add raise_sigsegv
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (18 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:26   ` Philippe Mathieu-Daudé
  2021-09-19 18:35   ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 21/41] target/alpha: Make alpha_cpu_tlb_fill sysemu only Richard Henderson
                   ` (21 subsequent siblings)
  41 siblings, 2 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This is a new interface to be provided by the os emulator
for raising SIGSEGV on fault.  Use the new record_sigsegv
target hook.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/exec/exec-all.h | 15 +++++++++++++++
 accel/tcg/user-exec.c   | 33 ++++++++++++++++++---------------
 linux-user/signal.c     | 30 ++++++++++++++++++++++--------
 3 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5dd663c153..2091c1bf1a 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -685,6 +685,21 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
 bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
                                  uintptr_t host_pc, abi_ptr guest_addr);
 
+/**
+ * raise_sigsegv:
+ * @cpu: the cpu context
+ * @addr: the guest address of the fault
+ * @access_type: access was read/write/execute
+ * @maperr: true for invalid page, false for permission fault
+ * @ra: host pc for unwinding
+ *
+ * Use the TCGCPUOps hook to record cpu state, do guest operating system
+ * specific things to raise SIGSEGV, and jump to the main cpu loop.
+ */
+void QEMU_NORETURN raise_sigsegv(CPUState *cpu, target_ulong addr,
+                                 MMUAccessType access_type,
+                                 bool maperr, uintptr_t ra);
+
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 01e7e69e7f..ab9cc6686d 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -143,35 +143,38 @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
                                  int fault_size, MMUAccessType access_type,
                                  bool nonfault, uintptr_t ra)
 {
-    int flags;
+    bool maperr = true;
+    int acc_flag;
 
     switch (access_type) {
     case MMU_DATA_STORE:
-        flags = PAGE_WRITE;
+        acc_flag = PAGE_WRITE_ORG;
         break;
     case MMU_DATA_LOAD:
-        flags = PAGE_READ;
+        acc_flag = PAGE_READ;
         break;
     case MMU_INST_FETCH:
-        flags = PAGE_EXEC;
+        acc_flag = PAGE_EXEC;
         break;
     default:
         g_assert_not_reached();
     }
 
-    if (!guest_addr_valid_untagged(addr) ||
-        page_check_range(addr, 1, flags) < 0) {
-        if (nonfault) {
-            return TLB_INVALID_MASK;
-        } else {
-            CPUState *cpu = env_cpu(env);
-            CPUClass *cc = CPU_GET_CLASS(cpu);
-            cc->tcg_ops->tlb_fill(cpu, addr, fault_size, access_type,
-                                  MMU_USER_IDX, false, ra);
-            g_assert_not_reached();
+    if (guest_addr_valid_untagged(addr)) {
+        int page_flags = page_get_flags(addr);
+        if (page_flags & acc_flag) {
+            return 0; /* success */
+        }
+        if (page_flags & PAGE_VALID) {
+            maperr = false;
         }
     }
-    return 0;
+
+    if (nonfault) {
+        return TLB_INVALID_MASK;
+    }
+
+    raise_sigsegv(env_cpu(env), addr, access_type, maperr, ra);
 }
 
 int probe_access_flags(CPUArchState *env, target_ulong addr,
diff --git a/linux-user/signal.c b/linux-user/signal.c
index e6531fdfa0..ae31b46be0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -681,9 +681,27 @@ void force_sigsegv(int oldsig)
     }
     force_sig(TARGET_SIGSEGV);
 }
-
 #endif
 
+void raise_sigsegv(CPUState *cpu, target_ulong addr,
+                   MMUAccessType access_type, bool maperr, uintptr_t ra)
+{
+    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);
+    } else if (tcg_ops->tlb_fill) {
+        tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
+        g_assert_not_reached();
+    }
+
+    force_sig_fault(TARGET_SIGSEGV,
+                    maperr ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR,
+                    addr);
+    cpu->exception_index = EXCP_INTERRUPT;
+    cpu_loop_exit_restore(cpu, ra);
+}
+
 /* abort execution with signal */
 static void QEMU_NORETURN dump_core_and_abort(int target_sig)
 {
@@ -799,7 +817,7 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
         access_type = adjust_signal_pc(&pc, is_write);
 
         if (host_sig == SIGSEGV) {
-            const struct TCGCPUOps *tcg_ops;
+            bool maperr = true;
 
             if (info->si_code == SEGV_ACCERR && h2g_valid(host_addr)) {
                 /* If this was a write to a TB protected page, restart. */
@@ -814,18 +832,14 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
                  * which means that we may get ACCERR when we want MAPERR.
                  */
                 if (page_get_flags(guest_addr) & PAGE_VALID) {
-                    /* maperr = false; */
+                    maperr = false;
                 } else {
                     info->si_code = SEGV_MAPERR;
                 }
             }
 
             sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
-
-            tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
-            tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
-                              MMU_USER_IDX, false, pc);
-            g_assert_not_reached();
+            raise_sigsegv(cpu, guest_addr, access_type, maperr, pc);
         } else {
             sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
         }
-- 
2.25.1



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

* [PATCH v2 21/41] target/alpha: Make alpha_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (19 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 20/41] linux-user: Add raise_sigsegv Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 22/41] target/arm: Use raise_sigsegv for mte tag lookup Richard Henderson
                   ` (20 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for alpha-linux-user.
Remove the code from cpu_loop that handled EXCP_MMFAULT.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/alpha/cpu.h          |  7 ++++---
 linux-user/alpha/cpu_loop.c |  8 --------
 target/alpha/cpu.c          |  2 +-
 target/alpha/helper.c       | 13 +------------
 4 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index ce9ec32199..cbca4c369c 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -439,9 +439,6 @@ void alpha_translate_init(void);
 #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
 
 void alpha_cpu_list(void);
-bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                        MMUAccessType access_type, int mmu_idx,
-                        bool probe, uintptr_t retaddr);
 void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 
@@ -449,12 +446,16 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
 uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg);
 void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val);
+
 #ifndef CONFIG_USER_ONLY
 void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                      vaddr addr, unsigned size,
                                      MMUAccessType access_type,
                                      int mmu_idx, MemTxAttrs attrs,
                                      MemTxResult response, uintptr_t retaddr);
+bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                        MMUAccessType access_type, int mmu_idx,
+                        bool probe, uintptr_t retaddr);
 #endif
 
 static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 7ce2461a02..60b650a827 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -52,14 +52,6 @@ void cpu_loop(CPUAlphaState *env)
             fprintf(stderr, "External interrupt. Exit\n");
             exit(EXIT_FAILURE);
             break;
-        case EXCP_MMFAULT:
-            info.si_signo = TARGET_SIGSEGV;
-            info.si_errno = 0;
-            info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
-                            ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
-            info._sifields._sigfault._addr = env->trap_arg0;
-            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            break;
         case EXCP_UNALIGN:
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 1ca601cac5..83c201d86a 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -220,10 +220,10 @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
 
 static const struct TCGCPUOps alpha_tcg_ops = {
     .initialize = alpha_translate_init,
-    .tlb_fill = alpha_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = alpha_cpu_has_work,
+    .tlb_fill = alpha_cpu_tlb_fill,
     .cpu_exec_interrupt = alpha_cpu_exec_interrupt,
     .do_interrupt = alpha_cpu_do_interrupt,
     .do_transaction_failed = alpha_cpu_do_transaction_failed,
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 81550d9e2f..266d56ea73 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -119,18 +119,7 @@ void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val)
     *cpu_alpha_addr_gr(env, reg) = val;
 }
 
-#if defined(CONFIG_USER_ONLY)
-bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                        MMUAccessType access_type, int mmu_idx,
-                        bool probe, uintptr_t retaddr)
-{
-    AlphaCPU *cpu = ALPHA_CPU(cs);
-
-    cs->exception_index = EXCP_MMFAULT;
-    cpu->env.trap_arg0 = address;
-    cpu_loop_exit_restore(cs, retaddr);
-}
-#else
+#ifndef CONFIG_USER_ONLY
 /* Returns the OSF/1 entMM failure indication, or -1 on success.  */
 static int get_physical_address(CPUAlphaState *env, target_ulong addr,
                                 int prot_need, int mmu_idx,
-- 
2.25.1



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

* [PATCH v2 22/41] target/arm: Use raise_sigsegv for mte tag lookup
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (20 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 21/41] target/alpha: Make alpha_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 23/41] target/arm: Implement arm_cpu_record_sigsegv Richard Henderson
                   ` (19 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Use the new os interface for raising the exception,
rather than calling arm_cpu_tlb_fill directly.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/mte_helper.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 724175210b..2575e65860 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -84,10 +84,8 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
     uintptr_t index;
 
     if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE_ORG : PAGE_READ))) {
-        /* SIGSEGV */
-        arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access,
-                         ptr_mmu_idx, false, ra);
-        g_assert_not_reached();
+        raise_sigsegv(env_cpu(env), ptr, ptr_access,
+                      !(flags & PAGE_VALID), ra);
     }
 
     /* Require both MAP_ANON and PROT_MTE for the page. */
-- 
2.25.1



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

* [PATCH v2 23/41] target/arm: Implement arm_cpu_record_sigsegv
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (21 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 22/41] target/arm: Use raise_sigsegv for mte tag lookup Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only Richard Henderson
                   ` (18 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Because of the complexity of setting ESR, continue to use
arm_deliver_fault.  This means we cannot remove the code
within cpu_loop that decodes EXCP_DATA_ABORT and
EXCP_PREFETCH_ABORT.

But using the new hook means that we don't have to do the
page_get_flags check manually, and we'll be able to restrict
the tlb_fill hook to sysemu later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h  |  6 ++++++
 target/arm/cpu.c        |  6 ++++--
 target/arm/cpu_tcg.c    |  6 ++++--
 target/arm/tlb_helper.c | 36 +++++++++++++++++++-----------------
 4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index cd2ea8a388..480145b382 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -544,9 +544,15 @@ static inline bool arm_extabort_type(MemTxResult result)
     return result != MEMTX_DECODE_ERROR;
 }
 
+#ifdef CONFIG_USER_ONLY
+void arm_cpu_record_sigsegv(CPUState *cpu, vaddr addr,
+                            MMUAccessType access_type,
+                            bool maperr, uintptr_t ra);
+#else
 bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                       MMUAccessType access_type, int mmu_idx,
                       bool probe, uintptr_t retaddr);
+#endif
 
 static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
 {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e11aa625a5..4fc01768ab 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2016,10 +2016,12 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
 static const struct TCGCPUOps arm_tcg_ops = {
     .initialize = arm_translate_init,
     .synchronize_from_tb = arm_cpu_synchronize_from_tb,
-    .tlb_fill = arm_cpu_tlb_fill,
     .debug_excp_handler = arm_debug_excp_handler,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+    .record_sigsegv = arm_cpu_record_sigsegv,
+#else
+    .tlb_fill = arm_cpu_tlb_fill,
     .has_work = arm_cpu_has_work,
     .cpu_exec_interrupt = arm_cpu_exec_interrupt,
     .do_interrupt = arm_cpu_do_interrupt,
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0d5adccf1a..7b3bea2fbb 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -898,10 +898,12 @@ static void pxa270c5_initfn(Object *obj)
 static const struct TCGCPUOps arm_v7m_tcg_ops = {
     .initialize = arm_translate_init,
     .synchronize_from_tb = arm_cpu_synchronize_from_tb,
-    .tlb_fill = arm_cpu_tlb_fill,
     .debug_excp_handler = arm_debug_excp_handler,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+    .record_sigsegv = arm_cpu_record_sigsegv,
+#else
+    .tlb_fill = arm_cpu_tlb_fill,
     .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
     .do_interrupt = arm_v7m_cpu_do_interrupt,
     .do_transaction_failed = arm_cpu_do_transaction_failed,
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index 3107f9823e..dc5860180f 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -147,28 +147,12 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
     arm_deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
 }
 
-#endif /* !defined(CONFIG_USER_ONLY) */
-
 bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                       MMUAccessType access_type, int mmu_idx,
                       bool probe, uintptr_t retaddr)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     ARMMMUFaultInfo fi = {};
-
-#ifdef CONFIG_USER_ONLY
-    int flags = page_get_flags(useronly_clean_ptr(address));
-    if (flags & PAGE_VALID) {
-        fi.type = ARMFault_Permission;
-    } else {
-        fi.type = ARMFault_Translation;
-    }
-    fi.level = 3;
-
-    /* now we have a real cpu fault */
-    cpu_restore_state(cs, retaddr, true);
-    arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
-#else
     hwaddr phys_addr;
     target_ulong page_size;
     int prot, ret;
@@ -210,5 +194,23 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         cpu_restore_state(cs, retaddr, true);
         arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
     }
-#endif
 }
+#else
+void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+                            MMUAccessType access_type,
+                            bool maperr, uintptr_t ra)
+{
+    ARMMMUFaultInfo fi = {
+        .type = maperr ? ARMFault_Translation : ARMFault_Permission,
+        .level = 3,
+    };
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    /*
+     * We report both ESR and FAR to signal handlers.
+     * For now, it's easiest to deliver the fault normally.
+     */
+    cpu_restore_state(cs, ra, true);
+    arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, &fi);
+}
+#endif /* !defined(CONFIG_USER_ONLY) */
-- 
2.25.1



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

* [PATCH v2 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (22 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 23/41] target/arm: Implement arm_cpu_record_sigsegv Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:28   ` Philippe Mathieu-Daudé
  2021-09-18 18:45 ` [PATCH v2 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill Richard Henderson
                   ` (17 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for cris-linux-user.
Remove the code from cpu_loop that handled the unnamed 0xaa exception.

This makes all of the code in helper.c sysemu only, so remove the
ifdefs and move the file to cris_softmmu_ss.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/cpu.h          |  8 ++++----
 linux-user/cris/cpu_loop.c | 10 ----------
 target/cris/cpu.c          |  4 ++--
 target/cris/helper.c       | 18 ------------------
 target/cris/meson.build    |  7 +++++--
 5 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 6603565f83..b445b194ea 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -189,6 +189,10 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void crisv10_cpu_do_interrupt(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                       MMUAccessType access_type, int mmu_idx,
+                       bool probe, uintptr_t retaddr);
 #endif
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
@@ -251,10 +255,6 @@ static inline int cpu_mmu_index (CPUCRISState *env, bool ifetch)
 	return !!(env->pregs[PR_CCS] & U_FLAG);
 }
 
-bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr);
-
 /* Support function regs.  */
 #define SFR_RW_GC_CFG      0][0
 #define SFR_RW_MM_CFG      env->pregs[PR_SRS]][0
diff --git a/linux-user/cris/cpu_loop.c b/linux-user/cris/cpu_loop.c
index 334edddd1e..0de941c0b4 100644
--- a/linux-user/cris/cpu_loop.c
+++ b/linux-user/cris/cpu_loop.c
@@ -35,16 +35,6 @@ void cpu_loop(CPUCRISState *env)
         process_queued_cpu_work(cs);
 
         switch (trapnr) {
-        case 0xaa:
-            {
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = env->pregs[PR_EDA];
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            }
-            break;
         case EXCP_INTERRUPT:
           /* just indicate that signals should be handled asap */
           break;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index b9f30ba58f..b8ac1b9f25 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -207,10 +207,10 @@ static const struct SysemuCPUOps cris_sysemu_ops = {
 
 static const struct TCGCPUOps crisv10_tcg_ops = {
     .initialize = cris_initialize_crisv10_tcg,
-    .tlb_fill = cris_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = cris_cpu_has_work,
+    .tlb_fill = cris_cpu_tlb_fill,
     .cpu_exec_interrupt = cris_cpu_exec_interrupt,
     .do_interrupt = crisv10_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
@@ -218,9 +218,9 @@ static const struct TCGCPUOps crisv10_tcg_ops = {
 
 static const struct TCGCPUOps crisv32_tcg_ops = {
     .initialize = cris_initialize_tcg,
-    .tlb_fill = cris_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+    .tlb_fill = cris_cpu_tlb_fill,
     .cpu_exec_interrupt = cris_cpu_exec_interrupt,
     .do_interrupt = cris_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 36926faf32..a0d6ecdcd3 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -39,22 +39,6 @@
 #define D_LOG(...) do { } while (0)
 #endif
 
-#if defined(CONFIG_USER_ONLY)
-
-bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr)
-{
-    CRISCPU *cpu = CRIS_CPU(cs);
-
-    cs->exception_index = 0xaa;
-    cpu->env.pregs[PR_EDA] = address;
-    cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
-
 static void cris_shift_ccs(CPUCRISState *env)
 {
     uint32_t ccs;
@@ -304,5 +288,3 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 
     return ret;
 }
-
-#endif /* !CONFIG_USER_ONLY */
diff --git a/target/cris/meson.build b/target/cris/meson.build
index 67c3793c85..c1e326d950 100644
--- a/target/cris/meson.build
+++ b/target/cris/meson.build
@@ -2,13 +2,16 @@ cris_ss = ss.source_set()
 cris_ss.add(files(
   'cpu.c',
   'gdbstub.c',
-  'helper.c',
   'op_helper.c',
   'translate.c',
 ))
 
 cris_softmmu_ss = ss.source_set()
-cris_softmmu_ss.add(files('mmu.c', 'machine.c'))
+cris_softmmu_ss.add(files(
+  'helper.c',
+  'machine.c',
+  'mmu.c',
+))
 
 target_arch += {'cris': cris_ss}
 target_softmmu_arch += {'cris': cris_softmmu_ss}
-- 
2.25.1



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

* [PATCH v2 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (23 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 26/41] target/hppa: Make hppa_cpu_tlb_fill sysemu only Richard Henderson
                   ` (16 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for hexagon.
Remove the code from cpu_loop that raises SIGSEGV.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/hexagon/cpu_loop.c | 24 +-----------------------
 target/hexagon/cpu.c          | 23 -----------------------
 2 files changed, 1 insertion(+), 46 deletions(-)

diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index bc34f5d7c3..244917e27f 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -26,8 +26,7 @@
 void cpu_loop(CPUHexagonState *env)
 {
     CPUState *cs = env_cpu(env);
-    int trapnr, signum, sigcode;
-    target_ulong sigaddr;
+    int trapnr;
     target_ulong syscallnum;
     target_ulong ret;
 
@@ -37,10 +36,6 @@ void cpu_loop(CPUHexagonState *env)
         cpu_exec_end(cs);
         process_queued_cpu_work(cs);
 
-        signum = 0;
-        sigcode = 0;
-        sigaddr = 0;
-
         switch (trapnr) {
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -63,12 +58,6 @@ void cpu_loop(CPUHexagonState *env)
                 env->gpr[0] = ret;
             }
             break;
-        case HEX_EXCP_FETCH_NO_UPAGE:
-        case HEX_EXCP_PRIV_NO_UREAD:
-        case HEX_EXCP_PRIV_NO_UWRITE:
-            signum = TARGET_SIGSEGV;
-            sigcode = TARGET_SEGV_MAPERR;
-            break;
         case EXCP_ATOMIC:
             cpu_exec_step_atomic(cs);
             break;
@@ -77,17 +66,6 @@ void cpu_loop(CPUHexagonState *env)
                      trapnr);
             exit(EXIT_FAILURE);
         }
-
-        if (signum) {
-            target_siginfo_t info = {
-                .si_signo = signum,
-                .si_errno = 0,
-                .si_code = sigcode,
-                ._sifields._sigfault._addr = sigaddr
-            };
-            queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
-        }
-
         process_pending_signals(env);
     }
 }
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index aa01974807..96cd7db170 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -240,34 +240,11 @@ static void hexagon_cpu_init(Object *obj)
     qdev_property_add_static(DEVICE(obj), &hexagon_lldb_stack_adjust_property);
 }
 
-static bool hexagon_tlb_fill(CPUState *cs, vaddr address, int size,
-                             MMUAccessType access_type, int mmu_idx,
-                             bool probe, uintptr_t retaddr)
-{
-#ifdef CONFIG_USER_ONLY
-    switch (access_type) {
-    case MMU_INST_FETCH:
-        cs->exception_index = HEX_EXCP_FETCH_NO_UPAGE;
-        break;
-    case MMU_DATA_LOAD:
-        cs->exception_index = HEX_EXCP_PRIV_NO_UREAD;
-        break;
-    case MMU_DATA_STORE:
-        cs->exception_index = HEX_EXCP_PRIV_NO_UWRITE;
-        break;
-    }
-    cpu_loop_exit_restore(cs, retaddr);
-#else
-#error System mode not implemented for Hexagon
-#endif
-}
-
 #include "hw/core/tcg-cpu-ops.h"
 
 static const struct TCGCPUOps hexagon_tcg_ops = {
     .initialize = hexagon_translate_init,
     .synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
-    .tlb_fill = hexagon_tlb_fill,
 };
 
 static void hexagon_cpu_class_init(ObjectClass *c, void *data)
-- 
2.25.1



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

* [PATCH v2 26/41] target/hppa: Make hppa_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (24 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv Richard Henderson
                   ` (15 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for hppa-linux-user.
Remove the code from cpu_loop that raised SIGSEGV.

This makes all of the code in mem_helper.c sysemu only, so remove the
ifdefs and move the file to hppa_softmmu_ss.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/hppa/cpu.h          |  2 +-
 linux-user/hppa/cpu_loop.c | 16 ----------------
 target/hppa/cpu.c          |  2 +-
 target/hppa/mem_helper.c   | 15 ---------------
 target/hppa/meson.build    |  6 ++++--
 5 files changed, 6 insertions(+), 35 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index d3cb7a279f..294fd7297f 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,10 +323,10 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
+#ifndef CONFIG_USER_ONLY
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr);
-#ifndef CONFIG_USER_ONLY
 void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 82d8183821..a6122b3594 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -142,22 +142,6 @@ void cpu_loop(CPUHPPAState *env)
             env->iaoq_f = env->gr[31];
             env->iaoq_b = env->gr[31] + 4;
             break;
-        case EXCP_ITLB_MISS:
-        case EXCP_DTLB_MISS:
-        case EXCP_NA_ITLB_MISS:
-        case EXCP_NA_DTLB_MISS:
-        case EXCP_IMP:
-        case EXCP_DMP:
-        case EXCP_DMB:
-        case EXCP_PAGE_REF:
-        case EXCP_DMAR:
-        case EXCP_DMPI:
-            info.si_signo = TARGET_SIGSEGV;
-            info.si_errno = 0;
-            info.si_code = TARGET_SEGV_ACCERR;
-            info._sifields._sigfault._addr = env->cr[CR_IOR];
-            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            break;
         case EXCP_UNALIGN:
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index be940ae224..9b92e82af7 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -146,10 +146,10 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
 static const struct TCGCPUOps hppa_tcg_ops = {
     .initialize = hppa_translate_init,
     .synchronize_from_tb = hppa_cpu_synchronize_from_tb,
-    .tlb_fill = hppa_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = hppa_cpu_has_work,
+    .tlb_fill = hppa_cpu_tlb_fill,
     .cpu_exec_interrupt = hppa_cpu_exec_interrupt,
     .do_interrupt = hppa_cpu_do_interrupt,
     .do_unaligned_access = hppa_cpu_do_unaligned_access,
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index afc5b56c3e..bf07445cd1 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -24,20 +24,6 @@
 #include "hw/core/cpu.h"
 #include "trace.h"
 
-#ifdef CONFIG_USER_ONLY
-bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr)
-{
-    HPPACPU *cpu = HPPA_CPU(cs);
-
-    /* ??? Test between data page fault and data memory protection trap,
-       which would affect si_code.  */
-    cs->exception_index = EXCP_DMP;
-    cpu->env.cr[CR_IOR] = address;
-    cpu_loop_exit_restore(cs, retaddr);
-}
-#else
 static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
 {
     int i;
@@ -392,4 +378,3 @@ int hppa_artype_for_page(CPUHPPAState *env, target_ulong vaddr)
     hppa_tlb_entry *ent = hppa_find_tlb(env, vaddr);
     return ent ? ent->ar_type : -1;
 }
-#endif /* CONFIG_USER_ONLY */
diff --git a/target/hppa/meson.build b/target/hppa/meson.build
index 8a7ff82efc..021e42a2d0 100644
--- a/target/hppa/meson.build
+++ b/target/hppa/meson.build
@@ -7,13 +7,15 @@ hppa_ss.add(files(
   'gdbstub.c',
   'helper.c',
   'int_helper.c',
-  'mem_helper.c',
   'op_helper.c',
   'translate.c',
 ))
 
 hppa_softmmu_ss = ss.source_set()
-hppa_softmmu_ss.add(files('machine.c'))
+hppa_softmmu_ss.add(files(
+  'machine.c',
+  'mem_helper.c',
+))
 
 target_arch += {'hppa': hppa_ss}
 target_softmmu_arch += {'hppa': hppa_softmmu_ss}
-- 
2.25.1



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

* [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (25 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 26/41] target/hppa: Make hppa_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:32   ` Philippe Mathieu-Daudé
  2021-09-19 18:59   ` Warner Losh
  2021-09-18 18:45 ` [PATCH v2 28/41] target/m68k: Make m68k_cpu_tlb_fill sysemu only Richard Henderson
                   ` (14 subsequent siblings)
  41 siblings, 2 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Record cr2, error_code, and exception_index.  That last means
that we must exit to cpu_loop ourselves, instead of letting
exception_index being overwritten.

Use the maperr parameter to properly set PG_ERROR_P_MASK.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/helper-tcg.h       |  6 ++++++
 target/i386/tcg/tcg-cpu.c          |  3 ++-
 target/i386/tcg/user/excp_helper.c | 23 +++++++++++++++++------
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 60ca09e95e..0a4401e917 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -43,9 +43,15 @@ bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 #endif
 
 /* helper.c */
+#ifdef CONFIG_USER_ONLY
+void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+                            MMUAccessType access_type,
+                            bool maperr, uintptr_t ra);
+#else
 bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                       MMUAccessType access_type, int mmu_idx,
                       bool probe, uintptr_t retaddr);
+#endif
 
 void breakpoint_handler(CPUState *cs);
 
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index aef050d089..3fab3676b1 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -77,11 +77,12 @@ static const struct TCGCPUOps x86_tcg_ops = {
     .synchronize_from_tb = x86_cpu_synchronize_from_tb,
     .cpu_exec_enter = x86_cpu_exec_enter,
     .cpu_exec_exit = x86_cpu_exec_exit,
-    .tlb_fill = x86_cpu_tlb_fill,
 #ifdef CONFIG_USER_ONLY
     .fake_user_interrupt = x86_cpu_do_interrupt,
+    .record_sigsegv = x86_cpu_record_sigsegv,
 #else
     .has_work = x86_cpu_has_work,
+    .tlb_fill = x86_cpu_tlb_fill,
     .do_interrupt = x86_cpu_do_interrupt,
     .cpu_exec_interrupt = x86_cpu_exec_interrupt,
     .debug_excp_handler = breakpoint_handler,
diff --git a/target/i386/tcg/user/excp_helper.c b/target/i386/tcg/user/excp_helper.c
index a89b5228fd..cd507e2a1b 100644
--- a/target/i386/tcg/user/excp_helper.c
+++ b/target/i386/tcg/user/excp_helper.c
@@ -22,18 +22,29 @@
 #include "exec/exec-all.h"
 #include "tcg/helper-tcg.h"
 
-bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
-                      MMUAccessType access_type, int mmu_idx,
-                      bool probe, uintptr_t retaddr)
+void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+                            MMUAccessType access_type,
+                            bool maperr, uintptr_t ra)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
 
+    /*
+     * The error_code that hw reports as part of the exception frame
+     * is copied to linux sigcontext.err.  The exception_index is
+     * copied to linux sigcontext.trapno.  Short of inventing a new
+     * place to store the trapno, we cannot let our caller raise the
+     * signal and set exception_index to EXCP_INTERRUPT.
+     */
     env->cr[2] = addr;
-    env->error_code = (access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT;
-    env->error_code |= PG_ERROR_U_MASK;
+    env->error_code = ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
+                    | (maperr ? 0 : PG_ERROR_P_MASK)
+                    | PG_ERROR_U_MASK;
     cs->exception_index = EXCP0E_PAGE;
+
+    /* Disable do_interrupt_user. */
     env->exception_is_int = 0;
     env->exception_next_eip = -1;
-    cpu_loop_exit_restore(cs, retaddr);
+
+    cpu_loop_exit_restore(cs, ra);
 }
-- 
2.25.1



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

* [PATCH v2 28/41] target/m68k: Make m68k_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (26 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 29/41] target/microblaze: Make mb_cpu_tlb_fill " Richard Henderson
                   ` (13 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for m68k-linux-user.
Remove the code from cpu_loop that handled EXCP_ACCESS.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/m68k/cpu_loop.c | 10 ----------
 target/m68k/cpu.c          |  2 +-
 target/m68k/helper.c       |  6 +-----
 3 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index c7a500b58c..7d106aa86e 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -88,16 +88,6 @@ void cpu_loop(CPUM68KState *env)
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
             break;
-        case EXCP_ACCESS:
-            {
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = env->mmu.ar;
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            }
-            break;
         case EXCP_DEBUG:
             info.si_signo = TARGET_SIGTRAP;
             info.si_errno = 0;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index ad5d26b5c9..94b7fc90e8 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -517,10 +517,10 @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
 
 static const struct TCGCPUOps m68k_tcg_ops = {
     .initialize = m68k_tcg_init,
-    .tlb_fill = m68k_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = m68k_cpu_has_work,
+    .tlb_fill = m68k_cpu_tlb_fill,
     .cpu_exec_interrupt = m68k_cpu_exec_interrupt,
     .do_interrupt = m68k_cpu_do_interrupt,
     .do_transaction_failed = m68k_cpu_transaction_failed,
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 137a3e1a3d..5728e48585 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -978,16 +978,12 @@ void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
     }
 }
 
-#endif
-
 bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                        MMUAccessType qemu_access_type, int mmu_idx,
                        bool probe, uintptr_t retaddr)
 {
     M68kCPU *cpu = M68K_CPU(cs);
     CPUM68KState *env = &cpu->env;
-
-#ifndef CONFIG_USER_ONLY
     hwaddr physical;
     int prot;
     int access_type;
@@ -1051,12 +1047,12 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     if (!(access_type & ACCESS_STORE)) {
         env->mmu.ssw |= M68K_RW_040;
     }
-#endif
 
     cs->exception_index = EXCP_ACCESS;
     env->mmu.ar = address;
     cpu_loop_exit_restore(cs, retaddr);
 }
+#endif /* !CONFIG_USER_ONLY */
 
 uint32_t HELPER(bitrev)(uint32_t x)
 {
-- 
2.25.1



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

* [PATCH v2 29/41] target/microblaze: Make mb_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (27 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 28/41] target/m68k: Make m68k_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 30/41] target/mips: Make mips_cpu_tlb_fill " Richard Henderson
                   ` (12 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for mb linux-user.
Remove the code from cpu_loop that handled the unnamed 0xaa exception.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h          |  8 ++++----
 linux-user/microblaze/cpu_loop.c | 10 ----------
 target/microblaze/cpu.c          |  2 +-
 target/microblaze/helper.c       | 13 +------------
 4 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 13ed3cd4dd..2f3075d902 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -394,10 +394,6 @@ void mb_tcg_init(void);
 #define MMU_USER_IDX    2
 /* See NB_MMU_MODES further up the file.  */
 
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                     MMUAccessType access_type, int mmu_idx,
-                     bool probe, uintptr_t retaddr);
-
 typedef CPUMBState CPUArchState;
 typedef MicroBlazeCPU ArchCPU;
 
@@ -415,6 +411,10 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
 }
 
 #if !defined(CONFIG_USER_ONLY)
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                     MMUAccessType access_type, int mmu_idx,
+                     bool probe, uintptr_t retaddr);
+
 void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                unsigned size, MMUAccessType access_type,
                                int mmu_idx, MemTxAttrs attrs,
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index c3396a6e09..0b889a04a7 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -35,16 +35,6 @@ void cpu_loop(CPUMBState *env)
         process_queued_cpu_work(cs);
 
         switch (trapnr) {
-        case 0xaa:
-            {
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = 0;
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            }
-            break;
         case EXCP_INTERRUPT:
           /* just indicate that signals should be handled asap */
           break;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 36e6e54048..67a3b80512 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -366,10 +366,10 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
 static const struct TCGCPUOps mb_tcg_ops = {
     .initialize = mb_tcg_init,
     .synchronize_from_tb = mb_cpu_synchronize_from_tb,
-    .tlb_fill = mb_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = mb_cpu_has_work,
+    .tlb_fill = mb_cpu_tlb_fill,
     .cpu_exec_interrupt = mb_cpu_exec_interrupt,
     .do_interrupt = mb_cpu_do_interrupt,
     .do_transaction_failed = mb_cpu_transaction_failed,
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index dd2aecd1d5..a607fe68e5 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -24,18 +24,7 @@
 #include "qemu/host-utils.h"
 #include "exec/log.h"
 
-#if defined(CONFIG_USER_ONLY)
-
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                     MMUAccessType access_type, int mmu_idx,
-                     bool probe, uintptr_t retaddr)
-{
-    cs->exception_index = 0xaa;
-    cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
 static bool mb_cpu_access_is_secure(MicroBlazeCPU *cpu,
                                     MMUAccessType access_type)
 {
-- 
2.25.1



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

* [PATCH v2 30/41] target/mips: Make mips_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (28 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 29/41] target/microblaze: Make mb_cpu_tlb_fill " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 31/41] target/nios2: Make nios2_cpu_tlb_fill " Richard Henderson
                   ` (11 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for mips linux-user.
This means we can remove tcg/user/tlb_helper.c entirely.
Remove the code from cpu_loop that raised SIGSEGV.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/mips/tcg/tcg-internal.h    |  7 ++--
 linux-user/mips/cpu_loop.c        | 11 ------
 target/mips/cpu.c                 |  2 +-
 target/mips/tcg/user/tlb_helper.c | 59 -------------------------------
 target/mips/tcg/meson.build       |  3 --
 target/mips/tcg/user/meson.build  |  3 --
 6 files changed, 5 insertions(+), 80 deletions(-)
 delete mode 100644 target/mips/tcg/user/tlb_helper.c
 delete mode 100644 target/mips/tcg/user/meson.build

diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h
index c7a77ddccd..8ba36a8ef8 100644
--- a/target/mips/tcg/tcg-internal.h
+++ b/target/mips/tcg/tcg-internal.h
@@ -18,9 +18,6 @@
 void mips_tcg_init(void);
 
 void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
-bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr);
 void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
                                   MMUAccessType access_type,
                                   int mmu_idx, uintptr_t retaddr);
@@ -60,6 +57,10 @@ void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                     MemTxResult response, uintptr_t retaddr);
 void cpu_mips_tlb_flush(CPUMIPSState *env);
 
+bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                       MMUAccessType access_type, int mmu_idx,
+                       bool probe, uintptr_t retaddr);
+
 #endif /* !CONFIG_USER_ONLY */
 
 #endif
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 9d813ece4e..40825ca566 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -156,17 +156,6 @@ done_syscall:
             }
             env->active_tc.gpr[2] = ret;
             break;
-        case EXCP_TLBL:
-        case EXCP_TLBS:
-        case EXCP_AdEL:
-        case EXCP_AdES:
-            info.si_signo = TARGET_SIGSEGV;
-            info.si_errno = 0;
-            /* XXX: check env->error_code */
-            info.si_code = TARGET_SEGV_MAPERR;
-            info._sifields._sigfault._addr = env->CP0_BadVAddr;
-            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            break;
         case EXCP_CpU:
         case EXCP_RI:
             info.si_signo = TARGET_SIGILL;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 3639c03f8e..439b2f1635 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -541,10 +541,10 @@ static const struct SysemuCPUOps mips_sysemu_ops = {
 static const struct TCGCPUOps mips_tcg_ops = {
     .initialize = mips_tcg_init,
     .synchronize_from_tb = mips_cpu_synchronize_from_tb,
-    .tlb_fill = mips_cpu_tlb_fill,
 
 #if !defined(CONFIG_USER_ONLY)
     .has_work = mips_cpu_has_work,
+    .tlb_fill = mips_cpu_tlb_fill,
     .cpu_exec_interrupt = mips_cpu_exec_interrupt,
     .do_interrupt = mips_cpu_do_interrupt,
     .do_transaction_failed = mips_cpu_do_transaction_failed,
diff --git a/target/mips/tcg/user/tlb_helper.c b/target/mips/tcg/user/tlb_helper.c
deleted file mode 100644
index 210c6d529e..0000000000
--- a/target/mips/tcg/user/tlb_helper.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * MIPS TLB (Translation lookaside buffer) helpers.
- *
- *  Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "internal.h"
-
-static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
-                                MMUAccessType access_type)
-{
-    CPUState *cs = env_cpu(env);
-
-    env->error_code = 0;
-    if (access_type == MMU_INST_FETCH) {
-        env->error_code |= EXCP_INST_NOTAVAIL;
-    }
-
-    /* Reference to kernel address from user mode or supervisor mode */
-    /* Reference to supervisor address from user mode */
-    if (access_type == MMU_DATA_STORE) {
-        cs->exception_index = EXCP_AdES;
-    } else {
-        cs->exception_index = EXCP_AdEL;
-    }
-
-    /* Raise exception */
-    if (!(env->hflags & MIPS_HFLAG_DM)) {
-        env->CP0_BadVAddr = address;
-    }
-}
-
-bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr)
-{
-    MIPSCPU *cpu = MIPS_CPU(cs);
-    CPUMIPSState *env = &cpu->env;
-
-    /* data access */
-    raise_mmu_exception(env, address, access_type);
-    do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
-}
diff --git a/target/mips/tcg/meson.build b/target/mips/tcg/meson.build
index 8f6f7508b6..98003779ae 100644
--- a/target/mips/tcg/meson.build
+++ b/target/mips/tcg/meson.build
@@ -28,9 +28,6 @@ mips_ss.add(when: 'TARGET_MIPS64', if_true: files(
   'mxu_translate.c',
 ))
 
-if have_user
-  subdir('user')
-endif
 if have_system
   subdir('sysemu')
 endif
diff --git a/target/mips/tcg/user/meson.build b/target/mips/tcg/user/meson.build
deleted file mode 100644
index 79badcd321..0000000000
--- a/target/mips/tcg/user/meson.build
+++ /dev/null
@@ -1,3 +0,0 @@
-mips_user_ss.add(files(
-  'tlb_helper.c',
-))
-- 
2.25.1



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

* [PATCH v2 31/41] target/nios2: Make nios2_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (29 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 30/41] target/mips: Make mips_cpu_tlb_fill " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 32/41] linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE Richard Henderson
                   ` (10 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for nios2.
Remove the code from cpu_loop that handled the unnamed 0xaa exception.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/nios2/cpu_loop.c | 10 ----------
 target/nios2/cpu.c          |  2 +-
 target/nios2/helper.c       |  8 --------
 3 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c
index fd3f853ac2..c06fb6fabd 100644
--- a/linux-user/nios2/cpu_loop.c
+++ b/linux-user/nios2/cpu_loop.c
@@ -106,16 +106,6 @@ void cpu_loop(CPUNios2State *env)
             info.si_code = TARGET_TRAP_BRKPT;
             queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
-        case 0xaa:
-            {
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                /* TODO: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = env->regs[R_PC];
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            }
-            break;
         default:
             EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
                      trapnr);
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 9938d7c291..b9f79b1bb2 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -222,10 +222,10 @@ static const struct SysemuCPUOps nios2_sysemu_ops = {
 
 static const struct TCGCPUOps nios2_tcg_ops = {
     .initialize = nios2_tcg_init,
-    .tlb_fill = nios2_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = nios2_cpu_has_work,
+    .tlb_fill = nios2_cpu_tlb_fill,
     .cpu_exec_interrupt = nios2_cpu_exec_interrupt,
     .do_interrupt = nios2_cpu_do_interrupt,
     .do_unaligned_access = nios2_cpu_do_unaligned_access,
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 53be8398e9..8b9b55ec67 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -38,14 +38,6 @@ void nios2_cpu_do_interrupt(CPUState *cs)
     env->regs[R_EA] = env->regs[R_PC] + 4;
 }
 
-bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                        MMUAccessType access_type, int mmu_idx,
-                        bool probe, uintptr_t retaddr)
-{
-    cs->exception_index = 0xaa;
-    cpu_loop_exit_restore(cs, retaddr);
-}
-
 #else /* !CONFIG_USER_ONLY */
 
 void nios2_cpu_do_interrupt(CPUState *cs)
-- 
2.25.1



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

* [PATCH v2 32/41] linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (30 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 31/41] target/nios2: Make nios2_cpu_tlb_fill " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 33/41] target/openrisc: Make openrisc_cpu_tlb_fill sysemu only Richard Henderson
                   ` (9 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The kernel vectors both of these through unhandled_exception, which
results in force_sig(SIGSEGV).  This isn't very useful for userland
when enabling overflow traps or fpu traps, but c'est la vie.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/openrisc/cpu_loop.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index b33fa77718..314e7fba1e 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -21,6 +21,7 @@
 #include "qemu-common.h"
 #include "qemu.h"
 #include "cpu_loop-common.h"
+#include "signal-common.h"
 
 void cpu_loop(CPUOpenRISCState *env)
 {
@@ -54,13 +55,17 @@ void cpu_loop(CPUOpenRISCState *env)
             break;
         case EXCP_DPF:
         case EXCP_IPF:
-        case EXCP_RANGE:
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
             info.si_code = TARGET_SEGV_MAPERR;
             info._sifields._sigfault._addr = env->pc;
             queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
+        case EXCP_RANGE:
+        case EXCP_FPE:
+            /* ??? The kernel vectors both of these to unhandled_exception. */
+            force_sig(TARGET_SIGSEGV);
+            break;
         case EXCP_ALIGN:
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
@@ -75,13 +80,6 @@ void cpu_loop(CPUOpenRISCState *env)
             info._sifields._sigfault._addr = env->pc;
             queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
-        case EXCP_FPE:
-            info.si_signo = TARGET_SIGFPE;
-            info.si_errno = 0;
-            info.si_code = 0;
-            info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            break;
         case EXCP_INTERRUPT:
             /* We processed the pending cpu work above.  */
             break;
-- 
2.25.1



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

* [PATCH v2 33/41] target/openrisc: Make openrisc_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (31 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 32/41] linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 34/41] target/ppc: Implement ppc_cpu_record_sigsegv Richard Henderson
                   ` (8 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for openrisc.
This makes all of the code in mmu.c sysemu only, so remove
the ifdefs and move the file to openrisc_softmmu_ss.
Remove the code from cpu_loop that handled EXCP_DPF.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h          | 7 ++++---
 linux-user/openrisc/cpu_loop.c | 8 --------
 target/openrisc/cpu.c          | 2 +-
 target/openrisc/mmu.c          | 8 --------
 target/openrisc/meson.build    | 2 +-
 5 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 187a4a114e..ee069b080c 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,14 +317,15 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void openrisc_translate_init(void);
-bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                           MMUAccessType access_type, int mmu_idx,
-                           bool probe, uintptr_t retaddr);
 int print_insn_or1k(bfd_vma addr, disassemble_info *info);
 
 #define cpu_list cpu_openrisc_list
 
 #ifndef CONFIG_USER_ONLY
+bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                           MMUAccessType access_type, int mmu_idx,
+                           bool probe, uintptr_t retaddr);
+
 extern const VMStateDescription vmstate_openrisc_cpu;
 
 void openrisc_cpu_do_interrupt(CPUState *cpu);
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index 314e7fba1e..5e50c0d743 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -53,14 +53,6 @@ void cpu_loop(CPUOpenRISCState *env)
                 cpu_set_gpr(env, 11, ret);
             }
             break;
-        case EXCP_DPF:
-        case EXCP_IPF:
-            info.si_signo = TARGET_SIGSEGV;
-            info.si_errno = 0;
-            info.si_code = TARGET_SEGV_MAPERR;
-            info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            break;
         case EXCP_RANGE:
         case EXCP_FPE:
             /* ??? The kernel vectors both of these to unhandled_exception. */
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 3c368a1bde..0092fc161d 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -188,10 +188,10 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
 
 static const struct TCGCPUOps openrisc_tcg_ops = {
     .initialize = openrisc_translate_init,
-    .tlb_fill = openrisc_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = openrisc_cpu_has_work,
+    .tlb_fill = openrisc_cpu_tlb_fill,
     .cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
     .do_interrupt = openrisc_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 94df8c7bef..91cedf4125 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -23,11 +23,8 @@
 #include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 #include "qemu/host-utils.h"
-#ifndef CONFIG_USER_ONLY
 #include "hw/loader.h"
-#endif
 
-#ifndef CONFIG_USER_ONLY
 static inline void get_phys_nommu(hwaddr *phys_addr, int *prot,
                                   target_ulong address)
 {
@@ -94,7 +91,6 @@ static int get_phys_mmu(OpenRISCCPU *cpu, hwaddr *phys_addr, int *prot,
         return need & PAGE_EXEC ? EXCP_ITLBMISS : EXCP_DTLBMISS;
     }
 }
-#endif
 
 static void raise_mmu_exception(OpenRISCCPU *cpu, target_ulong address,
                                 int exception)
@@ -113,7 +109,6 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     int excp = EXCP_DPF;
 
-#ifndef CONFIG_USER_ONLY
     int prot;
     hwaddr phys_addr;
 
@@ -138,13 +133,11 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
     if (probe) {
         return false;
     }
-#endif
 
     raise_mmu_exception(cpu, addr, excp);
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-#ifndef CONFIG_USER_ONLY
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -177,4 +170,3 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         return phys_addr;
     }
 }
-#endif
diff --git a/target/openrisc/meson.build b/target/openrisc/meson.build
index e445dec4a0..84322086ec 100644
--- a/target/openrisc/meson.build
+++ b/target/openrisc/meson.build
@@ -10,7 +10,6 @@ openrisc_ss.add(files(
   'fpu_helper.c',
   'gdbstub.c',
   'interrupt_helper.c',
-  'mmu.c',
   'sys_helper.c',
   'translate.c',
 ))
@@ -19,6 +18,7 @@ openrisc_softmmu_ss = ss.source_set()
 openrisc_softmmu_ss.add(files(
   'interrupt.c',
   'machine.c',
+  'mmu.c',
 ))
 
 target_arch += {'openrisc': openrisc_ss}
-- 
2.25.1



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

* [PATCH v2 34/41] target/ppc: Implement ppc_cpu_record_sigsegv
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (32 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 33/41] target/openrisc: Make openrisc_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:37   ` Philippe Mathieu-Daudé
  2021-09-18 18:45 ` [PATCH v2 35/41] target/riscv: Make riscv_cpu_tlb_fill sysemu only Richard Henderson
                   ` (7 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Record DAR, DSISR, and exception_index.  That last means
that we must exit to cpu_loop ourselves, instead of letting
exception_index being overwritten.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/cpu.h              |  3 ---
 target/ppc/internal.h         |  9 +++++++++
 target/ppc/cpu_init.c         |  6 ++++--
 target/ppc/user_only_helper.c | 15 +++++++++++----
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 01d3773bc7..60d1117845 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1278,9 +1278,6 @@ extern const VMStateDescription vmstate_ppc_cpu;
 
 /*****************************************************************************/
 void ppc_translate_init(void);
-bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                      MMUAccessType access_type, int mmu_idx,
-                      bool probe, uintptr_t retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index b71406fa46..f3e5aa8fbc 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -283,5 +283,14 @@ static inline void pte_invalidate(target_ulong *pte0)
 #define PTE_PTEM_MASK 0x7FFFFFBF
 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
 
+#ifdef CONFIG_USER_ONLY
+void ppc_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+                            MMUAccessType access_type,
+                            bool maperr, uintptr_t ra);
+#else
+bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                      MMUAccessType access_type, int mmu_idx,
+                      bool probe, uintptr_t retaddr);
+#endif
 
 #endif /* PPC_INTERNAL_H */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 5c134adeea..d56fde1215 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -9028,10 +9028,12 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
 
 static const struct TCGCPUOps ppc_tcg_ops = {
   .initialize = ppc_translate_init,
-  .tlb_fill = ppc_cpu_tlb_fill,
 
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+  .record_sigsegv = ppc_cpu_record_sigsegv,
+#else
   .has_work = ppc_cpu_has_work,
+  .tlb_fill = ppc_cpu_tlb_fill,
   .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
   .do_interrupt = ppc_cpu_do_interrupt,
   .cpu_exec_enter = ppc_cpu_exec_enter,
diff --git a/target/ppc/user_only_helper.c b/target/ppc/user_only_helper.c
index aa3f867596..7ff76f7a06 100644
--- a/target/ppc/user_only_helper.c
+++ b/target/ppc/user_only_helper.c
@@ -21,16 +21,23 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
+#include "internal.h"
 
-
-bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                      MMUAccessType access_type, int mmu_idx,
-                      bool probe, uintptr_t retaddr)
+void ppc_cpu_record_sigsegv(CPUState *cs, vaddr address,
+                            MMUAccessType access_type,
+                            bool maperr, uintptr_t retaddr)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
     int exception, error_code;
 
+    /*
+     * Both DSISR and the "trap number" (exception vector offset,
+     * looked up from exception_index) are present in the linux-user
+     * signal frame.
+     * FIXME: we don't actually populate the trap number properly.
+     * It would be easiest to fill in an env->trap value now.
+     */
     if (access_type == MMU_INST_FETCH) {
         exception = POWERPC_EXCP_ISI;
         error_code = 0x40000000;
-- 
2.25.1



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

* [PATCH v2 35/41] target/riscv: Make riscv_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (33 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 34/41] target/ppc: Implement ppc_cpu_record_sigsegv Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 36/41] target/s390x: Use probe_access_flags in s390_probe_access Richard Henderson
                   ` (6 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for riscv.
Remove the code from cpu_loop that raised SIGSEGV.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/riscv/cpu_loop.c |  7 -------
 target/riscv/cpu.c          |  2 +-
 target/riscv/cpu_helper.c   | 21 +--------------------
 3 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 74a9628dc9..49fa2209a7 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -85,13 +85,6 @@ void cpu_loop(CPURISCVState *env)
             sigcode = TARGET_TRAP_BRKPT;
             sigaddr = env->pc;
             break;
-        case RISCV_EXCP_INST_PAGE_FAULT:
-        case RISCV_EXCP_LOAD_PAGE_FAULT:
-        case RISCV_EXCP_STORE_PAGE_FAULT:
-            signum = TARGET_SIGSEGV;
-            sigcode = TARGET_SEGV_MAPERR;
-            sigaddr = env->badaddr;
-            break;
         case RISCV_EXCP_SEMIHOST:
             env->gpr[xA0] = do_common_semihosting(cs);
             env->pc += 4;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index abb555a8bd..830e5b568f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -642,10 +642,10 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
 static const struct TCGCPUOps riscv_tcg_ops = {
     .initialize = riscv_translate_init,
     .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
-    .tlb_fill = riscv_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = riscv_cpu_has_work,
+    .tlb_fill = riscv_cpu_tlb_fill,
     .cpu_exec_interrupt = riscv_cpu_exec_interrupt,
     .do_interrupt = riscv_cpu_do_interrupt,
     .do_transaction_failed = riscv_cpu_do_transaction_failed,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 701858d670..2260f95c79 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -747,7 +747,6 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                             riscv_cpu_two_stage_lookup(mmu_idx);
     riscv_raise_exception(env, cs->exception_index, retaddr);
 }
-#endif /* !CONFIG_USER_ONLY */
 
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                         MMUAccessType access_type, int mmu_idx,
@@ -755,7 +754,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-#ifndef CONFIG_USER_ONLY
     vaddr im_address;
     hwaddr pa = 0;
     int prot, prot2, prot_pmp;
@@ -887,25 +885,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     }
 
     return true;
-
-#else
-    switch (access_type) {
-    case MMU_INST_FETCH:
-        cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
-        break;
-    case MMU_DATA_LOAD:
-        cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
-        break;
-    case MMU_DATA_STORE:
-        cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
-        break;
-    default:
-        g_assert_not_reached();
-    }
-    env->badaddr = address;
-    cpu_loop_exit_restore(cs, retaddr);
-#endif
 }
+#endif /* !CONFIG_USER_ONLY */
 
 /*
  * Handle Traps
-- 
2.25.1



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

* [PATCH v2 36/41] target/s390x: Use probe_access_flags in s390_probe_access
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (34 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 35/41] target/riscv: Make riscv_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 37/41] target/s390x: Implement s390_cpu_record_sigsegv Richard Henderson
                   ` (5 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Not sure why the user-only code wasn't rewritten to use
probe_access_flags at the same time that the sysemu code
was converted.  For the purpose of user-only, this is an
exact replacement.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/tcg/mem_helper.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index 0bf775a37d..596270e45d 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -142,20 +142,12 @@ static int s390_probe_access(CPUArchState *env, target_ulong addr, int size,
                              MMUAccessType access_type, int mmu_idx,
                              bool nonfault, void **phost, uintptr_t ra)
 {
+#if defined(CONFIG_USER_ONLY)
+    return probe_access_flags(env, addr, access_type, mmu_idx,
+                              nonfault, phost, ra);
+#else
     int flags;
 
-#if defined(CONFIG_USER_ONLY)
-    flags = page_get_flags(addr);
-    if (!(flags & (access_type == MMU_DATA_LOAD ?  PAGE_READ : PAGE_WRITE_ORG))) {
-        env->__excp_addr = addr;
-        flags = (flags & PAGE_VALID) ? PGM_PROTECTION : PGM_ADDRESSING;
-        if (nonfault) {
-            return flags;
-        }
-        tcg_s390_program_interrupt(env, flags, ra);
-    }
-    *phost = g2h(env_cpu(env), addr);
-#else
     /*
      * For !CONFIG_USER_ONLY, we cannot rely on TLB_INVALID_MASK or haddr==NULL
      * to detect if there was an exception during tlb_fill().
@@ -174,8 +166,8 @@ static int s390_probe_access(CPUArchState *env, target_ulong addr, int size,
                              (access_type == MMU_DATA_STORE
                               ? BP_MEM_WRITE : BP_MEM_READ), ra);
     }
-#endif
     return 0;
+#endif
 }
 
 static int access_prepare_nf(S390Access *access, CPUS390XState *env,
-- 
2.25.1



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

* [PATCH v2 37/41] target/s390x: Implement s390_cpu_record_sigsegv
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (35 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 36/41] target/s390x: Use probe_access_flags in s390_probe_access Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:39   ` Philippe Mathieu-Daudé
  2021-09-18 18:45 ` [PATCH v2 38/41] target/sh4: Make sh4_cpu_tlb_fill sysemu only Richard Henderson
                   ` (4 subsequent siblings)
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Move the masking of the address from cpu_loop into
s390_cpu_record_sigsegv -- this is governed by hw, not linux.
This does mean we have to raise our own exception, rather
than return to the fallback.

Use maperr to choose between PGM_PROTECTION and PGM_ADDRESSING.
Use the appropriate si_code for each in cpu_loop.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/s390x-internal.h  | 13 ++++++++++---
 linux-user/s390x/cpu_loop.c    | 14 +++++++-------
 target/s390x/cpu.c             |  6 ++++--
 target/s390x/tcg/excp_helper.c | 18 +++++++++++-------
 4 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h
index 7a6aa4dacc..2b6791a3a2 100644
--- a/target/s390x/s390x-internal.h
+++ b/target/s390x/s390x-internal.h
@@ -270,13 +270,20 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
-bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr);
 void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                                    MMUAccessType access_type,
                                    int mmu_idx, uintptr_t retaddr);
 
+#ifdef CONFIG_USER_ONLY
+void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
+                             MMUAccessType access_type,
+                             bool maperr, uintptr_t retaddr);
+#else
+bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                       MMUAccessType access_type, int mmu_idx,
+                       bool probe, uintptr_t retaddr);
+#endif
+
 
 /* fpu_helper.c */
 uint32_t set_cc_nz_f32(float32 v);
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index 6a69a6dd26..7a1d032227 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -21,9 +21,8 @@
 #include "qemu-common.h"
 #include "qemu.h"
 #include "cpu_loop-common.h"
+#include "signal-common.h"
 
-/* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS */
-#define S390X_FAIL_ADDR_MASK -4096LL
 
 static int get_pgm_data_si_code(int dxc_code)
 {
@@ -109,12 +108,13 @@ void cpu_loop(CPUS390XState *env)
                 n = TARGET_ILL_ILLOPC;
                 goto do_signal_pc;
             case PGM_PROTECTION:
+                force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_ACCERR,
+                                env->__excp_addr);
+                break;
             case PGM_ADDRESSING:
-                sig = TARGET_SIGSEGV;
-                /* XXX: check env->error_code */
-                n = TARGET_SEGV_MAPERR;
-                addr = env->__excp_addr & S390X_FAIL_ADDR_MASK;
-                goto do_signal;
+                force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+                                env->__excp_addr);
+                break;
             case PGM_EXECUTE:
             case PGM_SPECIFICATION:
             case PGM_SPECIAL_OP:
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index df8ade9021..fa999d586d 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -268,10 +268,12 @@ static void s390_cpu_reset_full(DeviceState *dev)
 
 static const struct TCGCPUOps s390_tcg_ops = {
     .initialize = s390x_translate_init,
-    .tlb_fill = s390_cpu_tlb_fill,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+    .record_sigsegv = s390_cpu_record_sigsegv,
+#else
     .has_work = s390_cpu_has_work,
+    .tlb_fill = s390_cpu_tlb_fill,
     .cpu_exec_interrupt = s390_cpu_exec_interrupt,
     .do_interrupt = s390_cpu_do_interrupt,
     .debug_excp_handler = s390x_cpu_debug_excp_handler,
diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
index 3d6662a53c..b923d080fc 100644
--- a/target/s390x/tcg/excp_helper.c
+++ b/target/s390x/tcg/excp_helper.c
@@ -89,16 +89,20 @@ void s390_cpu_do_interrupt(CPUState *cs)
     cs->exception_index = -1;
 }
 
-bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                       MMUAccessType access_type, int mmu_idx,
-                       bool probe, uintptr_t retaddr)
+void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
+                             MMUAccessType access_type,
+                             bool maperr, uintptr_t retaddr)
 {
     S390CPU *cpu = S390_CPU(cs);
 
-    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING);
-    /* On real machines this value is dropped into LowMem.  Since this
-       is userland, simply put this someplace that cpu_loop can find it.  */
-    cpu->env.__excp_addr = address;
+    trigger_pgm_exception(&cpu->env, maperr ? PGM_ADDRESSING : PGM_PROTECTION);
+    /*
+     * On real machines this value is dropped into LowMem. Since this
+     * is userland, simply put this someplace that cpu_loop can find it.
+     * S390 only gives the page of the fault, not the exact address.
+     * C.f. the construction of TEC in mmu_translate().
+     */
+    cpu->env.__excp_addr = address & TARGET_PAGE_MASK;
     cpu_loop_exit_restore(cs, retaddr);
 }
 
-- 
2.25.1



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

* [PATCH v2 38/41] target/sh4: Make sh4_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (36 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 37/41] target/s390x: Implement s390_cpu_record_sigsegv Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 39/41] target/sparc: Make sparc_cpu_tlb_fill " Richard Henderson
                   ` (3 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for sh4.
Remove the code from cpu_loop that raised SIGSEGV.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/sh4/cpu.h          | 6 +++---
 linux-user/sh4/cpu_loop.c | 8 --------
 target/sh4/cpu.c          | 2 +-
 target/sh4/helper.c       | 9 +--------
 4 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 56f7c32df9..17458587a5 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -213,12 +213,12 @@ void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
                                     int mmu_idx, uintptr_t retaddr);
 
 void sh4_translate_init(void);
+void sh4_cpu_list(void);
+
+#if !defined(CONFIG_USER_ONLY)
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
-
-void sh4_cpu_list(void);
-#if !defined(CONFIG_USER_ONLY)
 void superh_cpu_do_interrupt(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void cpu_sh4_invalidate_tlb(CPUSH4State *s);
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index 222ed1c670..8408d0c42d 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -63,14 +63,6 @@ void cpu_loop(CPUSH4State *env)
             info.si_code = TARGET_TRAP_BRKPT;
             queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
-        case 0xa0:
-        case 0xc0:
-            info.si_signo = TARGET_SIGSEGV;
-            info.si_errno = 0;
-            info.si_code = TARGET_SEGV_MAPERR;
-            info._sifields._sigfault._addr = env->tea;
-            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            break;
         case EXCP_ATOMIC:
             cpu_exec_step_atomic(cs);
             arch_interrupt = false;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index fb2116dc52..0cc1542681 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -237,10 +237,10 @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
 static const struct TCGCPUOps superh_tcg_ops = {
     .initialize = sh4_translate_init,
     .synchronize_from_tb = superh_cpu_synchronize_from_tb,
-    .tlb_fill = superh_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = superh_cpu_has_work,
+    .tlb_fill = superh_cpu_tlb_fill,
     .cpu_exec_interrupt = superh_cpu_exec_interrupt,
     .do_interrupt = superh_cpu_do_interrupt,
     .do_unaligned_access = superh_cpu_do_unaligned_access,
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 53cb9c3b63..6a620e36fc 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -796,8 +796,6 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     return false;
 }
 
-#endif /* !CONFIG_USER_ONLY */
-
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr)
@@ -806,11 +804,6 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     CPUSH4State *env = &cpu->env;
     int ret;
 
-#ifdef CONFIG_USER_ONLY
-    ret = (access_type == MMU_DATA_STORE ? MMU_DTLB_VIOLATION_WRITE :
-           access_type == MMU_INST_FETCH ? MMU_ITLB_VIOLATION :
-           MMU_DTLB_VIOLATION_READ);
-#else
     target_ulong physical;
     int prot;
 
@@ -829,7 +822,6 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     if (ret != MMU_DTLB_MULTIPLE && ret != MMU_ITLB_MULTIPLE) {
         env->pteh = (env->pteh & PTEH_ASID_MASK) | (address & PTEH_VPN_MASK);
     }
-#endif
 
     env->tea = address;
     switch (ret) {
@@ -868,3 +860,4 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     }
     cpu_loop_exit_restore(cs, retaddr);
 }
+#endif /* !CONFIG_USER_ONLY */
-- 
2.25.1



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

* [PATCH v2 39/41] target/sparc: Make sparc_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (37 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 38/41] target/sh4: Make sh4_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 40/41] target/xtensa: Make xtensa_cpu_tlb_fill " Richard Henderson
                   ` (2 subsequent siblings)
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for sparc.

This makes all of the code in mmu_helper.c sysemu only, so remove
the ifdefs and move the file to sparc_softmmu_ss.  Remove the code
from cpu_loop that handled TT_DFAULT and TT_TFAULT.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc/cpu_loop.c | 25 -------------------------
 target/sparc/cpu.c          |  2 +-
 target/sparc/mmu_helper.c   | 25 -------------------------
 target/sparc/meson.build    |  2 +-
 4 files changed, 2 insertions(+), 52 deletions(-)

diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 02532f198d..f5e0de7eaf 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -217,17 +217,6 @@ void cpu_loop (CPUSPARCState *env)
         case TT_WIN_UNF: /* window underflow */
             restore_window(env);
             break;
-        case TT_TFAULT:
-        case TT_DFAULT:
-            {
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = env->mmuregs[4];
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            }
-            break;
 #else
         case TT_SPILL: /* window overflow */
             save_window(env);
@@ -235,20 +224,6 @@ void cpu_loop (CPUSPARCState *env)
         case TT_FILL: /* window underflow */
             restore_window(env);
             break;
-        case TT_TFAULT:
-        case TT_DFAULT:
-            {
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                if (trapnr == TT_DFAULT)
-                    info._sifields._sigfault._addr = env->dmmu.mmuregs[4];
-                else
-                    info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-            }
-            break;
 #ifndef TARGET_ABI32
         case 0x16e:
             flush_windows(env);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 4a63ed1264..c068ef98e3 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -866,10 +866,10 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
 static const struct TCGCPUOps sparc_tcg_ops = {
     .initialize = sparc_tcg_init,
     .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
-    .tlb_fill = sparc_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = sparc_cpu_has_work,
+    .tlb_fill = sparc_cpu_tlb_fill,
     .cpu_exec_interrupt = sparc_cpu_exec_interrupt,
     .do_interrupt = sparc_cpu_do_interrupt,
     .do_transaction_failed = sparc_cpu_do_transaction_failed,
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index a44473a1c7..2ad47391d0 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -25,30 +25,6 @@
 
 /* Sparc MMU emulation */
 
-#if defined(CONFIG_USER_ONLY)
-
-bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                        MMUAccessType access_type, int mmu_idx,
-                        bool probe, uintptr_t retaddr)
-{
-    SPARCCPU *cpu = SPARC_CPU(cs);
-    CPUSPARCState *env = &cpu->env;
-
-    if (access_type == MMU_INST_FETCH) {
-        cs->exception_index = TT_TFAULT;
-    } else {
-        cs->exception_index = TT_DFAULT;
-#ifdef TARGET_SPARC64
-        env->dmmu.mmuregs[4] = address;
-#else
-        env->mmuregs[4] = address;
-#endif
-    }
-    cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else
-
 #ifndef TARGET_SPARC64
 /*
  * Sparc V8 Reference MMU (SRMMU)
@@ -926,4 +902,3 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     }
     return phys_addr;
 }
-#endif
diff --git a/target/sparc/meson.build b/target/sparc/meson.build
index a3638b9503..a801802ee2 100644
--- a/target/sparc/meson.build
+++ b/target/sparc/meson.build
@@ -6,7 +6,6 @@ sparc_ss.add(files(
   'gdbstub.c',
   'helper.c',
   'ldst_helper.c',
-  'mmu_helper.c',
   'translate.c',
   'win_helper.c',
 ))
@@ -16,6 +15,7 @@ sparc_ss.add(when: 'TARGET_SPARC64', if_true: files('int64_helper.c', 'vis_helpe
 sparc_softmmu_ss = ss.source_set()
 sparc_softmmu_ss.add(files(
   'machine.c',
+  'mmu_helper.c',
   'monitor.c',
 ))
 
-- 
2.25.1



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

* [PATCH v2 40/41] target/xtensa: Make xtensa_cpu_tlb_fill sysemu only
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (38 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 39/41] target/sparc: Make sparc_cpu_tlb_fill " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-18 18:45 ` [PATCH v2 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu Richard Henderson
  2021-09-19 10:38 ` [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Philippe Mathieu-Daudé
  41 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The fallback code in raise_sigsegv is sufficient for xtensa.
Remove the code from cpu_loop that raised SIGSEGV.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/xtensa/cpu.h          |  2 +-
 linux-user/xtensa/cpu_loop.c |  9 ---------
 target/xtensa/cpu.c          |  2 +-
 target/xtensa/helper.c       | 22 +---------------------
 4 files changed, 3 insertions(+), 32 deletions(-)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 646965f379..cf0fffbd26 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,10 +563,10 @@ struct XtensaCPU {
 };
 
 
+#ifndef CONFIG_USER_ONLY
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                          MMUAccessType access_type, int mmu_idx,
                          bool probe, uintptr_t retaddr);
-#ifndef CONFIG_USER_ONLY
 void xtensa_cpu_do_interrupt(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index 64831c9199..b48781c6e8 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -224,15 +224,6 @@ void cpu_loop(CPUXtensaState *env)
                 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                 break;
 
-            case LOAD_PROHIBITED_CAUSE:
-            case STORE_PROHIBITED_CAUSE:
-                info.si_signo = TARGET_SIGSEGV;
-                info.si_errno = 0;
-                info.si_code = TARGET_SEGV_ACCERR;
-                info._sifields._sigfault._addr = env->sregs[EXCVADDR];
-                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-                break;
-
             default:
                 fprintf(stderr, "exccause = %d\n", env->sregs[EXCCAUSE]);
                 g_assert_not_reached();
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 5cb19a8881..c289c4e679 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -192,11 +192,11 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
 
 static const struct TCGCPUOps xtensa_tcg_ops = {
     .initialize = xtensa_translate_init,
-    .tlb_fill = xtensa_cpu_tlb_fill,
     .debug_excp_handler = xtensa_breakpoint_handler,
 
 #ifndef CONFIG_USER_ONLY
     .has_work = xtensa_cpu_has_work,
+    .tlb_fill = xtensa_cpu_tlb_fill,
     .cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
     .do_interrupt = xtensa_cpu_do_interrupt,
     .do_transaction_failed = xtensa_cpu_do_transaction_failed,
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index f18ab383fd..29d216ec1b 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -242,27 +242,7 @@ void xtensa_cpu_list(void)
     }
 }
 
-#ifdef CONFIG_USER_ONLY
-
-bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-                         MMUAccessType access_type, int mmu_idx,
-                         bool probe, uintptr_t retaddr)
-{
-    XtensaCPU *cpu = XTENSA_CPU(cs);
-    CPUXtensaState *env = &cpu->env;
-
-    qemu_log_mask(CPU_LOG_INT,
-                  "%s: rw = %d, address = 0x%08" VADDR_PRIx ", size = %d\n",
-                  __func__, access_type, address, size);
-    env->sregs[EXCVADDR] = address;
-    env->sregs[EXCCAUSE] = (access_type == MMU_DATA_STORE ?
-                            STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE);
-    cs->exception_index = EXC_USER;
-    cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
 void xtensa_cpu_do_unaligned_access(CPUState *cs,
                                     vaddr addr, MMUAccessType access_type,
                                     int mmu_idx, uintptr_t retaddr)
-- 
2.25.1



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

* [PATCH v2 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (39 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 40/41] target/xtensa: Make xtensa_cpu_tlb_fill " Richard Henderson
@ 2021-09-18 18:45 ` Richard Henderson
  2021-09-19 18:40   ` Philippe Mathieu-Daudé
  2021-09-19 10:38 ` [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Philippe Mathieu-Daudé
  41 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-18 18:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

We have replaced tlb_fill with record_sigsegv for user mod.
Move the declaration to restrict it to system emulation.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/core/tcg-cpu-ops.h | 22 ++++++++++------------
 linux-user/signal.c           |  3 ---
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index e229a40772..988561e8d4 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -35,18 +35,6 @@ struct TCGCPUOps {
     void (*cpu_exec_enter)(CPUState *cpu);
     /** @cpu_exec_exit: Callback for cpu_exec cleanup */
     void (*cpu_exec_exit)(CPUState *cpu);
-    /**
-     * @tlb_fill: Handle a softmmu tlb miss or user-only address fault
-     *
-     * For system mode, if the access is valid, call tlb_set_page
-     * and return true; if the access is invalid, and probe is
-     * true, return false; otherwise raise an exception and do
-     * not return.  For user-only mode, always raise an exception
-     * and do not return.
-     */
-    bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
-                     MMUAccessType access_type, int mmu_idx,
-                     bool probe, uintptr_t retaddr);
     /** @debug_excp_handler: Callback for handling debug exceptions */
     void (*debug_excp_handler)(CPUState *cpu);
 
@@ -72,6 +60,16 @@ struct TCGCPUOps {
     bool (*has_work)(CPUState *cpu);
     /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
     bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
+    /**
+     * @tlb_fill: Handle a softmmu tlb miss
+     *
+     * If the access is valid, call tlb_set_page and return true;
+     * if the access is invalid and probe is true, return false;
+     * otherwise raise an exception and do not return.
+     */
+    bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
+                     MMUAccessType access_type, int mmu_idx,
+                     bool probe, uintptr_t retaddr);
     /**
      * @do_transaction_failed: Callback for handling failed memory transactions
      * (ie bus faults or external aborts; not MMU faults)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index ae31b46be0..4f4c919b23 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -690,9 +690,6 @@ void raise_sigsegv(CPUState *cpu, target_ulong addr,
 
     if (tcg_ops->record_sigsegv) {
         tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
-    } else if (tcg_ops->tlb_fill) {
-        tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
-        g_assert_not_reached();
     }
 
     force_sig_fault(TARGET_SIGSEGV,
-- 
2.25.1



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

* Re: [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV
  2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
                   ` (40 preceding siblings ...)
  2021-09-18 18:45 ` [PATCH v2 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu Richard Henderson
@ 2021-09-19 10:38 ` Philippe Mathieu-Daudé
  41 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 10:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:44, Richard Henderson wrote:

>   linux-user: Reorg handling for SIGSEGV
>   linux-user/host/x86: Populate host_signal.h
>   linux-user/host/ppc: Populate host_signal.h
>   linux-user/host/alpha: Populate host_signal.h
>   linux-user/host/sparc: Populate host_signal.h
>   linux-user/host/arm: Populate host_signal.h
>   linux-user/host/aarch64: Populate host_signal.h
>   linux-user/host/s390: Populate host_signal.h
>   linux-user/host/mips: Populate host_signal.h
>   linux-user/host/riscv: Populate host_signal.h
>   target/arm: Fixup comment re handle_cpu_signal
>   linux-user/host/riscv: Improve host_signal_write
>   linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER

Thanks for caring and splitting v1 patch :)


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

* Re: [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures
  2021-09-18 18:44 ` [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures Richard Henderson
@ 2021-09-19 17:56   ` Philippe Mathieu-Daudé
  2021-09-19 22:57   ` Alistair Francis
  1 sibling, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 17:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:44, Richard Henderson wrote:
> The existing code for safe-syscall.inc.S will compile
> without change for riscv32 and riscv64.  We may also
> drop the meson.build stanza that merges them for tcg/.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  configure                                             |  8 ++------
>  meson.build                                           |  4 +---
>  linux-user/host/{riscv64 => riscv}/hostdep.h          |  4 ++--
>  linux-user/host/riscv32/hostdep.h                     | 11 -----------
>  linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S |  0
>  5 files changed, 5 insertions(+), 22 deletions(-)
>  rename linux-user/host/{riscv64 => riscv}/hostdep.h (94%)
>  delete mode 100644 linux-user/host/riscv32/hostdep.h
>  rename linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S (100%)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV
  2021-09-18 18:44 ` [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV Richard Henderson
@ 2021-09-19 18:02   ` Philippe Mathieu-Daudé
  2021-09-19 19:01   ` Warner Losh
  2021-09-19 23:01   ` Alistair Francis
  2 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:44, Richard Henderson wrote:
> Add stub host-signal.h for all linux-user hosts.
> Add new code replacing cpu_signal_handler.
> Full migration will happen one host at a time.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 5ea8e4584a..6f953f10d4 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -18,12 +18,15 @@
>   */
>  #include "qemu/osdep.h"
>  #include "qemu/bitops.h"
> +#include "hw/core/tcg-cpu-ops.h"
> +
>  #include <sys/ucontext.h>
>  #include <sys/resource.h>
>  
>  #include "qemu.h"
>  #include "trace.h"
>  #include "signal-common.h"
> +#include "host-signal.h"
>  
>  static struct target_sigaction sigact_table[TARGET_NSIG];
>  
> @@ -761,41 +764,115 @@ static inline void rewind_if_in_safe_syscall(void *puc)
>  }
>  #endif
>  
> -static void host_signal_handler(int host_signum, siginfo_t *info,
> -                                void *puc)
> +static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
>  {
>      CPUArchState *env = thread_cpu->env_ptr;
>      CPUState *cpu = env_cpu(env);
>      TaskState *ts = cpu->opaque;
> -
> -    int sig;
>      target_siginfo_t tinfo;
>      ucontext_t *uc = puc;
>      struct emulated_sigtable *k;
> +    int guest_sig;
>  
> +#ifdef HOST_SIGNAL_PLACEHOLDER
>      /* the CPU emulator uses some host signals to detect exceptions,
>         we forward to it some signals */
> -    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
> +    if ((host_sig == SIGSEGV || host_sig == SIGBUS)
>          && info->si_code > 0) {
> -        if (cpu_signal_handler(host_signum, info, puc))
> +        if (cpu_signal_handler(host_sig, info, puc))
>              return;
>      }
> +#else
> +    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) {
> +            const struct TCGCPUOps *tcg_ops;
> +
> +            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);
> +
> +            tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
> +            tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
> +                              MMU_USER_IDX, false, pc);
> +            g_assert_not_reached();
> +        } else {
> +            sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
> +        }
> +
> +        sync_sig = true;
> +    }
> +#endif
>  
>      /* get target signal number */
> -    sig = host_to_target_signal(host_signum);
> -    if (sig < 1 || sig > TARGET_NSIG)
> +    guest_sig = host_to_target_signal(host_sig);
> +    if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
>          return;
> -    trace_user_host_signal(env, host_signum, sig);
> +    }
> +    trace_user_host_signal(env, host_sig, guest_sig);
> +
> +    host_to_target_siginfo_noswap(&tinfo, info);
> +    k = &ts->sigtab[guest_sig - 1];
> +    k->info = tinfo;
> +    k->pending = guest_sig;
> +    ts->signal_pending = 1;
> +
> +#ifndef HOST_SIGNAL_PLACEHOLDER
> +    /*
> +     * For synchronous signals, unwind the cpu state to the faulting
> +     * insn and then exit back to the main loop so that the signal
> +     * is delivered immediately.
> +     */
> +    if (sync_sig) {
> +        cpu->exception_index = EXCP_INTERRUPT;
> +        cpu_loop_exit_restore(cpu, pc);
> +    }
> +#endif
>  
>      rewind_if_in_safe_syscall(puc);
>  
> -    host_to_target_siginfo_noswap(&tinfo, info);
> -    k = &ts->sigtab[sig - 1];
> -    k->info = tinfo;
> -    k->pending = sig;
> -    ts->signal_pending = 1;
> -
> -    /* Block host signals until target signal handler entered. We
> +    /*
> +     * 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
> 

So this is outside of my comfort zone; however after reviewing and
to the best of my knowledge it looks OK, so:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

And I'll review the next patches assuming this one is OK.


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

* Re: [PATCH v2 09/41] linux-user/host/alpha: Populate host_signal.h
  2021-09-18 18:44 ` [PATCH v2 09/41] linux-user/host/alpha: " Richard Henderson
@ 2021-09-19 18:03   ` Philippe Mathieu-Daudé
  2021-09-19 18:07     ` Richard Henderson
  2021-09-19 18:13   ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:03 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:44, Richard Henderson wrote:
> Split host_signal_pc and host_signal_write out of user-exec.c.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/host/alpha/host-signal.h | 41 +++++++++++++++++++++++++++++
>  accel/tcg/user-exec.c               | 31 +---------------------
>  2 files changed, 42 insertions(+), 30 deletions(-)
>  create mode 100644 linux-user/host/alpha/host-signal.h

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 13/41] linux-user/host/s390: Populate host_signal.h
  2021-09-18 18:44 ` [PATCH v2 13/41] linux-user/host/s390: " Richard Henderson
@ 2021-09-19 18:07   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:07 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:44, Richard Henderson wrote:
> Split host_signal_pc and host_signal_write out of user-exec.c.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/host/s390/host-signal.h  | 93 ++++++++++++++++++++++++++++-
>  linux-user/host/s390x/host-signal.h |  2 +-
>  accel/tcg/user-exec.c               | 88 +--------------------------
>  3 files changed, 94 insertions(+), 89 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 09/41] linux-user/host/alpha: Populate host_signal.h
  2021-09-19 18:03   ` Philippe Mathieu-Daudé
@ 2021-09-19 18:07     ` Richard Henderson
  2021-09-19 18:11       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-19 18:07 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: laurent

On 9/19/21 11:03 AM, Philippe Mathieu-Daudé wrote:
> On 9/18/21 20:44, Richard Henderson wrote:
>> Split host_signal_pc and host_signal_write out of user-exec.c.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   linux-user/host/alpha/host-signal.h | 41 +++++++++++++++++++++++++++++
>>   accel/tcg/user-exec.c               | 31 +---------------------
>>   2 files changed, 42 insertions(+), 30 deletions(-)
>>   create mode 100644 linux-user/host/alpha/host-signal.h
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> 

Amusingly, this is one bit that we might want to simply drop.  The remaining required 
entries in linux-user/host/arch/ are missing, so one can't actually build with alpha host 
at the moment.

Similarly, linux-user/host/ia64/ is also unusable, because we would have hit the #error in 
accel/tcg/user-exec.c, missing the host signal handling.


r~


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

* Re: [PATCH v2 14/41] linux-user/host/mips: Populate host_signal.h
  2021-09-18 18:45 ` [PATCH v2 14/41] linux-user/host/mips: " Richard Henderson
@ 2021-09-19 18:08   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:08 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> Split host_signal_pc and host_signal_write out of user-exec.c.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/host/mips/host-signal.h | 62 +++++++++++++++++++++++++++++-
>  accel/tcg/user-exec.c              | 52 +------------------------
>  2 files changed, 62 insertions(+), 52 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 09/41] linux-user/host/alpha: Populate host_signal.h
  2021-09-19 18:07     ` Richard Henderson
@ 2021-09-19 18:11       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:11 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/19/21 20:07, Richard Henderson wrote:
> On 9/19/21 11:03 AM, Philippe Mathieu-Daudé wrote:
>> On 9/18/21 20:44, Richard Henderson wrote:
>>> Split host_signal_pc and host_signal_write out of user-exec.c.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>   linux-user/host/alpha/host-signal.h | 41 +++++++++++++++++++++++++++++
>>>   accel/tcg/user-exec.c               | 31 +---------------------
>>>   2 files changed, 42 insertions(+), 30 deletions(-)
>>>   create mode 100644 linux-user/host/alpha/host-signal.h
>>
>> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>>
> 
> Amusingly, this is one bit that we might want to simply drop.  The
> remaining required entries in linux-user/host/arch/ are missing, so one
> can't actually build with alpha host at the moment.
> 
> Similarly, linux-user/host/ia64/ is also unusable, because we would have
> hit the #error in accel/tcg/user-exec.c, missing the host signal handling.

Understandable. Since part of the work is done, I'd rather keep the
patches in this series and drop them after in another series (easier
to revert for someone interested in fixing these targets).


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

* Re: [PATCH v2 09/41] linux-user/host/alpha: Populate host_signal.h
  2021-09-18 18:44 ` [PATCH v2 09/41] linux-user/host/alpha: " Richard Henderson
  2021-09-19 18:03   ` Philippe Mathieu-Daudé
@ 2021-09-19 18:13   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:13 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:44, Richard Henderson wrote:
> Split host_signal_pc and host_signal_write out of user-exec.c.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/host/alpha/host-signal.h | 41 +++++++++++++++++++++++++++++
>  accel/tcg/user-exec.c               | 31 +---------------------
>  2 files changed, 42 insertions(+), 30 deletions(-)
>  create mode 100644 linux-user/host/alpha/host-signal.h

> +#ifndef ALPHA_HOST_SIGNAL_H
> +#define ALPHA_HOST_SIGNAL_H
> +
> +static inline uintptr_t host_signal_pc(ucontext_t *uc)
> +{
> +    return uc->uc_mcontext.sc_pc;
> +}
> +
> +static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
> +{
> +    uint32_t *pc = uc->uc_mcontext.sc_pc;

BTW I'd use host_signal_pc() here for consistency with other targets.

> +    uint32_t insn = *pc;
> +
> +    /* XXX: need kernel patch to get write flag faster */
> +    switch (insn >> 26) {
> +    case 0x0d: /* stw */
> +    case 0x0e: /* stb */
> +    case 0x0f: /* stq_u */
> +    case 0x24: /* stf */
> +    case 0x25: /* stg */
[...]


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

* Re: [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER
  2021-09-18 18:45 ` [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER Richard Henderson
@ 2021-09-19 18:18   ` Philippe Mathieu-Daudé
  2021-09-19 18:59   ` Warner Losh
  1 sibling, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:18 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> Now that all of the linux-user hosts have been converted
> to host-signal.h, drop the compatibility code.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/exec/exec-all.h | 12 ------------
>  linux-user/signal.c     | 13 -------------
>  2 files changed, 25 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv
  2021-09-18 18:45 ` [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv Richard Henderson
@ 2021-09-19 18:22   ` Philippe Mathieu-Daudé
  2021-09-19 18:24     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:22 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> Add a new user-only interface for updating cpu state before
> raising a signal.  This will replace tlb_fill for user-only
> and should result in less boilerplate for each guest.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
> index 4a4c4053e3..e229a40772 100644
> --- a/include/hw/core/tcg-cpu-ops.h
> +++ b/include/hw/core/tcg-cpu-ops.h
> @@ -114,6 +114,32 @@ struct TCGCPUOps {
>       */
>      bool (*io_recompile_replay_branch)(CPUState *cpu,
>                                         const TranslationBlock *tb);
> +#else
> +    /**
> +     * record_sigsegv:
> +     * @cpu: cpu context
> +     * @addr: faulting guest address
> +     * @access_type: access was read/write/execute
> +     * @maperr: true for invalid page, false for permission fault
> +     * @ra: host pc for unwinding
> +     *
> +     * We are about to raise SIGSEGV with si_code set for @maperr,
> +     * and si_addr set for @addr.  Record anything further needed
> +     * for the signal ucontext_t.
> +     *
> +     * If the emulated kernel does not provide anything to the signal
> +     * handler with anything besides the user context registers, and
> +     * the siginfo_t, then this hook need do nothing and may be omitted.
> +     * Otherwise, record the data and return; the caller will raise
> +     * the signal, unwind the cpu state, and return to the main loop.
> +     *
> +     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
> +     * so that a "normal" cpu exception can be raised.  In this case,
> +     * the signal must be raised by the architecture cpu_loop.
> +     */

Shouldn't it have the QEMU_NORETURN attribute?

> +    void (*record_sigsegv)(CPUState *cpu, vaddr addr,
> +                           MMUAccessType access_type,
> +                           bool maperr, uintptr_t ra);
>  #endif /* CONFIG_SOFTMMU */
>  #endif /* NEED_CPU_H */
>  
> 



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

* Re: [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv
  2021-09-19 18:22   ` Philippe Mathieu-Daudé
@ 2021-09-19 18:24     ` Philippe Mathieu-Daudé
  2021-09-19 18:32       ` Richard Henderson
  0 siblings, 1 reply; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:24 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/19/21 20:22, Philippe Mathieu-Daudé wrote:
> On 9/18/21 20:45, Richard Henderson wrote:
>> Add a new user-only interface for updating cpu state before
>> raising a signal.  This will replace tlb_fill for user-only
>> and should result in less boilerplate for each guest.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>  include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++
>>  1 file changed, 26 insertions(+)
>>
>> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
>> index 4a4c4053e3..e229a40772 100644
>> --- a/include/hw/core/tcg-cpu-ops.h
>> +++ b/include/hw/core/tcg-cpu-ops.h
>> @@ -114,6 +114,32 @@ struct TCGCPUOps {
>>       */
>>      bool (*io_recompile_replay_branch)(CPUState *cpu,
>>                                         const TranslationBlock *tb);
>> +#else
>> +    /**
>> +     * record_sigsegv:
>> +     * @cpu: cpu context
>> +     * @addr: faulting guest address
>> +     * @access_type: access was read/write/execute
>> +     * @maperr: true for invalid page, false for permission fault
>> +     * @ra: host pc for unwinding
>> +     *
>> +     * We are about to raise SIGSEGV with si_code set for @maperr,
>> +     * and si_addr set for @addr.  Record anything further needed
>> +     * for the signal ucontext_t.
>> +     *
>> +     * If the emulated kernel does not provide anything to the signal
>> +     * handler with anything besides the user context registers, and
>> +     * the siginfo_t, then this hook need do nothing and may be omitted.
>> +     * Otherwise, record the data and return; the caller will raise
>> +     * the signal, unwind the cpu state, and return to the main loop.
>> +     *
>> +     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
>> +     * so that a "normal" cpu exception can be raised.  In this case,
>> +     * the signal must be raised by the architecture cpu_loop.
>> +     */
> 
> Shouldn't it have the QEMU_NORETURN attribute?

Eh now I saw the next patch and understood raise_sigsegv() is
where QEMU_NORETURN belong :)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> 
>> +    void (*record_sigsegv)(CPUState *cpu, vaddr addr,
>> +                           MMUAccessType access_type,
>> +                           bool maperr, uintptr_t ra);
>>  #endif /* CONFIG_SOFTMMU */
>>  #endif /* NEED_CPU_H */
>>  
>>
> 
> 


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

* Re: [PATCH v2 20/41] linux-user: Add raise_sigsegv
  2021-09-18 18:45 ` [PATCH v2 20/41] linux-user: Add raise_sigsegv Richard Henderson
@ 2021-09-19 18:26   ` Philippe Mathieu-Daudé
  2021-09-19 18:35   ` Richard Henderson
  1 sibling, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:26 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> This is a new interface to be provided by the os emulator
> for raising SIGSEGV on fault.  Use the new record_sigsegv
> target hook.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/exec/exec-all.h | 15 +++++++++++++++
>  accel/tcg/user-exec.c   | 33 ++++++++++++++++++---------------
>  linux-user/signal.c     | 30 ++++++++++++++++++++++--------
>  3 files changed, 55 insertions(+), 23 deletions(-)

To the best of my knowledge:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only
  2021-09-18 18:45 ` [PATCH v2 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only Richard Henderson
@ 2021-09-19 18:28   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> The fallback code in raise_sigsegv is sufficient for cris-linux-user.
> Remove the code from cpu_loop that handled the unnamed 0xaa exception.
> 
> This makes all of the code in helper.c sysemu only, so remove the
> ifdefs and move the file to cris_softmmu_ss.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/cris/cpu.h          |  8 ++++----
>  linux-user/cris/cpu_loop.c | 10 ----------
>  target/cris/cpu.c          |  4 ++--
>  target/cris/helper.c       | 18 ------------------
>  target/cris/meson.build    |  7 +++++--
>  5 files changed, 11 insertions(+), 36 deletions(-)

Nice!

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv
  2021-09-18 18:45 ` [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv Richard Henderson
@ 2021-09-19 18:32   ` Philippe Mathieu-Daudé
  2021-09-19 18:59   ` Warner Losh
  1 sibling, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:32 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> Record cr2, error_code, and exception_index.  That last means
> that we must exit to cpu_loop ourselves, instead of letting
> exception_index being overwritten.
> 
> Use the maperr parameter to properly set PG_ERROR_P_MASK.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/i386/tcg/helper-tcg.h       |  6 ++++++
>  target/i386/tcg/tcg-cpu.c          |  3 ++-
>  target/i386/tcg/user/excp_helper.c | 23 +++++++++++++++++------
>  3 files changed, 25 insertions(+), 7 deletions(-)

> diff --git a/target/i386/tcg/user/excp_helper.c b/target/i386/tcg/user/excp_helper.c
> index a89b5228fd..cd507e2a1b 100644
> --- a/target/i386/tcg/user/excp_helper.c
> +++ b/target/i386/tcg/user/excp_helper.c
> @@ -22,18 +22,29 @@
>  #include "exec/exec-all.h"
>  #include "tcg/helper-tcg.h"
>  
> -bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
> -                      MMUAccessType access_type, int mmu_idx,
> -                      bool probe, uintptr_t retaddr)
> +void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
> +                            MMUAccessType access_type,
> +                            bool maperr, uintptr_t ra)
>  {
>      X86CPU *cpu = X86_CPU(cs);
>      CPUX86State *env = &cpu->env;
>  
> +    /*
> +     * The error_code that hw reports as part of the exception frame
> +     * is copied to linux sigcontext.err.  The exception_index is
> +     * copied to linux sigcontext.trapno.  Short of inventing a new
> +     * place to store the trapno, we cannot let our caller raise the
> +     * signal and set exception_index to EXCP_INTERRUPT.
> +     */
>      env->cr[2] = addr;
> -    env->error_code = (access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT;
> -    env->error_code |= PG_ERROR_U_MASK;
> +    env->error_code = ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
> +                    | (maperr ? 0 : PG_ERROR_P_MASK)
> +                    | PG_ERROR_U_MASK;
>      cs->exception_index = EXCP0E_PAGE;
> +
> +    /* Disable do_interrupt_user. */
>      env->exception_is_int = 0;
>      env->exception_next_eip = -1;
> -    cpu_loop_exit_restore(cs, retaddr);
> +
> +    cpu_loop_exit_restore(cs, ra);
>  }
> 

Better have an x86 expert also review this, but to the best
of my knowledge:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

And YAY! btw, thanks :>


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

* Re: [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv
  2021-09-19 18:24     ` Philippe Mathieu-Daudé
@ 2021-09-19 18:32       ` Richard Henderson
  0 siblings, 0 replies; 71+ messages in thread
From: Richard Henderson @ 2021-09-19 18:32 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: laurent

On 9/19/21 11:24 AM, Philippe Mathieu-Daudé wrote:
> On 9/19/21 20:22, Philippe Mathieu-Daudé wrote:
>> On 9/18/21 20:45, Richard Henderson wrote:
>>> Add a new user-only interface for updating cpu state before
>>> raising a signal.  This will replace tlb_fill for user-only
>>> and should result in less boilerplate for each guest.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>   include/hw/core/tcg-cpu-ops.h | 26 ++++++++++++++++++++++++++
>>>   1 file changed, 26 insertions(+)
>>>
>>> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
>>> index 4a4c4053e3..e229a40772 100644
>>> --- a/include/hw/core/tcg-cpu-ops.h
>>> +++ b/include/hw/core/tcg-cpu-ops.h
>>> @@ -114,6 +114,32 @@ struct TCGCPUOps {
>>>        */
>>>       bool (*io_recompile_replay_branch)(CPUState *cpu,
>>>                                          const TranslationBlock *tb);
>>> +#else
>>> +    /**
>>> +     * record_sigsegv:
>>> +     * @cpu: cpu context
>>> +     * @addr: faulting guest address
>>> +     * @access_type: access was read/write/execute
>>> +     * @maperr: true for invalid page, false for permission fault
>>> +     * @ra: host pc for unwinding
>>> +     *
>>> +     * We are about to raise SIGSEGV with si_code set for @maperr,
>>> +     * and si_addr set for @addr.  Record anything further needed
>>> +     * for the signal ucontext_t.
>>> +     *
>>> +     * If the emulated kernel does not provide anything to the signal
>>> +     * handler with anything besides the user context registers, and
>>> +     * the siginfo_t, then this hook need do nothing and may be omitted.
>>> +     * Otherwise, record the data and return; the caller will raise
>>> +     * the signal, unwind the cpu state, and return to the main loop.
>>> +     *
>>> +     * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
>>> +     * so that a "normal" cpu exception can be raised.  In this case,
>>> +     * the signal must be raised by the architecture cpu_loop.
>>> +     */
>>
>> Shouldn't it have the QEMU_NORETURN attribute?
> 
> Eh now I saw the next patch and understood raise_sigsegv() is
> where QEMU_NORETURN belong :)

Well, I had intended the hook to be able to return, so that the hook can merely set some 
env->fields, and return to raise the signal.  But in the end, all 4 targets that use the 
hook raise the exception themselves -- sometimes because env->exception_index is part of 
the data to be passed to the signal handler.


r~


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

* Re: [PATCH v2 20/41] linux-user: Add raise_sigsegv
  2021-09-18 18:45 ` [PATCH v2 20/41] linux-user: Add raise_sigsegv Richard Henderson
  2021-09-19 18:26   ` Philippe Mathieu-Daudé
@ 2021-09-19 18:35   ` Richard Henderson
  2021-09-19 18:43     ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 71+ messages in thread
From: Richard Henderson @ 2021-09-19 18:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

On 9/18/21 11:45 AM, Richard Henderson wrote:
> +/**
> + * raise_sigsegv:
> + * @cpu: the cpu context
> + * @addr: the guest address of the fault
> + * @access_type: access was read/write/execute
> + * @maperr: true for invalid page, false for permission fault
> + * @ra: host pc for unwinding
> + *
> + * Use the TCGCPUOps hook to record cpu state, do guest operating system
> + * specific things to raise SIGSEGV, and jump to the main cpu loop.
> + */
> +void QEMU_NORETURN raise_sigsegv(CPUState *cpu, target_ulong addr,
> +                                 MMUAccessType access_type,
> +                                 bool maperr, uintptr_t ra);

FYI, something to bikeshed here is the name of the function.  Should it in fact be 
cpu_loop_exit_raise_sigsegv?

Because it can't be used outside of the running cpu context.  (E.g. there are a couple of 
instances where it's tempting to use this from within cpu_loop itself, processing 
pseudo-syscalls.)


r~


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

* Re: [PATCH v2 34/41] target/ppc: Implement ppc_cpu_record_sigsegv
  2021-09-18 18:45 ` [PATCH v2 34/41] target/ppc: Implement ppc_cpu_record_sigsegv Richard Henderson
@ 2021-09-19 18:37   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:37 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> Record DAR, DSISR, and exception_index.  That last means
> that we must exit to cpu_loop ourselves, instead of letting
> exception_index being overwritten.

Maybe complete:

"This is exactly what the user-mode ppc_cpu_tlb_fill() does,
so simply rename it as ppc_cpu_record_sigsegv()."

Otherwise:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/ppc/cpu.h              |  3 ---
>  target/ppc/internal.h         |  9 +++++++++
>  target/ppc/cpu_init.c         |  6 ++++--
>  target/ppc/user_only_helper.c | 15 +++++++++++----
>  4 files changed, 24 insertions(+), 9 deletions(-)


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

* Re: [PATCH v2 37/41] target/s390x: Implement s390_cpu_record_sigsegv
  2021-09-18 18:45 ` [PATCH v2 37/41] target/s390x: Implement s390_cpu_record_sigsegv Richard Henderson
@ 2021-09-19 18:39   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:39 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> Move the masking of the address from cpu_loop into
> s390_cpu_record_sigsegv -- this is governed by hw, not linux.
> This does mean we have to raise our own exception, rather
> than return to the fallback.
> 
> Use maperr to choose between PGM_PROTECTION and PGM_ADDRESSING.
> Use the appropriate si_code for each in cpu_loop.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/s390x-internal.h  | 13 ++++++++++---
>  linux-user/s390x/cpu_loop.c    | 14 +++++++-------
>  target/s390x/cpu.c             |  6 ++++--
>  target/s390x/tcg/excp_helper.c | 18 +++++++++++-------
>  4 files changed, 32 insertions(+), 19 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu
  2021-09-18 18:45 ` [PATCH v2 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu Richard Henderson
@ 2021-09-19 18:40   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:40 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/18/21 20:45, Richard Henderson wrote:
> We have replaced tlb_fill with record_sigsegv for user mod.
> Move the declaration to restrict it to system emulation.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/core/tcg-cpu-ops.h | 22 ++++++++++------------
>  linux-user/signal.c           |  3 ---
>  2 files changed, 10 insertions(+), 15 deletions(-)

Lovely :>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 20/41] linux-user: Add raise_sigsegv
  2021-09-19 18:35   ` Richard Henderson
@ 2021-09-19 18:43     ` Philippe Mathieu-Daudé
  2021-09-19 18:53       ` Warner Losh
  0 siblings, 1 reply; 71+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-09-19 18:43 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 9/19/21 20:35, Richard Henderson wrote:
> On 9/18/21 11:45 AM, Richard Henderson wrote:
>> +/**
>> + * raise_sigsegv:
>> + * @cpu: the cpu context
>> + * @addr: the guest address of the fault
>> + * @access_type: access was read/write/execute
>> + * @maperr: true for invalid page, false for permission fault
>> + * @ra: host pc for unwinding
>> + *
>> + * Use the TCGCPUOps hook to record cpu state, do guest operating system
>> + * specific things to raise SIGSEGV, and jump to the main cpu loop.
>> + */
>> +void QEMU_NORETURN raise_sigsegv(CPUState *cpu, target_ulong addr,
>> +                                 MMUAccessType access_type,
>> +                                 bool maperr, uintptr_t ra);
> 
> FYI, something to bikeshed here is the name of the function.  Should it
> in fact be cpu_loop_exit_raise_sigsegv?

That or cpu_loop_exit_segv() which is explicit enough IMO.

> Because it can't be used outside of the running cpu context.  (E.g.
> there are a couple of instances where it's tempting to use this from
> within cpu_loop itself, processing pseudo-syscalls.)
> 
> 
> r~
> 



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

* Re: [PATCH v2 20/41] linux-user: Add raise_sigsegv
  2021-09-19 18:43     ` Philippe Mathieu-Daudé
@ 2021-09-19 18:53       ` Warner Losh
  0 siblings, 0 replies; 71+ messages in thread
From: Warner Losh @ 2021-09-19 18:53 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: Richard Henderson, qemu-devel, laurent



> On Sep 19, 2021, at 12:43 PM, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> 
> On 9/19/21 20:35, Richard Henderson wrote:
>> On 9/18/21 11:45 AM, Richard Henderson wrote:
>>> +/**
>>> + * raise_sigsegv:
>>> + * @cpu: the cpu context
>>> + * @addr: the guest address of the fault
>>> + * @access_type: access was read/write/execute
>>> + * @maperr: true for invalid page, false for permission fault
>>> + * @ra: host pc for unwinding
>>> + *
>>> + * Use the TCGCPUOps hook to record cpu state, do guest operating system
>>> + * specific things to raise SIGSEGV, and jump to the main cpu loop.
>>> + */
>>> +void QEMU_NORETURN raise_sigsegv(CPUState *cpu, target_ulong addr,
>>> +                                 MMUAccessType access_type,
>>> +                                 bool maperr, uintptr_t ra);
>> 
>> FYI, something to bikeshed here is the name of the function.  Should it
>> in fact be cpu_loop_exit_raise_sigsegv?
> 
> That or cpu_loop_exit_segv() which is explicit enough IMO.

That name works for me…

Also, and this is a stretch so consider it maybe a bit weak…

Reviewed by: Warner Losh <imp@bsdimp.com>


> Because it can't be used outside of the running cpu context.  (E.g.
>> 
>> there are a couple of instances where it's tempting to use this from
>> within cpu_loop itself, processing pseudo-syscalls.)
>> 
>> 
>> r~
>> 
> 
> 



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

* Re: [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv
  2021-09-18 18:45 ` [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv Richard Henderson
  2021-09-19 18:32   ` Philippe Mathieu-Daudé
@ 2021-09-19 18:59   ` Warner Losh
  1 sibling, 0 replies; 71+ messages in thread
From: Warner Losh @ 2021-09-19 18:59 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent



> On Sep 18, 2021, at 12:45 PM, Richard Henderson <richard.henderson@linaro.org> wrote:
> 
> Record cr2, error_code, and exception_index.  That last means
> that we must exit to cpu_loop ourselves, instead of letting
> exception_index being overwritten.
> 
> Use the maperr parameter to properly set PG_ERROR_P_MASK.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/helper-tcg.h       |  6 ++++++
> target/i386/tcg/tcg-cpu.c          |  3 ++-
> target/i386/tcg/user/excp_helper.c | 23 +++++++++++++++++------
> 3 files changed, 25 insertions(+), 7 deletions(-)


Reviewed by: Warner Losh <imp@bsdimp.com>

I think this encoding is fine, but haven’t thought though how I’d implement
this in bsd-user yet…  I have the signal code queued up, but not ready to send
off yet.

> diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
> index 60ca09e95e..0a4401e917 100644
> --- a/target/i386/tcg/helper-tcg.h
> +++ b/target/i386/tcg/helper-tcg.h
> @@ -43,9 +43,15 @@ bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
> #endif
> 
> /* helper.c */
> +#ifdef CONFIG_USER_ONLY
> +void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
> +                            MMUAccessType access_type,
> +                            bool maperr, uintptr_t ra);
> +#else
> bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>                       MMUAccessType access_type, int mmu_idx,
>                       bool probe, uintptr_t retaddr);
> +#endif
> 
> void breakpoint_handler(CPUState *cs);
> 
> diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
> index aef050d089..3fab3676b1 100644
> --- a/target/i386/tcg/tcg-cpu.c
> +++ b/target/i386/tcg/tcg-cpu.c
> @@ -77,11 +77,12 @@ static const struct TCGCPUOps x86_tcg_ops = {
>     .synchronize_from_tb = x86_cpu_synchronize_from_tb,
>     .cpu_exec_enter = x86_cpu_exec_enter,
>     .cpu_exec_exit = x86_cpu_exec_exit,
> -    .tlb_fill = x86_cpu_tlb_fill,
> #ifdef CONFIG_USER_ONLY
>     .fake_user_interrupt = x86_cpu_do_interrupt,
> +    .record_sigsegv = x86_cpu_record_sigsegv,
> #else
>     .has_work = x86_cpu_has_work,
> +    .tlb_fill = x86_cpu_tlb_fill,
>     .do_interrupt = x86_cpu_do_interrupt,
>     .cpu_exec_interrupt = x86_cpu_exec_interrupt,
>     .debug_excp_handler = breakpoint_handler,
> diff --git a/target/i386/tcg/user/excp_helper.c b/target/i386/tcg/user/excp_helper.c
> index a89b5228fd..cd507e2a1b 100644
> --- a/target/i386/tcg/user/excp_helper.c
> +++ b/target/i386/tcg/user/excp_helper.c
> @@ -22,18 +22,29 @@
> #include "exec/exec-all.h"
> #include "tcg/helper-tcg.h"
> 
> -bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
> -                      MMUAccessType access_type, int mmu_idx,
> -                      bool probe, uintptr_t retaddr)
> +void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
> +                            MMUAccessType access_type,
> +                            bool maperr, uintptr_t ra)
> {
>     X86CPU *cpu = X86_CPU(cs);
>     CPUX86State *env = &cpu->env;
> 
> +    /*
> +     * The error_code that hw reports as part of the exception frame
> +     * is copied to linux sigcontext.err.  The exception_index is
> +     * copied to linux sigcontext.trapno.  Short of inventing a new
> +     * place to store the trapno, we cannot let our caller raise the
> +     * signal and set exception_index to EXCP_INTERRUPT.
> +     */
>     env->cr[2] = addr;
> -    env->error_code = (access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT;
> -    env->error_code |= PG_ERROR_U_MASK;
> +    env->error_code = ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
> +                    | (maperr ? 0 : PG_ERROR_P_MASK)
> +                    | PG_ERROR_U_MASK;
>     cs->exception_index = EXCP0E_PAGE;
> +
> +    /* Disable do_interrupt_user. */
>     env->exception_is_int = 0;
>     env->exception_next_eip = -1;
> -    cpu_loop_exit_restore(cs, retaddr);
> +
> +    cpu_loop_exit_restore(cs, ra);
> }
> -- 
> 2.25.1
> 
> 



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

* Re: [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER
  2021-09-18 18:45 ` [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER Richard Henderson
  2021-09-19 18:18   ` Philippe Mathieu-Daudé
@ 2021-09-19 18:59   ` Warner Losh
  1 sibling, 0 replies; 71+ messages in thread
From: Warner Losh @ 2021-09-19 18:59 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent



> On Sep 18, 2021, at 12:45 PM, Richard Henderson <richard.henderson@linaro.org> wrote:
> 
> Now that all of the linux-user hosts have been converted
> to host-signal.h, drop the compatibility code.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/exec/exec-all.h | 12 ------------
> linux-user/signal.c     | 13 -------------
> 2 files changed, 25 deletions(-)

Reviewed by: Warner Losh <imp@bsdimp.com>

> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 5f94d799aa..5dd663c153 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -685,18 +685,6 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
> bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
>                                  uintptr_t host_pc, abi_ptr guest_addr);
> 
> -/**
> - * cpu_signal_handler
> - * @signum: host signal number
> - * @pinfo: host siginfo_t
> - * @puc: host ucontext_t
> - *
> - * To be called from the SIGBUS and SIGSEGV signal handler to inform the
> - * virtual cpu of exceptions.  Returns true if the signal was handled by
> - * the virtual CPU.
> - */
> -int cpu_signal_handler(int signum, void *pinfo, void *puc);
> -
> #else
> static inline void mmap_lock(void) {}
> static inline void mmap_unlock(void) {}
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 6f953f10d4..e6531fdfa0 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -773,16 +773,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
>     ucontext_t *uc = puc;
>     struct emulated_sigtable *k;
>     int guest_sig;
> -
> -#ifdef HOST_SIGNAL_PLACEHOLDER
> -    /* the CPU emulator uses some host signals to detect exceptions,
> -       we forward to it some signals */
> -    if ((host_sig == SIGSEGV || host_sig == SIGBUS)
> -        && info->si_code > 0) {
> -        if (cpu_signal_handler(host_sig, info, puc))
> -            return;
> -    }
> -#else
>     uintptr_t pc = 0;
>     bool sync_sig = false;
> 
> @@ -842,7 +832,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
> 
>         sync_sig = true;
>     }
> -#endif
> 
>     /* get target signal number */
>     guest_sig = host_to_target_signal(host_sig);
> @@ -857,7 +846,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
>     k->pending = guest_sig;
>     ts->signal_pending = 1;
> 
> -#ifndef HOST_SIGNAL_PLACEHOLDER
>     /*
>      * For synchronous signals, unwind the cpu state to the faulting
>      * insn and then exit back to the main loop so that the signal
> @@ -867,7 +855,6 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
>         cpu->exception_index = EXCP_INTERRUPT;
>         cpu_loop_exit_restore(cpu, pc);
>     }
> -#endif
> 
>     rewind_if_in_safe_syscall(puc);
> 
> -- 
> 2.25.1
> 
> 



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

* Re: [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV
  2021-09-18 18:44 ` [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV Richard Henderson
  2021-09-19 18:02   ` Philippe Mathieu-Daudé
@ 2021-09-19 19:01   ` Warner Losh
  2021-09-19 23:01   ` Alistair Francis
  2 siblings, 0 replies; 71+ messages in thread
From: Warner Losh @ 2021-09-19 19:01 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent



> On Sep 18, 2021, at 12:44 PM, Richard Henderson <richard.henderson@linaro.org> wrote:
> 
> Add stub host-signal.h for all linux-user hosts.
> Add new code replacing cpu_signal_handler.
> Full migration will happen one host at a time.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> linux-user/host/aarch64/host-signal.h |   1 +
> linux-user/host/arm/host-signal.h     |   1 +
> linux-user/host/i386/host-signal.h    |   1 +
> linux-user/host/mips/host-signal.h    |   1 +
> linux-user/host/ppc/host-signal.h     |   1 +
> linux-user/host/ppc64/host-signal.h   |   1 +
> linux-user/host/riscv/host-signal.h   |   1 +
> linux-user/host/s390/host-signal.h    |   1 +
> linux-user/host/s390x/host-signal.h   |   1 +
> linux-user/host/sparc/host-signal.h   |   1 +
> linux-user/host/sparc64/host-signal.h |   1 +
> linux-user/host/x32/host-signal.h     |   1 +
> linux-user/host/x86_64/host-signal.h  |   1 +
> linux-user/signal.c                   | 109 ++++++++++++++++++++++----
> 14 files changed, 106 insertions(+), 16 deletions(-)
> create mode 100644 linux-user/host/aarch64/host-signal.h
> create mode 100644 linux-user/host/arm/host-signal.h
> create mode 100644 linux-user/host/i386/host-signal.h
> create mode 100644 linux-user/host/mips/host-signal.h
> create mode 100644 linux-user/host/ppc/host-signal.h
> create mode 100644 linux-user/host/ppc64/host-signal.h
> create mode 100644 linux-user/host/riscv/host-signal.h
> create mode 100644 linux-user/host/s390/host-signal.h
> create mode 100644 linux-user/host/s390x/host-signal.h
> create mode 100644 linux-user/host/sparc/host-signal.h
> create mode 100644 linux-user/host/sparc64/host-signal.h
> create mode 100644 linux-user/host/x32/host-signal.h
> create mode 100644 linux-user/host/x86_64/host-signal.h

Seems sensible to me.

Reviewed-by: Warner Losh <imp@bsdimp.com>


> diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/aarch64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/arm/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/i386/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/mips/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/ppc/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/ppc64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/riscv/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/s390/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/s390x/host-signal.h b/linux-user/host/s390x/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/s390x/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/sparc/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/sparc64/host-signal.h b/linux-user/host/sparc64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/sparc64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/x32/host-signal.h b/linux-user/host/x32/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/x32/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/x86_64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 5ea8e4584a..6f953f10d4 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -18,12 +18,15 @@
>  */
> #include "qemu/osdep.h"
> #include "qemu/bitops.h"
> +#include "hw/core/tcg-cpu-ops.h"
> +
> #include <sys/ucontext.h>
> #include <sys/resource.h>
> 
> #include "qemu.h"
> #include "trace.h"
> #include "signal-common.h"
> +#include "host-signal.h"
> 
> static struct target_sigaction sigact_table[TARGET_NSIG];
> 
> @@ -761,41 +764,115 @@ static inline void rewind_if_in_safe_syscall(void *puc)
> }
> #endif
> 
> -static void host_signal_handler(int host_signum, siginfo_t *info,
> -                                void *puc)
> +static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
> {
>     CPUArchState *env = thread_cpu->env_ptr;
>     CPUState *cpu = env_cpu(env);
>     TaskState *ts = cpu->opaque;
> -
> -    int sig;
>     target_siginfo_t tinfo;
>     ucontext_t *uc = puc;
>     struct emulated_sigtable *k;
> +    int guest_sig;
> 
> +#ifdef HOST_SIGNAL_PLACEHOLDER
>     /* the CPU emulator uses some host signals to detect exceptions,
>        we forward to it some signals */
> -    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
> +    if ((host_sig == SIGSEGV || host_sig == SIGBUS)
>         && info->si_code > 0) {
> -        if (cpu_signal_handler(host_signum, info, puc))
> +        if (cpu_signal_handler(host_sig, info, puc))
>             return;
>     }
> +#else
> +    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) {
> +            const struct TCGCPUOps *tcg_ops;
> +
> +            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);
> +
> +            tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
> +            tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
> +                              MMU_USER_IDX, false, pc);
> +            g_assert_not_reached();
> +        } else {
> +            sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
> +        }
> +
> +        sync_sig = true;
> +    }
> +#endif
> 
>     /* get target signal number */
> -    sig = host_to_target_signal(host_signum);
> -    if (sig < 1 || sig > TARGET_NSIG)
> +    guest_sig = host_to_target_signal(host_sig);
> +    if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
>         return;
> -    trace_user_host_signal(env, host_signum, sig);
> +    }
> +    trace_user_host_signal(env, host_sig, guest_sig);
> +
> +    host_to_target_siginfo_noswap(&tinfo, info);
> +    k = &ts->sigtab[guest_sig - 1];
> +    k->info = tinfo;
> +    k->pending = guest_sig;
> +    ts->signal_pending = 1;
> +
> +#ifndef HOST_SIGNAL_PLACEHOLDER
> +    /*
> +     * For synchronous signals, unwind the cpu state to the faulting
> +     * insn and then exit back to the main loop so that the signal
> +     * is delivered immediately.
> +     */
> +    if (sync_sig) {
> +        cpu->exception_index = EXCP_INTERRUPT;
> +        cpu_loop_exit_restore(cpu, pc);
> +    }
> +#endif
> 
>     rewind_if_in_safe_syscall(puc);
> 
> -    host_to_target_siginfo_noswap(&tinfo, info);
> -    k = &ts->sigtab[sig - 1];
> -    k->info = tinfo;
> -    k->pending = sig;
> -    ts->signal_pending = 1;
> -
> -    /* Block host signals until target signal handler entered. We
> +    /*
> +     * 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
> -- 
> 2.25.1
> 
> 



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

* Re: [PATCH v2 08/41] linux-user/host/ppc: Populate host_signal.h
  2021-09-18 18:44 ` [PATCH v2 08/41] linux-user/host/ppc: " Richard Henderson
@ 2021-09-19 19:34   ` Warner Losh
  0 siblings, 0 replies; 71+ messages in thread
From: Warner Losh @ 2021-09-19 19:34 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, laurent



> On Sep 18, 2021, at 12:44 PM, Richard Henderson <richard.henderson@linaro.org> wrote:
> 
> Split host_signal_pc and host_signal_write out of user-exec.c.
> Drop the *BSD code, to be re-created under bsd-user/ later.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> linux-user/host/ppc/host-signal.h   | 25 ++++++++-
> linux-user/host/ppc64/host-signal.h |  2 +-
> accel/tcg/user-exec.c               | 79 +----------------------------
> 3 files changed, 26 insertions(+), 80 deletions(-)

This is going to be a little work for me, but I’ll be able to snag most of it from
the - lines in this patch. It’s a better structure, to be honest, since we were
building user-exec.c for some platforms that never really had bsd-user
and a natural consequence of this patch will stop that.

Reviewed-by: Warner Losh <imp@bsdimp.com>


> diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h
> index f4b4d65031..e09756c691 100644
> --- a/linux-user/host/ppc/host-signal.h
> +++ b/linux-user/host/ppc/host-signal.h
> @@ -1 +1,24 @@
> -#define HOST_SIGNAL_PLACEHOLDER
> +/*
> + * host-signal.h: signal info dependent on the host architecture
> + *
> + * Copyright (C) 2021 Linaro Limited
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef PPC_HOST_SIGNAL_H
> +#define PPC_HOST_SIGNAL_H
> +
> +static inline uintptr_t host_signal_pc(ucontext_t *uc)
> +{
> +    return uc->uc_mcontext.regs->nip;
> +}
> +
> +static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
> +{
> +    return uc->uc_mcontext.regs->trap != 0x400
> +        && (uc->uc_mcontext.regs->dsisr & 0x02000000);
> +}
> +
> +#endif
> diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/host-signal.h
> index f4b4d65031..a353c22a90 100644
> --- a/linux-user/host/ppc64/host-signal.h
> +++ b/linux-user/host/ppc64/host-signal.h
> @@ -1 +1 @@
> -#define HOST_SIGNAL_PLACEHOLDER
> +#include "../ppc/host-signal.h"
> diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
> index b5d06183db..e9e530e2e1 100644
> --- a/accel/tcg/user-exec.c
> +++ b/accel/tcg/user-exec.c
> @@ -255,84 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
>     return size ? g2h(env_cpu(env), addr) : NULL;
> }
> 
> -#if defined(_ARCH_PPC)
> -
> -/***********************************************************************
> - * signal context platform-specific definitions
> - * From Wine
> - */
> -#ifdef linux
> -/* All Registers access - only for local access */
> -#define REG_sig(reg_name, context)              \
> -    ((context)->uc_mcontext.regs->reg_name)
> -/* Gpr Registers access  */
> -#define GPR_sig(reg_num, context)              REG_sig(gpr[reg_num], context)
> -/* Program counter */
> -#define IAR_sig(context)                       REG_sig(nip, context)
> -/* Machine State Register (Supervisor) */
> -#define MSR_sig(context)                       REG_sig(msr, context)
> -/* Count register */
> -#define CTR_sig(context)                       REG_sig(ctr, context)
> -/* User's integer exception register */
> -#define XER_sig(context)                       REG_sig(xer, context)
> -/* Link register */
> -#define LR_sig(context)                        REG_sig(link, context)
> -/* Condition register */
> -#define CR_sig(context)                        REG_sig(ccr, context)
> -
> -/* Float Registers access  */
> -#define FLOAT_sig(reg_num, context)                                     \
> -    (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num])
> -#define FPSCR_sig(context) \
> -    (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4)))
> -/* Exception Registers access */
> -#define DAR_sig(context)                       REG_sig(dar, context)
> -#define DSISR_sig(context)                     REG_sig(dsisr, context)
> -#define TRAP_sig(context)                      REG_sig(trap, context)
> -#endif /* linux */
> -
> -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
> -#include <ucontext.h>
> -#define IAR_sig(context)               ((context)->uc_mcontext.mc_srr0)
> -#define MSR_sig(context)               ((context)->uc_mcontext.mc_srr1)
> -#define CTR_sig(context)               ((context)->uc_mcontext.mc_ctr)
> -#define XER_sig(context)               ((context)->uc_mcontext.mc_xer)
> -#define LR_sig(context)                ((context)->uc_mcontext.mc_lr)
> -#define CR_sig(context)                ((context)->uc_mcontext.mc_cr)
> -/* Exception Registers access */
> -#define DAR_sig(context)               ((context)->uc_mcontext.mc_dar)
> -#define DSISR_sig(context)             ((context)->uc_mcontext.mc_dsisr)
> -#define TRAP_sig(context)              ((context)->uc_mcontext.mc_exc)
> -#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
> -
> -int cpu_signal_handler(int host_signum, void *pinfo,
> -                       void *puc)
> -{
> -    siginfo_t *info = pinfo;
> -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
> -    ucontext_t *uc = puc;
> -#else
> -    ucontext_t *uc = puc;
> -#endif
> -    unsigned long pc;
> -    int is_write;
> -
> -    pc = IAR_sig(uc);
> -    is_write = 0;
> -#if 0
> -    /* ppc 4xx case */
> -    if (DSISR_sig(uc) & 0x00800000) {
> -        is_write = 1;
> -    }
> -#else
> -    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) {
> -        is_write = 1;
> -    }
> -#endif
> -    return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
> -}
> -
> -#elif defined(__alpha__)
> +#if defined(__alpha__)
> 
> int cpu_signal_handler(int host_signum, void *pinfo,
>                            void *puc)
> -- 
> 2.25.1
> 
> 



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

* Re: [PATCH v2 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop
  2021-09-18 18:44 ` [PATCH v2 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop Richard Henderson
@ 2021-09-19 19:35   ` Warner Losh
  0 siblings, 0 replies; 71+ messages in thread
From: Warner Losh @ 2021-09-19 19:35 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent



> On Sep 18, 2021, at 12:44 PM, Richard Henderson <richard.henderson@linaro.org> wrote:
> 
> Currently there are only two places that require we reset this
> value before exiting to the main loop, but that will change.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/cpu-exec.c  | 3 ++-
> accel/tcg/user-exec.c | 2 --
> 2 files changed, 2 insertions(+), 3 deletions(-)

Reviewed-by: Warner Losh <imp@bsdimp.com>

> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 5fd1ed3422..410588d08a 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -451,6 +451,7 @@ void cpu_exec_step_atomic(CPUState *cpu)
>          * memory.
>          */
> #ifndef CONFIG_SOFTMMU
> +        clear_helper_retaddr();
>         tcg_debug_assert(!have_mmap_lock());
> #endif
>         if (qemu_mutex_iothread_locked()) {
> @@ -460,7 +461,6 @@ void cpu_exec_step_atomic(CPUState *cpu)
>         qemu_plugin_disable_mem_helpers(cpu);
>     }
> 
> -
>     /*
>      * As we start the exclusive region before codegen we must still
>      * be in the region if we longjump out of either the codegen or
> @@ -905,6 +905,7 @@ int cpu_exec(CPUState *cpu)
> #endif
> 
> #ifndef CONFIG_SOFTMMU
> +        clear_helper_retaddr();
>         tcg_debug_assert(!have_mmap_lock());
> #endif
>         if (qemu_mutex_iothread_locked()) {
> diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
> index cef025d001..e94f1fed00 100644
> --- a/accel/tcg/user-exec.c
> +++ b/accel/tcg/user-exec.c
> @@ -175,7 +175,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
>              * currently executing TB was modified and must be exited
>              * immediately.  Clear helper_retaddr for next execution.
>              */
> -            clear_helper_retaddr();
>             cpu_exit_tb_from_sighandler(cpu, old_set);
>             /* NORETURN */
> 
> @@ -193,7 +192,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
>      * an exception.  Undo signal and retaddr state prior to longjmp.
>      */
>     sigprocmask(SIG_SETMASK, old_set, NULL);
> -    clear_helper_retaddr();
> 
>     cc = CPU_GET_CLASS(cpu);
>     cc->tcg_ops->tlb_fill(cpu, address, 0, access_type,
> -- 
> 2.25.1
> 
> 



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

* Re: [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures
  2021-09-18 18:44 ` [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures Richard Henderson
  2021-09-19 17:56   ` Philippe Mathieu-Daudé
@ 2021-09-19 22:57   ` Alistair Francis
  1 sibling, 0 replies; 71+ messages in thread
From: Alistair Francis @ 2021-09-19 22:57 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel@nongnu.org Developers, Laurent Vivier

On Sun, Sep 19, 2021 at 4:53 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The existing code for safe-syscall.inc.S will compile
> without change for riscv32 and riscv64.  We may also
> drop the meson.build stanza that merges them for tcg/.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  configure                                             |  8 ++------
>  meson.build                                           |  4 +---
>  linux-user/host/{riscv64 => riscv}/hostdep.h          |  4 ++--
>  linux-user/host/riscv32/hostdep.h                     | 11 -----------
>  linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S |  0
>  5 files changed, 5 insertions(+), 22 deletions(-)
>  rename linux-user/host/{riscv64 => riscv}/hostdep.h (94%)
>  delete mode 100644 linux-user/host/riscv32/hostdep.h
>  rename linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S (100%)
>
> diff --git a/configure b/configure
> index da2501489f..6ff037bac1 100755
> --- a/configure
> +++ b/configure
> @@ -650,11 +650,7 @@ elif check_define __s390__ ; then
>      cpu="s390"
>    fi
>  elif check_define __riscv ; then
> -  if check_define _LP64 ; then
> -    cpu="riscv64"
> -  else
> -    cpu="riscv32"
> -  fi
> +  cpu="riscv"
>  elif check_define __arm__ ; then
>    cpu="arm"
>  elif check_define __aarch64__ ; then
> @@ -667,7 +663,7 @@ ARCH=
>  # Normalise host CPU name and set ARCH.
>  # Note that this case should only have supported host CPUs, not guests.
>  case "$cpu" in
> -  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64)
> +  ppc|ppc64|s390x|sparc64|x32|riscv)
>    ;;
>    ppc64le)
>      ARCH="ppc64"
> diff --git a/meson.build b/meson.build
> index 2711cbb789..c35a230bf0 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -56,7 +56,7 @@ have_block = have_system or have_tools
>  python = import('python').find_installation()
>
>  supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
> -supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
> +supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
>    'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
>
>  cpu = host_machine.cpu_family()
> @@ -271,8 +271,6 @@ if not get_option('tcg').disabled()
>      tcg_arch = 'i386'
>    elif config_host['ARCH'] == 'ppc64'
>      tcg_arch = 'ppc'
> -  elif config_host['ARCH'] in ['riscv32', 'riscv64']
> -    tcg_arch = 'riscv'
>    endif
>    add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
>                          language: ['c', 'cpp', 'objc'])
> diff --git a/linux-user/host/riscv64/hostdep.h b/linux-user/host/riscv/hostdep.h
> similarity index 94%
> rename from linux-user/host/riscv64/hostdep.h
> rename to linux-user/host/riscv/hostdep.h
> index 865f0fb9ff..2ba07456ae 100644
> --- a/linux-user/host/riscv64/hostdep.h
> +++ b/linux-user/host/riscv/hostdep.h
> @@ -5,8 +5,8 @@
>   * See the COPYING file in the top-level directory.
>   */
>
> -#ifndef RISCV64_HOSTDEP_H
> -#define RISCV64_HOSTDEP_H
> +#ifndef RISCV_HOSTDEP_H
> +#define RISCV_HOSTDEP_H
>
>  /* We have a safe-syscall.inc.S */
>  #define HAVE_SAFE_SYSCALL
> diff --git a/linux-user/host/riscv32/hostdep.h b/linux-user/host/riscv32/hostdep.h
> deleted file mode 100644
> index adf9edbf2d..0000000000
> --- a/linux-user/host/riscv32/hostdep.h
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/*
> - * hostdep.h : things which are dependent on the host architecture
> - *
> - * This work is licensed under the terms of the GNU GPL, version 2 or later.
> - * See the COPYING file in the top-level directory.
> - */
> -
> -#ifndef RISCV32_HOSTDEP_H
> -#define RISCV32_HOSTDEP_H
> -
> -#endif
> diff --git a/linux-user/host/riscv64/safe-syscall.inc.S b/linux-user/host/riscv/safe-syscall.inc.S
> similarity index 100%
> rename from linux-user/host/riscv64/safe-syscall.inc.S
> rename to linux-user/host/riscv/safe-syscall.inc.S
> --
> 2.25.1
>
>


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

* Re: [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV
  2021-09-18 18:44 ` [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV Richard Henderson
  2021-09-19 18:02   ` Philippe Mathieu-Daudé
  2021-09-19 19:01   ` Warner Losh
@ 2021-09-19 23:01   ` Alistair Francis
  2 siblings, 0 replies; 71+ messages in thread
From: Alistair Francis @ 2021-09-19 23:01 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel@nongnu.org Developers, Laurent Vivier

On Sun, Sep 19, 2021 at 4:55 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Add stub host-signal.h for all linux-user hosts.
> Add new code replacing cpu_signal_handler.
> Full migration will happen one host at a time.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  linux-user/host/aarch64/host-signal.h |   1 +
>  linux-user/host/arm/host-signal.h     |   1 +
>  linux-user/host/i386/host-signal.h    |   1 +
>  linux-user/host/mips/host-signal.h    |   1 +
>  linux-user/host/ppc/host-signal.h     |   1 +
>  linux-user/host/ppc64/host-signal.h   |   1 +
>  linux-user/host/riscv/host-signal.h   |   1 +
>  linux-user/host/s390/host-signal.h    |   1 +
>  linux-user/host/s390x/host-signal.h   |   1 +
>  linux-user/host/sparc/host-signal.h   |   1 +
>  linux-user/host/sparc64/host-signal.h |   1 +
>  linux-user/host/x32/host-signal.h     |   1 +
>  linux-user/host/x86_64/host-signal.h  |   1 +
>  linux-user/signal.c                   | 109 ++++++++++++++++++++++----
>  14 files changed, 106 insertions(+), 16 deletions(-)
>  create mode 100644 linux-user/host/aarch64/host-signal.h
>  create mode 100644 linux-user/host/arm/host-signal.h
>  create mode 100644 linux-user/host/i386/host-signal.h
>  create mode 100644 linux-user/host/mips/host-signal.h
>  create mode 100644 linux-user/host/ppc/host-signal.h
>  create mode 100644 linux-user/host/ppc64/host-signal.h
>  create mode 100644 linux-user/host/riscv/host-signal.h
>  create mode 100644 linux-user/host/s390/host-signal.h
>  create mode 100644 linux-user/host/s390x/host-signal.h
>  create mode 100644 linux-user/host/sparc/host-signal.h
>  create mode 100644 linux-user/host/sparc64/host-signal.h
>  create mode 100644 linux-user/host/x32/host-signal.h
>  create mode 100644 linux-user/host/x86_64/host-signal.h
>
> diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/aarch64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/arm/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/i386/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/mips/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/ppc/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/ppc64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/riscv/host-signal.h b/linux-user/host/riscv/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/riscv/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/s390/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/s390x/host-signal.h b/linux-user/host/s390x/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/s390x/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/sparc/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/sparc64/host-signal.h b/linux-user/host/sparc64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/sparc64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/x32/host-signal.h b/linux-user/host/x32/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/x32/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/host-signal.h
> new file mode 100644
> index 0000000000..f4b4d65031
> --- /dev/null
> +++ b/linux-user/host/x86_64/host-signal.h
> @@ -0,0 +1 @@
> +#define HOST_SIGNAL_PLACEHOLDER
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 5ea8e4584a..6f953f10d4 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -18,12 +18,15 @@
>   */
>  #include "qemu/osdep.h"
>  #include "qemu/bitops.h"
> +#include "hw/core/tcg-cpu-ops.h"
> +
>  #include <sys/ucontext.h>
>  #include <sys/resource.h>
>
>  #include "qemu.h"
>  #include "trace.h"
>  #include "signal-common.h"
> +#include "host-signal.h"
>
>  static struct target_sigaction sigact_table[TARGET_NSIG];
>
> @@ -761,41 +764,115 @@ static inline void rewind_if_in_safe_syscall(void *puc)
>  }
>  #endif
>
> -static void host_signal_handler(int host_signum, siginfo_t *info,
> -                                void *puc)
> +static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
>  {
>      CPUArchState *env = thread_cpu->env_ptr;
>      CPUState *cpu = env_cpu(env);
>      TaskState *ts = cpu->opaque;
> -
> -    int sig;
>      target_siginfo_t tinfo;
>      ucontext_t *uc = puc;
>      struct emulated_sigtable *k;
> +    int guest_sig;
>
> +#ifdef HOST_SIGNAL_PLACEHOLDER
>      /* the CPU emulator uses some host signals to detect exceptions,
>         we forward to it some signals */
> -    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
> +    if ((host_sig == SIGSEGV || host_sig == SIGBUS)
>          && info->si_code > 0) {
> -        if (cpu_signal_handler(host_signum, info, puc))
> +        if (cpu_signal_handler(host_sig, info, puc))
>              return;
>      }
> +#else
> +    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) {
> +            const struct TCGCPUOps *tcg_ops;
> +
> +            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);
> +
> +            tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
> +            tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
> +                              MMU_USER_IDX, false, pc);
> +            g_assert_not_reached();
> +        } else {
> +            sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
> +        }
> +
> +        sync_sig = true;
> +    }
> +#endif
>
>      /* get target signal number */
> -    sig = host_to_target_signal(host_signum);
> -    if (sig < 1 || sig > TARGET_NSIG)
> +    guest_sig = host_to_target_signal(host_sig);
> +    if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
>          return;
> -    trace_user_host_signal(env, host_signum, sig);
> +    }
> +    trace_user_host_signal(env, host_sig, guest_sig);
> +
> +    host_to_target_siginfo_noswap(&tinfo, info);
> +    k = &ts->sigtab[guest_sig - 1];
> +    k->info = tinfo;
> +    k->pending = guest_sig;
> +    ts->signal_pending = 1;
> +
> +#ifndef HOST_SIGNAL_PLACEHOLDER
> +    /*
> +     * For synchronous signals, unwind the cpu state to the faulting
> +     * insn and then exit back to the main loop so that the signal
> +     * is delivered immediately.
> +     */
> +    if (sync_sig) {
> +        cpu->exception_index = EXCP_INTERRUPT;
> +        cpu_loop_exit_restore(cpu, pc);
> +    }
> +#endif
>
>      rewind_if_in_safe_syscall(puc);
>
> -    host_to_target_siginfo_noswap(&tinfo, info);
> -    k = &ts->sigtab[sig - 1];
> -    k->info = tinfo;
> -    k->pending = sig;
> -    ts->signal_pending = 1;
> -
> -    /* Block host signals until target signal handler entered. We
> +    /*
> +     * 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
> --
> 2.25.1
>
>


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

end of thread, other threads:[~2021-09-19 23:03 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-18 18:44 [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Richard Henderson
2021-09-18 18:44 ` [PATCH v2 01/41] accel/tcg: Split out adjust_signal_pc Richard Henderson
2021-09-18 18:44 ` [PATCH v2 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop Richard Henderson
2021-09-19 19:35   ` Warner Losh
2021-09-18 18:44 ` [PATCH v2 03/41] accel/tcg: Split out handle_sigsegv_accerr_write Richard Henderson
2021-09-18 18:44 ` [PATCH v2 04/41] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller Richard Henderson
2021-09-18 18:44 ` [PATCH v2 05/41] configure: Merge riscv32 and riscv64 host architectures Richard Henderson
2021-09-19 17:56   ` Philippe Mathieu-Daudé
2021-09-19 22:57   ` Alistair Francis
2021-09-18 18:44 ` [PATCH v2 06/41] linux-user: Reorg handling for SIGSEGV Richard Henderson
2021-09-19 18:02   ` Philippe Mathieu-Daudé
2021-09-19 19:01   ` Warner Losh
2021-09-19 23:01   ` Alistair Francis
2021-09-18 18:44 ` [PATCH v2 07/41] linux-user/host/x86: Populate host_signal.h Richard Henderson
2021-09-18 18:44 ` [PATCH v2 08/41] linux-user/host/ppc: " Richard Henderson
2021-09-19 19:34   ` Warner Losh
2021-09-18 18:44 ` [PATCH v2 09/41] linux-user/host/alpha: " Richard Henderson
2021-09-19 18:03   ` Philippe Mathieu-Daudé
2021-09-19 18:07     ` Richard Henderson
2021-09-19 18:11       ` Philippe Mathieu-Daudé
2021-09-19 18:13   ` Philippe Mathieu-Daudé
2021-09-18 18:44 ` [PATCH v2 10/41] linux-user/host/sparc: " Richard Henderson
2021-09-18 18:44 ` [PATCH v2 11/41] linux-user/host/arm: " Richard Henderson
2021-09-18 18:44 ` [PATCH v2 12/41] linux-user/host/aarch64: " Richard Henderson
2021-09-18 18:44 ` [PATCH v2 13/41] linux-user/host/s390: " Richard Henderson
2021-09-19 18:07   ` Philippe Mathieu-Daudé
2021-09-18 18:45 ` [PATCH v2 14/41] linux-user/host/mips: " Richard Henderson
2021-09-19 18:08   ` Philippe Mathieu-Daudé
2021-09-18 18:45 ` [PATCH v2 15/41] linux-user/host/riscv: " Richard Henderson
2021-09-18 18:45 ` [PATCH v2 16/41] target/arm: Fixup comment re handle_cpu_signal Richard Henderson
2021-09-18 18:45 ` [PATCH v2 17/41] linux-user/host/riscv: Improve host_signal_write Richard Henderson
2021-09-18 18:45 ` [PATCH v2 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER Richard Henderson
2021-09-19 18:18   ` Philippe Mathieu-Daudé
2021-09-19 18:59   ` Warner Losh
2021-09-18 18:45 ` [PATCH v2 19/41] hw/core: Add TCGCPUOps.record_sigsegv Richard Henderson
2021-09-19 18:22   ` Philippe Mathieu-Daudé
2021-09-19 18:24     ` Philippe Mathieu-Daudé
2021-09-19 18:32       ` Richard Henderson
2021-09-18 18:45 ` [PATCH v2 20/41] linux-user: Add raise_sigsegv Richard Henderson
2021-09-19 18:26   ` Philippe Mathieu-Daudé
2021-09-19 18:35   ` Richard Henderson
2021-09-19 18:43     ` Philippe Mathieu-Daudé
2021-09-19 18:53       ` Warner Losh
2021-09-18 18:45 ` [PATCH v2 21/41] target/alpha: Make alpha_cpu_tlb_fill sysemu only Richard Henderson
2021-09-18 18:45 ` [PATCH v2 22/41] target/arm: Use raise_sigsegv for mte tag lookup Richard Henderson
2021-09-18 18:45 ` [PATCH v2 23/41] target/arm: Implement arm_cpu_record_sigsegv Richard Henderson
2021-09-18 18:45 ` [PATCH v2 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only Richard Henderson
2021-09-19 18:28   ` Philippe Mathieu-Daudé
2021-09-18 18:45 ` [PATCH v2 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill Richard Henderson
2021-09-18 18:45 ` [PATCH v2 26/41] target/hppa: Make hppa_cpu_tlb_fill sysemu only Richard Henderson
2021-09-18 18:45 ` [PATCH v2 27/41] target/i386: Implement x86_cpu_record_sigsegv Richard Henderson
2021-09-19 18:32   ` Philippe Mathieu-Daudé
2021-09-19 18:59   ` Warner Losh
2021-09-18 18:45 ` [PATCH v2 28/41] target/m68k: Make m68k_cpu_tlb_fill sysemu only Richard Henderson
2021-09-18 18:45 ` [PATCH v2 29/41] target/microblaze: Make mb_cpu_tlb_fill " Richard Henderson
2021-09-18 18:45 ` [PATCH v2 30/41] target/mips: Make mips_cpu_tlb_fill " Richard Henderson
2021-09-18 18:45 ` [PATCH v2 31/41] target/nios2: Make nios2_cpu_tlb_fill " Richard Henderson
2021-09-18 18:45 ` [PATCH v2 32/41] linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE Richard Henderson
2021-09-18 18:45 ` [PATCH v2 33/41] target/openrisc: Make openrisc_cpu_tlb_fill sysemu only Richard Henderson
2021-09-18 18:45 ` [PATCH v2 34/41] target/ppc: Implement ppc_cpu_record_sigsegv Richard Henderson
2021-09-19 18:37   ` Philippe Mathieu-Daudé
2021-09-18 18:45 ` [PATCH v2 35/41] target/riscv: Make riscv_cpu_tlb_fill sysemu only Richard Henderson
2021-09-18 18:45 ` [PATCH v2 36/41] target/s390x: Use probe_access_flags in s390_probe_access Richard Henderson
2021-09-18 18:45 ` [PATCH v2 37/41] target/s390x: Implement s390_cpu_record_sigsegv Richard Henderson
2021-09-19 18:39   ` Philippe Mathieu-Daudé
2021-09-18 18:45 ` [PATCH v2 38/41] target/sh4: Make sh4_cpu_tlb_fill sysemu only Richard Henderson
2021-09-18 18:45 ` [PATCH v2 39/41] target/sparc: Make sparc_cpu_tlb_fill " Richard Henderson
2021-09-18 18:45 ` [PATCH v2 40/41] target/xtensa: Make xtensa_cpu_tlb_fill " Richard Henderson
2021-09-18 18:45 ` [PATCH v2 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu Richard Henderson
2021-09-19 18:40   ` Philippe Mathieu-Daudé
2021-09-19 10:38 ` [PATCH v2 00/41] linux-user: Streamline handling of SIGSEGV Philippe Mathieu-Daudé

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.