qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: laurent@vivier.eu
Subject: [PATCH v2 20/41] linux-user: Add raise_sigsegv
Date: Sat, 18 Sep 2021 11:45:06 -0700	[thread overview]
Message-ID: <20210918184527.408540-21-richard.henderson@linaro.org> (raw)
In-Reply-To: <20210918184527.408540-1-richard.henderson@linaro.org>

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



  parent reply	other threads:[~2021-09-18 18:57 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Richard Henderson [this message]
2021-09-19 18:26   ` [PATCH v2 20/41] linux-user: Add raise_sigsegv 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é

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210918184527.408540-21-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).