All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] linux-user: Move signal trampolines to new page
@ 2021-06-16  1:11 Richard Henderson
  2021-06-16  1:11 ` [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
                   ` (21 more replies)
  0 siblings, 22 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

It is my guess that the majority of the flakiness with the
linux-user signals.c test is due to a race condition between
translation and page writes.  I vaguely recall a bug report
about this, but I cannot find it now.

Since the vast majority of "self-modifying code" is due to
signal delivery, work around this by allocating a new page,
into which we write the signal handlers.

A better workaround would be to implement the vdso that is
required by many guests.  However, that is a much larger
problem, and some guests do not define a vdso in upstream
linux.  This serves as a decent fallback.

Neither bit of work, I will note, solves the posited race
condition described above.


r~


Richard Henderson (21):
  linux-user: Add infrastructure for a signal trampoline page
  linux-user/aarch64: Implement setup_sigtramp
  linux-user/arm: Force v2 frames for fdpic
  linux-user/arm: Implement setup_sigtramp
  linux-user/alpha: Implement setup_sigtramp
  linux-user/cris: Implement setup_sigtramp
  linux-user/hexagon: Implement setup_sigtramp
  linux-user/hppa: Document non-use of setup_sigtramp
  linux-user/i386: Implement setup_sigtramp
  linux-user/m68k: Implement setup_sigtramp
  linux-user/microblaze: Implement setup_sigtramp
  linux-user/mips: Implement setup_sigtramp
  linux-user/nios2: Document non-use of setup_sigtramp
  linux-user/openrisc: Implement setup_sigtramp
  linux-user/ppc: Implement setup_sigtramp
  linux-user/riscv: Implement setup_sigtramp
  linux-user/s390x: Implement setup_sigtramp
  linux-user/sh4: Implement setup_sigtramp
  linux-user/sparc: Implement setup_sigtramp
  linux-user/xtensa: Implement setup_sigtramp
  linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE

 linux-user/aarch64/target_signal.h    |   2 +
 linux-user/alpha/target_signal.h      |   1 +
 linux-user/arm/target_signal.h        |   2 +
 linux-user/cris/target_signal.h       |   2 +
 linux-user/hexagon/target_signal.h    |   2 +
 linux-user/hppa/target_signal.h       |  14 ++
 linux-user/i386/target_signal.h       |   2 +
 linux-user/m68k/target_signal.h       |   2 +
 linux-user/microblaze/target_signal.h |   2 +
 linux-user/mips/target_signal.h       |   1 +
 linux-user/mips64/target_signal.h     |   2 +
 linux-user/nios2/target_signal.h      |   3 +
 linux-user/openrisc/target_signal.h   |   2 +
 linux-user/ppc/target_signal.h        |   2 +
 linux-user/qemu.h                     |   7 +
 linux-user/riscv/target_signal.h      |   2 +
 linux-user/s390x/target_signal.h      |   2 +
 linux-user/sh4/target_signal.h        |   2 +
 linux-user/sparc/target_signal.h      |   4 +
 linux-user/x86_64/target_signal.h     |   3 +
 linux-user/xtensa/target_signal.h     |   2 +
 linux-user/aarch64/signal.c           |  28 ++--
 linux-user/alpha/signal.c             |  34 +++--
 linux-user/arm/signal.c               | 190 +++++++++++++++-----------
 linux-user/cris/signal.c              |  29 ++--
 linux-user/elfload.c                  |  13 ++
 linux-user/hexagon/signal.c           |  19 ++-
 linux-user/i386/signal.c              |  42 +++---
 linux-user/m68k/signal.c              |  47 +++----
 linux-user/microblaze/signal.c        |  24 +++-
 linux-user/mips/signal.c              |  39 ++++--
 linux-user/openrisc/signal.c          |  24 ++--
 linux-user/ppc/signal.c               |  34 ++---
 linux-user/riscv/signal.c             |  22 +--
 linux-user/s390x/signal.c             |  24 ++--
 linux-user/sh4/signal.c               |  40 +++---
 linux-user/signal.c                   |   3 +
 linux-user/sparc/signal.c             |  32 +++--
 linux-user/xtensa/signal.c            |  50 ++++---
 39 files changed, 488 insertions(+), 267 deletions(-)

-- 
2.25.1



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

* [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 13:36   ` Max Filippov
  2021-06-16  1:11 ` [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Allocate a page to hold the signal trampoline(s).
Invoke a guest-specific hook to fill in the contents
of the page before marking it read-execute again.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/qemu.h    |  7 +++++++
 linux-user/elfload.c | 17 +++++++++++++++++
 linux-user/signal.c  |  3 +++
 3 files changed, 27 insertions(+)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 3b0b6b75fe..9e5e2aa499 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -437,6 +437,13 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
 abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
                         abi_ulong unew_ctx, abi_long ctx_size);
+
+/* Fallback addresses into sigtramp page. */
+extern abi_ulong default_sigreturn;
+extern abi_ulong default_rt_sigreturn;
+
+void setup_sigtramp(abi_ulong tramp_page);
+
 /**
  * block_signals: block all signals while handling this guest syscall
  *
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 17ab06f612..7bc67ac9cb 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -14,6 +14,7 @@
 #include "qemu/units.h"
 #include "qemu/selfmap.h"
 #include "qapi/error.h"
+#include "target_signal.h"
 
 #ifdef _ARCH_PPC64
 #undef ARCH_DLINFO
@@ -25,6 +26,10 @@
 #undef ELF_ARCH
 #endif
 
+#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
+#endif
+
 #define ELF_OSABI   ELFOSABI_SYSV
 
 /* from personality.h */
@@ -3232,6 +3237,18 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
 #endif
     }
 
+    /*
+     * TODO: load a vdso, which would also contain the signal trampolines.
+     * Otherwise, allocate a private page to hold them.
+     */
+    if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) {
+        abi_ulong tramp_page = target_mmap(0, TARGET_PAGE_SIZE,
+                                           PROT_READ | PROT_WRITE,
+                                           MAP_PRIVATE | MAP_ANON, -1, 0);
+        setup_sigtramp(tramp_page);
+        target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC);
+    }
+
     bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
                                 info, (elf_interpreter ? &interp_info : NULL));
     info->start_stack = bprm->p;
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9016896dcd..2f19cc0bf6 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -30,6 +30,9 @@ static struct target_sigaction sigact_table[TARGET_NSIG];
 static void host_signal_handler(int host_signum, siginfo_t *info,
                                 void *puc);
 
+/* Fallback addresses into sigtramp page. */
+abi_ulong default_sigreturn;
+abi_ulong default_rt_sigreturn;
 
 /*
  * System includes define _NSIG as SIGRTMAX + 1,
-- 
2.25.1



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

* [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
  2021-06-16  1:11 ` [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 17:00   ` Philippe Mathieu-Daudé
  2021-06-16  1:11 ` [PATCH 03/21] linux-user/arm: Force v2 frames for fdpic Richard Henderson
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-arm, alex.bennee, laurent

Create and record the rt signal trampoline.
Use it when the guest does not use SA_RESTORER.

Cc: qemu-arm@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/aarch64/target_signal.h |  2 ++
 linux-user/aarch64/signal.c        | 28 ++++++++++++++++++----------
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/linux-user/aarch64/target_signal.h b/linux-user/aarch64/target_signal.h
index 18013e1b23..7580d99403 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -25,4 +25,6 @@ typedef struct target_sigaltstack {
 #define TARGET_SEGV_MTESERR  9  /* Synchronous ARM MTE exception */
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* AARCH64_TARGET_SIGNAL_H */
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 662bcd1c4e..65b84eb04e 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -108,7 +108,6 @@ struct target_rt_sigframe {
 struct target_rt_frame_record {
     uint64_t fp;
     uint64_t lr;
-    uint32_t tramp[2];
 };
 
 static void target_setup_general_frame(struct target_rt_sigframe *sf,
@@ -495,15 +494,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         return_addr = ka->sa_restorer;
     } else {
-        /*
-         * mov x8,#__NR_rt_sigreturn; svc #0
-         * Since these are instructions they need to be put as little-endian
-         * regardless of target default or current CPU endianness.
-         */
-        __put_user_e(0xd2801168, &fr->tramp[0], le);
-        __put_user_e(0xd4000001, &fr->tramp[1], le);
-        return_addr = frame_addr + fr_ofs
-            + offsetof(struct target_rt_frame_record, tramp);
+        return_addr = default_rt_sigreturn;
     }
     env->xregs[0] = usig;
     env->xregs[29] = frame_addr + fr_ofs;
@@ -576,3 +567,20 @@ long do_sigreturn(CPUARMState *env)
 {
     return do_rt_sigreturn(env);
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
+    assert(tramp != NULL);
+
+    /*
+     * mov x8,#__NR_rt_sigreturn; svc #0
+     * Since these are instructions they need to be put as little-endian
+     * regardless of target default or current CPU endianness.
+     */
+    __put_user_e(0xd2801168, &tramp[0], le);
+    __put_user_e(0xd4000001, &tramp[1], le);
+
+    default_rt_sigreturn = sigtramp_page;
+    unlock_user(tramp, sigtramp_page, 8);
+}
-- 
2.25.1



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

* [PATCH 03/21] linux-user/arm: Force v2 frames for fdpic
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
  2021-06-16  1:11 ` [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
  2021-06-16  1:11 ` [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 17:01   ` Philippe Mathieu-Daudé
  2021-06-16  1:11 ` [PATCH 04/21] linux-user/arm: Implement setup_sigtramp Richard Henderson
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-arm, alex.bennee, laurent

The value of get_os_release may be controlled by a command
line option.  Since fdpic was added in v4.14, and v2 frame
were added in v2.6.12, this makes no change under normal conditions.

Split out a helper function to perform the test.

Cc: qemu-arm@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/arm/signal.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index 32b68ee302..2d30345fc2 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -165,6 +165,18 @@ static inline int valid_user_regs(CPUARMState *regs)
     return 1;
 }
 
+static bool v2_frame(void)
+{
+    /*
+     * We do not create fdpic trampolines for v1 frames.
+     * Thus we force v2 frames, regardless of what uname says.
+     * Support for fdpic dates from Linux 4.14, so this is not
+     * really a behaviour change.
+     */
+    int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
+    return is_fdpic || get_osversion() >= 0x020612;
+}
+
 static void
 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
                  CPUARMState *env, abi_ulong mask)
@@ -422,7 +434,7 @@ sigsegv:
 void setup_frame(int usig, struct target_sigaction *ka,
                  target_sigset_t *set, CPUARMState *regs)
 {
-    if (get_osversion() >= 0x020612) {
+    if (v2_frame()) {
         setup_frame_v2(usig, ka, set, regs);
     } else {
         setup_frame_v1(usig, ka, set, regs);
@@ -516,7 +528,7 @@ void setup_rt_frame(int usig, struct target_sigaction *ka,
                     target_siginfo_t *info,
                     target_sigset_t *set, CPUARMState *env)
 {
-    if (get_osversion() >= 0x020612) {
+    if (v2_frame()) {
         setup_rt_frame_v2(usig, ka, info, set, env);
     } else {
         setup_rt_frame_v1(usig, ka, info, set, env);
@@ -734,7 +746,7 @@ badframe:
 
 long do_sigreturn(CPUARMState *env)
 {
-    if (get_osversion() >= 0x020612) {
+    if (v2_frame()) {
         return do_sigreturn_v2(env);
     } else {
         return do_sigreturn_v1(env);
@@ -823,7 +835,7 @@ badframe:
 
 long do_rt_sigreturn(CPUARMState *env)
 {
-    if (get_osversion() >= 0x020612) {
+    if (v2_frame()) {
         return do_rt_sigreturn_v2(env);
     } else {
         return do_rt_sigreturn_v1(env);
-- 
2.25.1



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

* [PATCH 04/21] linux-user/arm: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (2 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 03/21] linux-user/arm: Force v2 frames for fdpic Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 13:46   ` Alex Bennée
  2021-06-16  1:11 ` [PATCH 05/21] linux-user/alpha: " Richard Henderson
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-arm, alex.bennee, laurent

ARM is more complicated than the others, in that we also
have trampolines for using SA_RESTORER with FDPIC, and
we need to create trampolines for both ARM and Thumb modes.

Cc: qemu-arm@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/arm/target_signal.h |   2 +
 linux-user/arm/signal.c        | 170 +++++++++++++++++++--------------
 2 files changed, 100 insertions(+), 72 deletions(-)

diff --git a/linux-user/arm/target_signal.h b/linux-user/arm/target_signal.h
index 0998dd6dfa..1e7fb0cecb 100644
--- a/linux-user/arm/target_signal.h
+++ b/linux-user/arm/target_signal.h
@@ -22,4 +22,6 @@ typedef struct target_sigaltstack {
 #include "../generic/signal.h"
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* ARM_TARGET_SIGNAL_H */
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index 2d30345fc2..b7c3c80c75 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -101,13 +101,12 @@ struct sigframe_v1
 {
     struct target_sigcontext sc;
     abi_ulong extramask[TARGET_NSIG_WORDS-1];
-    abi_ulong retcode[4];
 };
 
 struct sigframe_v2
 {
     struct target_ucontext_v2 uc;
-    abi_ulong retcode[4];
+    abi_ulong fdpic_ret;
 };
 
 struct rt_sigframe_v1
@@ -116,49 +115,20 @@ struct rt_sigframe_v1
     abi_ulong puc;
     struct target_siginfo info;
     struct target_ucontext_v1 uc;
-    abi_ulong retcode[4];
 };
 
 struct rt_sigframe_v2
 {
     struct target_siginfo info;
     struct target_ucontext_v2 uc;
-    abi_ulong retcode[4];
+    abi_ulong fdpic_ret;
 };
 
 /*
- * For ARM syscalls, we encode the syscall number into the instruction.
+ * Stubs needed to make sure the FD register (r9) contains the right value.
+ * There are 4 of them, each consuming 8 bytes.
  */
-#define SWI_SYS_SIGRETURN       (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
-#define SWI_SYS_RT_SIGRETURN    (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
-
-/*
- * For Thumb syscalls, we pass the syscall number via r7.  We therefore
- * need two 16-bit instructions.
- */
-#define SWI_THUMB_SIGRETURN     (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
-#define SWI_THUMB_RT_SIGRETURN  (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
-
-static const abi_ulong retcodes[4] = {
-        SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
-        SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
-};
-
-/*
- * Stub needed to make sure the FD register (r9) contains the right
- * value.
- */
-static const unsigned long sigreturn_fdpic_codes[3] = {
-    0xe59fc004, /* ldr r12, [pc, #4] to read function descriptor */
-    0xe59c9004, /* ldr r9, [r12, #4] to setup GOT */
-    0xe59cf000  /* ldr pc, [r12] to jump into restorer */
-};
-
-static const unsigned long sigreturn_fdpic_thumb_codes[3] = {
-    0xc008f8df, /* ldr r12, [pc, #8] to read function descriptor */
-    0x9004f8dc, /* ldr r9, [r12, #4] to setup GOT */
-    0xf000f8dc  /* ldr pc, [r12] to jump into restorer */
-};
+static abi_ulong sigreturn_fdpic_tramp;
 
 static inline int valid_user_regs(CPUARMState *regs)
 {
@@ -219,13 +189,12 @@ get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
 
 static int
 setup_return(CPUARMState *env, struct target_sigaction *ka,
-             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
+             abi_ulong frame_addr, int usig)
 {
     abi_ulong handler = 0;
     abi_ulong handler_fdpic_GOT = 0;
     abi_ulong retcode;
-
-    int thumb;
+    int thumb, retcode_idx;
     int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
 
     if (is_fdpic) {
@@ -243,6 +212,7 @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
     }
 
     thumb = handler & 1;
+    retcode_idx = thumb + (ka->sa_flags & TARGET_SA_SIGINFO ? 2 : 0);
 
     uint32_t cpsr = cpsr_read(env);
 
@@ -260,37 +230,24 @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
 
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         if (is_fdpic) {
-            /* For FDPIC we ensure that the restorer is called with a
-             * correct r9 value.  For that we need to write code on
-             * the stack that sets r9 and jumps back to restorer
-             * value.
+            /*
+             * For FDPIC we ensure that the restorer is called with a
+             * correct r9 value.  For that we use a special trampoline
+             * that reads the function descriptor from the frame,
+             * sets r9 and jumps back to restorer value.
              */
-            if (thumb) {
-                __put_user(sigreturn_fdpic_thumb_codes[0], rc);
-                __put_user(sigreturn_fdpic_thumb_codes[1], rc + 1);
-                __put_user(sigreturn_fdpic_thumb_codes[2], rc + 2);
-                __put_user((abi_ulong)ka->sa_restorer, rc + 3);
-            } else {
-                __put_user(sigreturn_fdpic_codes[0], rc);
-                __put_user(sigreturn_fdpic_codes[1], rc + 1);
-                __put_user(sigreturn_fdpic_codes[2], rc + 2);
-                __put_user((abi_ulong)ka->sa_restorer, rc + 3);
-            }
-
-            retcode = rc_addr + thumb;
+            abi_ulong fd_ofs = (retcode_idx & 2
+                                ? offsetof(struct rt_sigframe_v2, fdpic_ret)
+                                : offsetof(struct sigframe_v2, fdpic_ret));
+            put_user_ual(ka->sa_restorer, frame_addr + fd_ofs);
+            /* Each trampoline variant consumes 8-byte slot. */
+            retcode = sigreturn_fdpic_tramp + retcode_idx * 8 + thumb;
         } else {
             retcode = ka->sa_restorer;
         }
     } else {
-        unsigned int idx = thumb;
-
-        if (ka->sa_flags & TARGET_SA_SIGINFO) {
-            idx += 2;
-        }
-
-        __put_user(retcodes[idx], rc);
-
-        retcode = rc_addr + thumb;
+        /* Each trampoline variant consumes one 4-byte slot. */
+        retcode = default_sigreturn + retcode_idx * 4 + thumb;
     }
 
     env->regs[0] = usig;
@@ -394,8 +351,7 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
         __put_user(set->sig[i], &frame->extramask[i - 1]);
     }
 
-    if (setup_return(regs, ka, frame->retcode, frame_addr, usig,
-                     frame_addr + offsetof(struct sigframe_v1, retcode))) {
+    if (setup_return(regs, ka, frame_addr, usig)) {
         goto sigsegv;
     }
 
@@ -419,8 +375,7 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
 
     setup_sigframe_v2(&frame->uc, set, regs);
 
-    if (setup_return(regs, ka, frame->retcode, frame_addr, usig,
-                     frame_addr + offsetof(struct sigframe_v2, retcode))) {
+    if (setup_return(regs, ka, frame_addr, usig)) {
         goto sigsegv;
     }
 
@@ -475,8 +430,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
     }
 
-    if (setup_return(env, ka, frame->retcode, frame_addr, usig,
-                     frame_addr + offsetof(struct rt_sigframe_v1, retcode))) {
+    if (setup_return(env, ka, frame_addr, usig)) {
         goto sigsegv;
     }
 
@@ -509,8 +463,7 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
 
     setup_sigframe_v2(&frame->uc, set, env);
 
-    if (setup_return(env, ka, frame->retcode, frame_addr, usig,
-                     frame_addr + offsetof(struct rt_sigframe_v2, retcode))) {
+    if (setup_return(env, ka, frame_addr, usig)) {
         goto sigsegv;
     }
 
@@ -841,3 +794,76 @@ long do_rt_sigreturn(CPUARMState *env)
         return do_rt_sigreturn_v1(env);
     }
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    enum {
+        /* For ARM, we encode the syscall number into the instruction. */
+        SWI_SYS_SIGRETURN =
+            0xef000000 | (TARGET_NR_sigreturn + ARM_SYSCALL_BASE),
+        SWI_SYS_RT_SIGRETURN =
+            0xef000000 | (TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE),
+
+        /*
+         * For Thumb , we pass the syscall number via r7.
+         * We therefore need two 16-bit instructions.
+         */
+        SWI_THUMB_SIGRETURN =
+            0xdf00 << 16 | 0x2700 | TARGET_NR_sigreturn,
+        SWI_THUMB_RT_SIGRETURN =
+            0xdf00 << 16 | 0x2700 | TARGET_NR_rt_sigreturn,
+
+        SIGFRAME_FDPIC_OFS = offsetof(struct sigframe_v2, fdpic_ret),
+        RT_SIGFRAME_FDPIC_OFS = offsetof(struct rt_sigframe_v2, fdpic_ret),
+    };
+
+    uint32_t total_size = 4 * 4 + 2 * 8;
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, total_size, 0);
+    uint32_t i = 0;
+
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    __put_user(SWI_SYS_SIGRETURN, &tramp[i++]);
+    __put_user(SWI_THUMB_SIGRETURN, &tramp[i++]);
+    __put_user(SWI_SYS_RT_SIGRETURN, &tramp[i++]);
+    __put_user(SWI_THUMB_RT_SIGRETURN, &tramp[i++]);
+
+    /*
+     * FDPIC require trampolines to call sa_restorer.
+     *
+     * ARM versions use:
+     *    ldr   r9, [sp, #ofs]
+     *    ldmia r9, {r9, pc}
+     *
+     * Thumb versions use:
+     *    ldrd  r9, r10, [sp, #ofs]
+     *    bx    r10
+     *    nop
+     */
+    sigreturn_fdpic_tramp = sigtramp_page + i * 4;
+
+    /* ARM sigframe */
+    _Static_assert(SIGFRAME_FDPIC_OFS <= 0xfff);
+    __put_user(0xe59d9000 | SIGFRAME_FDPIC_OFS, &tramp[i++]);
+    __put_user(0xe8998200, &tramp[i++]);
+
+    /* Thumb sigframe */
+    _Static_assert(SIGFRAME_FDPIC_OFS <= 0xff << 2);
+    _Static_assert((SIGFRAME_FDPIC_OFS & 3) == 0);
+    __put_user(0x9a00e9dd | (SIGFRAME_FDPIC_OFS << 14), &tramp[i++]);
+    __put_user(0x46c04750, &tramp[i++]);
+
+    /* ARM rt_sigframe */
+    _Static_assert(RT_SIGFRAME_FDPIC_OFS <= 0xfff);
+    __put_user(0xe59d9000 | RT_SIGFRAME_FDPIC_OFS, &tramp[i++]);
+    __put_user(0xe8998200, &tramp[i++]);
+
+    /* Thumb rt_sigframe */
+    _Static_assert(RT_SIGFRAME_FDPIC_OFS <= 0xff << 2);
+    _Static_assert((RT_SIGFRAME_FDPIC_OFS & 3) == 0);
+    __put_user(0x9a00e9dd | (RT_SIGFRAME_FDPIC_OFS << 14), &tramp[i++]);
+    __put_user(0x46c04750, &tramp[i++]);
+
+    unlock_user(tramp, sigtramp_page, total_size);
+}
-- 
2.25.1



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

* [PATCH 05/21] linux-user/alpha: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (3 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 04/21] linux-user/arm: Implement setup_sigtramp Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 16:56   ` Philippe Mathieu-Daudé
  2021-06-16  1:11 ` [PATCH 06/21] linux-user/cris: " Richard Henderson
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Create and record the two signal trampolines.
Use them when the guest does not use ka_restorer.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/alpha/target_signal.h |  1 +
 linux-user/alpha/signal.c        | 34 +++++++++++++++++++-------------
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/linux-user/alpha/target_signal.h b/linux-user/alpha/target_signal.h
index 250642913e..0b6a39de65 100644
--- a/linux-user/alpha/target_signal.h
+++ b/linux-user/alpha/target_signal.h
@@ -93,6 +93,7 @@ typedef struct target_sigaltstack {
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
 #define TARGET_ARCH_HAS_KA_RESTORER
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
 
 /* bit-flags */
 #define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */
diff --git a/linux-user/alpha/signal.c b/linux-user/alpha/signal.c
index 1129ffeea1..e15f5438c3 100644
--- a/linux-user/alpha/signal.c
+++ b/linux-user/alpha/signal.c
@@ -54,13 +54,11 @@ struct target_ucontext {
 
 struct target_sigframe {
     struct target_sigcontext sc;
-    unsigned int retcode[3];
 };
 
 struct target_rt_sigframe {
     target_siginfo_t info;
     struct target_ucontext uc;
-    unsigned int retcode[3];
 };
 
 #define INSN_MOV_R30_R16        0x47fe0410
@@ -141,12 +139,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     if (ka->ka_restorer) {
         r26 = ka->ka_restorer;
     } else {
-        __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
-        __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
-                   &frame->retcode[1]);
-        __put_user(INSN_CALLSYS, &frame->retcode[2]);
-        /* imb() */
-        r26 = frame_addr + offsetof(struct target_sigframe, retcode);
+        r26 = default_sigreturn;
     }
 
     unlock_user_struct(frame, frame_addr, 1);
@@ -195,12 +188,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     if (ka->ka_restorer) {
         r26 = ka->ka_restorer;
     } else {
-        __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
-        __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
-                   &frame->retcode[1]);
-        __put_user(INSN_CALLSYS, &frame->retcode[2]);
-        /* imb(); */
-        r26 = frame_addr + offsetof(struct target_rt_sigframe, retcode);
+        r26 = default_rt_sigreturn;
     }
 
     if (err) {
@@ -268,3 +256,21 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6 * 4, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    __put_user(INSN_MOV_R30_R16, &tramp[0]);
+    __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn, &tramp[1]);
+    __put_user(INSN_CALLSYS, &tramp[2]);
+
+    default_rt_sigreturn = sigtramp_page + 3 * 4;
+    __put_user(INSN_MOV_R30_R16, &tramp[3]);
+    __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn, &tramp[4]);
+    __put_user(INSN_CALLSYS, &tramp[5]);
+
+    unlock_user(tramp, sigtramp_page, 6 * 4);
+}
-- 
2.25.1



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

* [PATCH 06/21] linux-user/cris: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (4 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 05/21] linux-user/alpha: " Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 16:37   ` Philippe Mathieu-Daudé
  2021-06-16  1:11 ` [PATCH 07/21] linux-user/hexagon: " Richard Henderson
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E . Iglesias, alex.bennee, laurent

Split out setup_sigreturn so that we can continue to
initialize the words on the stack, as documented.
However, use the off-stack trampoline.

Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/cris/target_signal.h |  2 ++
 linux-user/cris/signal.c        | 29 +++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/linux-user/cris/target_signal.h b/linux-user/cris/target_signal.h
index 495a142896..83a5155507 100644
--- a/linux-user/cris/target_signal.h
+++ b/linux-user/cris/target_signal.h
@@ -22,4 +22,6 @@ typedef struct target_sigaltstack {
 #include "../generic/signal.h"
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* CRIS_TARGET_SIGNAL_H */
diff --git a/linux-user/cris/signal.c b/linux-user/cris/signal.c
index 1e02194377..51d1ee877f 100644
--- a/linux-user/cris/signal.c
+++ b/linux-user/cris/signal.c
@@ -96,6 +96,14 @@ static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
     return sp - framesize;
 }
 
+static void setup_sigreturn(uint16_t *retcode)
+{
+    /* This is movu.w __NR_sigreturn, r9; break 13; */
+    __put_user(0x9c5f, retcode + 0);
+    __put_user(TARGET_NR_sigreturn, retcode + 1);
+    __put_user(0xe93d, retcode + 2);
+}
+
 void setup_frame(int sig, struct target_sigaction *ka,
                  target_sigset_t *set, CPUCRISState *env)
 {
@@ -111,14 +119,8 @@ void setup_frame(int sig, struct target_sigaction *ka,
     /*
      * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
      * use this trampoline anymore but it sets it up for GDB.
-     * In QEMU, using the trampoline simplifies things a bit so we use it.
-     *
-     * This is movu.w __NR_sigreturn, r9; break 13;
      */
-    __put_user(0x9c5f, frame->retcode+0);
-    __put_user(TARGET_NR_sigreturn,
-               frame->retcode + 1);
-    __put_user(0xe93d, frame->retcode + 2);
+    setup_sigreturn(frame->retcode);
 
     /* Save the mask.  */
     __put_user(set->sig[0], &frame->sc.oldmask);
@@ -134,7 +136,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     env->regs[10] = sig;
     env->pc = (unsigned long) ka->_sa_handler;
     /* Link SRP so the guest returns through the trampoline.  */
-    env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
+    env->pregs[PR_SRP] = default_sigreturn;
 
     unlock_user_struct(frame, frame_addr, 1);
     return;
@@ -186,3 +188,14 @@ long do_rt_sigreturn(CPUCRISState *env)
     qemu_log_mask(LOG_UNIMP, "do_rt_sigreturn: not implemented\n");
     return -TARGET_ENOSYS;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 2, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    setup_sigreturn(tramp);
+
+    unlock_user(tramp, sigtramp_page, 4 * 2);
+}
-- 
2.25.1



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

* [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (5 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 06/21] linux-user/cris: " Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16  8:07   ` Taylor Simpson
  2021-06-16  1:11 ` [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Taylor Simpson, alex.bennee, laurent

Continue to initialize the words on the stack, as documented.
However, use the off-stack trampoline.

Cc: Taylor Simpson <tsimpson@quicinc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/hexagon/target_signal.h |  2 ++
 linux-user/hexagon/signal.c        | 19 +++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/linux-user/hexagon/target_signal.h b/linux-user/hexagon/target_signal.h
index 345cf1cbb8..9e0223d322 100644
--- a/linux-user/hexagon/target_signal.h
+++ b/linux-user/hexagon/target_signal.h
@@ -31,4 +31,6 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c
index 85eab5e943..bd0f9b1c85 100644
--- a/linux-user/hexagon/signal.c
+++ b/linux-user/hexagon/signal.c
@@ -161,6 +161,11 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     setup_ucontext(&frame->uc, env, set);
     tswap_siginfo(&frame->info, info);
+    /*
+     * The on-stack signal trampoline is no longer executed;
+     * however, the libgcc signal frame unwinding code checks
+     * for the presence of these two numeric magic values.
+     */
     install_sigtramp(frame->tramp);
 
     env->gpr[HEX_REG_PC] = ka->_sa_handler;
@@ -170,8 +175,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
         frame_addr + offsetof(struct target_rt_sigframe, info);
     env->gpr[HEX_REG_R02] =
         frame_addr + offsetof(struct target_rt_sigframe, uc);
-    env->gpr[HEX_REG_LR] =
-        frame_addr + offsetof(struct target_rt_sigframe, tramp);
+    env->gpr[HEX_REG_LR] = default_rt_sigreturn;
 
     return;
 
@@ -270,3 +274,14 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return 0;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 2, 0);
+    assert(tramp != NULL);
+
+    default_rt_sigreturn = sigtramp_page;
+    install_sigtramp(tramp);
+
+    unlock_user(tramp, sigtramp_page, 4 * 2);
+}
-- 
2.25.1



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

* [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (6 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 07/21] linux-user/hexagon: " Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 10:46   ` Philippe Mathieu-Daudé
  2021-06-16 21:16   ` Alex Bennée
  2021-06-16  1:11 ` [PATCH 09/21] linux-user/i386: Implement setup_sigtramp Richard Henderson
                   ` (13 subsequent siblings)
  21 siblings, 2 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

We cannot use a raw sigtramp page for hppa,
but must wait for full vdso support.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/hppa/target_signal.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/linux-user/hppa/target_signal.h b/linux-user/hppa/target_signal.h
index 7f525362e9..d558119ee7 100644
--- a/linux-user/hppa/target_signal.h
+++ b/linux-user/hppa/target_signal.h
@@ -71,4 +71,18 @@ typedef struct target_sigaltstack {
 /* mask for all SS_xxx flags */
 #define TARGET_SS_FLAG_BITS  TARGET_SS_AUTODISARM
 
+/*
+ * We cannot use a bare sigtramp page for hppa-linux.
+ *
+ * Unlike other guests where we use the instructions at PC to validate
+ * an offset from SP, the hppa libgcc signal frame fallback unwinding uses
+ * the PC address itself to find the frame.  This is due to the fact that
+ * the hppa grows the stack upward, and the frame is of unknown size.
+ *
+ * TODO: We should be able to use a VDSO to address this, by providing
+ * proper unwind info for the sigtramp code, at which point the fallback
+ * unwinder will not be used.
+ */
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
+
 #endif /* HPPA_TARGET_SIGNAL_H */
-- 
2.25.1



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

* [PATCH 09/21] linux-user/i386: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (7 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16  1:11 ` [PATCH 10/21] linux-user/m68k: " Richard Henderson
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Create and record the two signal trampolines.
Use them when the guest does not use SA_RESTORER.
Note that x86_64 does not use this code.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/i386/target_signal.h   |  2 ++
 linux-user/x86_64/target_signal.h |  3 +++
 linux-user/i386/signal.c          | 42 ++++++++++++++++++-------------
 3 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/linux-user/i386/target_signal.h b/linux-user/i386/target_signal.h
index 50361af874..64d09f2e75 100644
--- a/linux-user/i386/target_signal.h
+++ b/linux-user/i386/target_signal.h
@@ -22,4 +22,6 @@ typedef struct target_sigaltstack {
 #include "../generic/signal.h"
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* I386_TARGET_SIGNAL_H */
diff --git a/linux-user/x86_64/target_signal.h b/linux-user/x86_64/target_signal.h
index 4ea74f20dd..4673c5a886 100644
--- a/linux-user/x86_64/target_signal.h
+++ b/linux-user/x86_64/target_signal.h
@@ -21,4 +21,7 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+/* For x86_64, use of SA_RESTORER is mandatory. */
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
+
 #endif /* X86_64_TARGET_SIGNAL_H */
diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
index 8701774e37..a83ecba54f 100644
--- a/linux-user/i386/signal.c
+++ b/linux-user/i386/signal.c
@@ -337,16 +337,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         __put_user(ka->sa_restorer, &frame->pretcode);
     } else {
-        uint16_t val16;
-        abi_ulong retcode_addr;
-        retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
-        __put_user(retcode_addr, &frame->pretcode);
-        /* This is popl %eax ; movl $,%eax ; int $0x80 */
-        val16 = 0xb858;
-        __put_user(val16, (uint16_t *)(frame->retcode+0));
-        __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
-        val16 = 0x80cd;
-        __put_user(val16, (uint16_t *)(frame->retcode+6));
+        __put_user(default_sigreturn, &frame->pretcode);
     }
 
     /* Set up registers for signal handler */
@@ -415,14 +406,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         __put_user(ka->sa_restorer, &frame->pretcode);
     } else {
-        uint16_t val16;
-        addr = frame_addr + offsetof(struct rt_sigframe, retcode);
-        __put_user(addr, &frame->pretcode);
-        /* This is movl $,%eax ; int $0x80 */
-        __put_user(0xb8, (char *)(frame->retcode+0));
-        __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
-        val16 = 0x80cd;
-        __put_user(val16, (uint16_t *)(frame->retcode+5));
+        __put_user(default_rt_sigreturn, &frame->pretcode);
     }
 #else
     /* XXX: Would be slightly better to return -EFAULT here if test fails
@@ -591,3 +575,25 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+#ifndef TARGET_X86_64
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    /* This is popl %eax ; movl $,%eax ; int $0x80 */
+    __put_user(0xb858, (uint16_t *)(tramp + 0));
+    __put_user(TARGET_NR_sigreturn, (int *)(tramp + 2));
+    __put_user(0x80cd, (uint16_t *)(tramp + 6));
+
+    default_rt_sigreturn = sigtramp_page + 8;
+    /* This is movl $,%eax ; int $0x80 */
+    __put_user(0xb8, (char *)(tramp + 8));
+    __put_user(TARGET_NR_rt_sigreturn, (int *)(tramp + 9));
+    __put_user(0x80cd, (uint16_t *)(tramp + 13));
+
+    unlock_user(tramp, sigtramp_page, 2 * 8);
+}
+#endif
-- 
2.25.1



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

* [PATCH 10/21] linux-user/m68k: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (8 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 09/21] linux-user/i386: Implement setup_sigtramp Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 16:42   ` Philippe Mathieu-Daudé
  2021-06-16  1:11 ` [PATCH 11/21] linux-user/microblaze: " Richard Henderson
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

Create and record the two signal trampolines.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/m68k/target_signal.h |  2 ++
 linux-user/m68k/signal.c        | 47 +++++++++++++++------------------
 2 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/linux-user/m68k/target_signal.h b/linux-user/m68k/target_signal.h
index d096544ef8..94157bf1f4 100644
--- a/linux-user/m68k/target_signal.h
+++ b/linux-user/m68k/target_signal.h
@@ -22,4 +22,6 @@ typedef struct target_sigaltstack {
 #include "../generic/signal.h"
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* M68K_TARGET_SIGNAL_H */
diff --git a/linux-user/m68k/signal.c b/linux-user/m68k/signal.c
index d06230655e..b4fade1ed6 100644
--- a/linux-user/m68k/signal.c
+++ b/linux-user/m68k/signal.c
@@ -38,7 +38,6 @@ struct target_sigframe
     int sig;
     int code;
     abi_ulong psc;
-    char retcode[8];
     abi_ulong extramask[TARGET_NSIG_WORDS-1];
     struct target_sigcontext sc;
 };
@@ -75,7 +74,6 @@ struct target_rt_sigframe
     int sig;
     abi_ulong pinfo;
     abi_ulong puc;
-    char retcode[8];
     struct target_siginfo info;
     struct target_ucontext uc;
 };
@@ -129,7 +127,6 @@ void setup_frame(int sig, struct target_sigaction *ka,
 {
     struct target_sigframe *frame;
     abi_ulong frame_addr;
-    abi_ulong retcode_addr;
     abi_ulong sc_addr;
     int i;
 
@@ -151,16 +148,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Set up to return from userspace.  */
-
-    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
-    __put_user(retcode_addr, &frame->pretcode);
-
-    /* moveq #,d0; trap #0 */
-
-    __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
-               (uint32_t *)(frame->retcode));
-
-    /* Set up to return from userspace */
+    __put_user(default_sigreturn, &frame->pretcode);
 
     env->aregs[7] = frame_addr;
     env->pc = ka->_sa_handler;
@@ -287,7 +275,6 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 {
     struct target_rt_sigframe *frame;
     abi_ulong frame_addr;
-    abi_ulong retcode_addr;
     abi_ulong info_addr;
     abi_ulong uc_addr;
     int err = 0;
@@ -324,17 +311,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Set up to return from userspace.  */
-
-    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
-    __put_user(retcode_addr, &frame->pretcode);
-
-    /* moveq #,d0; notb d0; trap #0 */
-
-    __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
-               (uint32_t *)(frame->retcode + 0));
-    __put_user(0x4e40, (uint16_t *)(frame->retcode + 4));
-
-    /* Set up to return from userspace */
+    __put_user(default_rt_sigreturn, &frame->pretcode);
 
     env->aregs[7] = frame_addr;
     env->pc = ka->_sa_handler;
@@ -410,3 +387,23 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    void *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 + 6, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+
+    /* moveq #,d0; trap #0 */
+    __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16), (uint32_t *)tramp);
+
+    default_rt_sigreturn = sigtramp_page + 4;
+
+    /* moveq #,d0; notb d0; trap #0 */
+    __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
+               (uint32_t *)(tramp + 4));
+    __put_user(0x4e40, (uint16_t *)(tramp + 8));
+
+    unlock_user(tramp, sigtramp_page, 4 + 6);
+}
-- 
2.25.1



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

* [PATCH 11/21] linux-user/microblaze: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (9 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 10/21] linux-user/m68k: " Richard Henderson
@ 2021-06-16  1:11 ` Richard Henderson
  2021-06-16 16:43   ` Philippe Mathieu-Daudé
  2021-06-16  1:12 ` [PATCH 12/21] linux-user/mips: " Richard Henderson
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E . Iglesias, alex.bennee, laurent

Create and record the rt signal trampoline.

Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/microblaze/target_signal.h |  2 ++
 linux-user/microblaze/signal.c        | 24 +++++++++++++++++-------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/linux-user/microblaze/target_signal.h b/linux-user/microblaze/target_signal.h
index 1c326296de..e8b510f6b1 100644
--- a/linux-user/microblaze/target_signal.h
+++ b/linux-user/microblaze/target_signal.h
@@ -21,4 +21,6 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* MICROBLAZE_TARGET_SIGNAL_H */
diff --git a/linux-user/microblaze/signal.c b/linux-user/microblaze/signal.c
index 4c483bd8c6..aa27454931 100644
--- a/linux-user/microblaze/signal.c
+++ b/linux-user/microblaze/signal.c
@@ -160,17 +160,11 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     /* Kernel does not use SA_RESTORER. */
 
-    /* addi r12, r0, __NR_sigreturn */
-    __put_user(0x31800000U | TARGET_NR_rt_sigreturn, frame->tramp + 0);
-    /* brki r14, 0x8 */
-    __put_user(0xb9cc0008U, frame->tramp + 1);
-
     /*
      * Return from sighandler will jump to the tramp.
      * Negative 8 offset because return is rtsd r15, 8
      */
-    env->regs[15] =
-        frame_addr + offsetof(struct target_rt_sigframe, tramp) - 8;
+    env->regs[15] = default_rt_sigreturn - 8;
 
     /* Set up registers for signal handler */
     env->regs[1] = frame_addr;
@@ -219,3 +213,19 @@ long do_rt_sigreturn(CPUMBState *env)
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
+    assert(tramp != NULL);
+
+    /*
+     * addi r12, r0, __NR_rt_sigreturn
+     * brki r14, 0x8
+     */
+    __put_user(0x31800000U | TARGET_NR_rt_sigreturn, tramp);
+    __put_user(0xb9cc0008U, tramp + 1);
+
+    default_rt_sigreturn = sigtramp_page;
+    unlock_user(tramp, sigtramp_page, 8);
+}
-- 
2.25.1



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

* [PATCH 12/21] linux-user/mips: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (10 preceding siblings ...)
  2021-06-16  1:11 ` [PATCH 11/21] linux-user/microblaze: " Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16 16:48   ` Philippe Mathieu-Daudé
  2021-06-16  1:12 ` [PATCH 13/21] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Philippe Mathieu-Daudé

Create and record the two signal trampolines.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/mips/target_signal.h   |  1 +
 linux-user/mips64/target_signal.h |  2 ++
 linux-user/mips/signal.c          | 39 ++++++++++++++++++++-----------
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h
index d521765f6b..780a4ddf29 100644
--- a/linux-user/mips/target_signal.h
+++ b/linux-user/mips/target_signal.h
@@ -73,6 +73,7 @@ typedef struct target_sigaltstack {
 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
 #define TARGET_ARCH_HAS_SETUP_FRAME
 #endif
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
 
 /* bit-flags */
 #define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */
diff --git a/linux-user/mips64/target_signal.h b/linux-user/mips64/target_signal.h
index d857c55e4c..275e9b7f9a 100644
--- a/linux-user/mips64/target_signal.h
+++ b/linux-user/mips64/target_signal.h
@@ -76,4 +76,6 @@ typedef struct target_sigaltstack {
 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
 #define TARGET_ARCH_HAS_SETUP_FRAME
 #endif
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* MIPS64_TARGET_SIGNAL_H */
diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index e6be807a81..234f85905b 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -86,10 +86,8 @@ struct target_rt_sigframe {
 };
 
 /* Install trampoline to jump back from signal handler */
-static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
+static void install_sigtramp(unsigned int *tramp, unsigned int syscall)
 {
-    int err = 0;
-
     /*
      * Set up the return code ...
      *
@@ -99,7 +97,6 @@ static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
 
     __put_user(0x24020000 + syscall, tramp + 0);
     __put_user(0x0000000c          , tramp + 1);
-    return err;
 }
 
 static inline void setup_sigcontext(CPUMIPSState *regs,
@@ -211,8 +208,6 @@ void setup_frame(int sig, struct target_sigaction * ka,
         goto give_sigsegv;
     }
 
-    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
-
     setup_sigcontext(regs, &frame->sf_sc);
 
     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
@@ -233,7 +228,7 @@ void setup_frame(int sig, struct target_sigaction * ka,
     regs->active_tc.gpr[ 5] = 0;
     regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
     regs->active_tc.gpr[29] = frame_addr;
-    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
+    regs->active_tc.gpr[31] = default_sigreturn;
     /* The original kernel code sets CP0_EPC to the handler
     * since it returns to userland using eret
     * we cannot do this here, and we must set PC directly */
@@ -307,8 +302,6 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
         goto give_sigsegv;
     }
 
-    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
-
     tswap_siginfo(&frame->rs_info, info);
 
     __put_user(0, &frame->rs_uc.tuc_flags);
@@ -337,11 +330,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     env->active_tc.gpr[ 6] = frame_addr
                              + offsetof(struct target_rt_sigframe, rs_uc);
     env->active_tc.gpr[29] = frame_addr;
-    env->active_tc.gpr[31] = frame_addr
-                             + offsetof(struct target_rt_sigframe, rs_code);
-    /* The original kernel code sets CP0_EPC to the handler
-    * since it returns to userland using eret
-    * we cannot do this here, and we must set PC directly */
+    env->active_tc.gpr[31] = default_rt_sigreturn;
+
+    /*
+     * The original kernel code sets CP0_EPC to the handler
+     * since it returns to userland using eret
+     * we cannot do this here, and we must set PC directly
+     */
     env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
     mips_set_hflags_isa_mode_from_pc(env);
     unlock_user_struct(frame, frame_addr, 1);
@@ -381,3 +376,19 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
+    assert(tramp != NULL);
+
+#ifdef TARGET_ARCH_HAS_SETUP_FRAME
+    default_sigreturn = sigtramp_page;
+    install_sigtramp(tramp, TARGET_NR_sigreturn);
+#endif
+
+    default_rt_sigreturn = sigtramp_page + 8;
+    install_sigtramp(tramp + 2, TARGET_NR_rt_sigreturn);
+
+    unlock_user(tramp, sigtramp_page, 2 * 8);
+}
-- 
2.25.1



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

* [PATCH 13/21] linux-user/nios2: Document non-use of setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (11 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 12/21] linux-user/mips: " Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16  1:12 ` [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marek Vasut, Chris Wulff, alex.bennee, laurent

Cc: Chris Wulff <crwulff@gmail.com>
Cc: Marek Vasut <marex@denx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/nios2/target_signal.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-user/nios2/target_signal.h b/linux-user/nios2/target_signal.h
index aebf749f12..fe266c4c51 100644
--- a/linux-user/nios2/target_signal.h
+++ b/linux-user/nios2/target_signal.h
@@ -19,4 +19,7 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+/* Nios2 uses a fixed address on the kuser page for sigreturn. */
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
+
 #endif /* NIOS2_TARGET_SIGNAL_H */
-- 
2.25.1



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

* [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (12 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 13/21] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16 16:49   ` Philippe Mathieu-Daudé
  2021-06-17  0:24   ` Stafford Horne
  2021-06-16  1:12 ` [PATCH 15/21] linux-user/ppc: " Richard Henderson
                   ` (7 subsequent siblings)
  21 siblings, 2 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stafford Horne, alex.bennee, laurent

Create and record the rt signal trampoline.

Cc: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/openrisc/target_signal.h |  2 ++
 linux-user/openrisc/signal.c        | 24 ++++++++++++++++--------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/linux-user/openrisc/target_signal.h b/linux-user/openrisc/target_signal.h
index 8283eaf544..077ec3d5e8 100644
--- a/linux-user/openrisc/target_signal.h
+++ b/linux-user/openrisc/target_signal.h
@@ -26,4 +26,6 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* OPENRISC_TARGET_SIGNAL_H */
diff --git a/linux-user/openrisc/signal.c b/linux-user/openrisc/signal.c
index 5c5640a284..b411b01864 100644
--- a/linux-user/openrisc/signal.c
+++ b/linux-user/openrisc/signal.c
@@ -37,7 +37,6 @@ typedef struct target_ucontext {
 typedef struct target_rt_sigframe {
     struct target_siginfo info;
     target_ucontext uc;
-    uint32_t retcode[4];  /* trampoline code */
 } target_rt_sigframe;
 
 static void restore_sigcontext(CPUOpenRISCState *env, target_sigcontext *sc)
@@ -115,14 +114,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
         __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
     }
 
-    /* This is l.ori r11,r0,__NR_sigreturn; l.sys 1; l.nop; l.nop */
-    __put_user(0xa9600000 | TARGET_NR_rt_sigreturn, frame->retcode + 0);
-    __put_user(0x20000001, frame->retcode + 1);
-    __put_user(0x15000000, frame->retcode + 2);
-    __put_user(0x15000000, frame->retcode + 3);
-
     /* Set up registers for signal handler */
-    cpu_set_gpr(env, 9, frame_addr + offsetof(target_rt_sigframe, retcode));
+    cpu_set_gpr(env, 9, default_rt_sigreturn);
     cpu_set_gpr(env, 3, sig);
     cpu_set_gpr(env, 4, frame_addr + offsetof(target_rt_sigframe, info));
     cpu_set_gpr(env, 5, frame_addr + offsetof(target_rt_sigframe, uc));
@@ -168,3 +161,18 @@ long do_rt_sigreturn(CPUOpenRISCState *env)
     force_sig(TARGET_SIGSEGV);
     return 0;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 4, 0);
+    assert(tramp != NULL);
+
+    /* This is l.ori r11,r0,__NR_sigreturn; l.sys 1; l.nop; l.nop */
+    __put_user(0xa9600000 | TARGET_NR_rt_sigreturn, tramp + 0);
+    __put_user(0x20000001, tramp + 1);
+    __put_user(0x15000000, tramp + 2);
+    __put_user(0x15000000, tramp + 3);
+
+    default_rt_sigreturn = sigtramp_page;
+    unlock_user(tramp, sigtramp_page, 4 * 4);
+}
-- 
2.25.1



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

* [PATCH 15/21] linux-user/ppc: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (13 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16  1:12   ` Richard Henderson
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, alex.bennee, laurent

Create and record the two signal trampolines.

Cc: qemu-ppc@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/ppc/target_signal.h |  2 ++
 linux-user/ppc/signal.c        | 34 ++++++++++++++++++----------------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/linux-user/ppc/target_signal.h b/linux-user/ppc/target_signal.h
index 72fcdd9bfa..82184ab8f2 100644
--- a/linux-user/ppc/target_signal.h
+++ b/linux-user/ppc/target_signal.h
@@ -24,4 +24,6 @@ typedef struct target_sigaltstack {
 #if !defined(TARGET_PPC64)
 #define TARGET_ARCH_HAS_SETUP_FRAME
 #endif
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* PPC_TARGET_SIGNAL_H */
diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c
index edfad28a37..4ae35aaf6d 100644
--- a/linux-user/ppc/signal.c
+++ b/linux-user/ppc/signal.c
@@ -202,9 +202,6 @@ struct target_func_ptr {
 
 #endif
 
-/* We use the mc_pad field for the signal return trampoline.  */
-#define tramp mc_pad
-
 /* See arch/powerpc/kernel/signal.c.  */
 static target_ulong get_sigframe(struct target_sigaction *ka,
                                  CPUPPCState *env,
@@ -437,12 +434,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     /* Save user regs.  */
     save_user_regs(env, &frame->mctx);
 
-    /* Construct the trampoline code on the stack. */
-    encode_trampoline(TARGET_NR_sigreturn, (uint32_t *)&frame->mctx.tramp);
-
-    /* The kernel checks for the presence of a VDSO here.  We don't
-       emulate a vdso, so use a sigreturn system call.  */
-    env->lr = (target_ulong) h2g(frame->mctx.tramp);
+    env->lr = default_sigreturn;
 
     /* Turn off all fp exceptions.  */
     env->fpscr = 0;
@@ -478,7 +470,6 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
                     target_sigset_t *set, CPUPPCState *env)
 {
     struct target_rt_sigframe *rt_sf;
-    uint32_t *trampptr = 0;
     struct target_mcontext *mctx = 0;
     target_ulong rt_sf_addr, newsp = 0;
     int i, err = 0;
@@ -508,22 +499,17 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 #if defined(TARGET_PPC64)
     mctx = &rt_sf->uc.tuc_sigcontext.mcontext;
-    trampptr = &rt_sf->trampoline[0];
 
     sc = &rt_sf->uc.tuc_sigcontext;
     __put_user(h2g(mctx), &sc->regs);
     __put_user(sig, &sc->signal);
 #else
     mctx = &rt_sf->uc.tuc_mcontext;
-    trampptr = (uint32_t *)&rt_sf->uc.tuc_mcontext.tramp;
 #endif
 
     save_user_regs(env, mctx);
-    encode_trampoline(TARGET_NR_rt_sigreturn, trampptr);
 
-    /* The kernel checks for the presence of a VDSO here.  We don't
-       emulate a vdso, so use a sigreturn system call.  */
-    env->lr = (target_ulong) h2g(trampptr);
+    env->lr = default_rt_sigreturn;
 
     /* Turn off all fp exceptions.  */
     env->fpscr = 0;
@@ -721,3 +707,19 @@ abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
 
     return 0;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
+    assert(tramp != NULL);
+
+#ifdef TARGET_ARCH_HAS_SETUP_FRAME
+    default_sigreturn = sigtramp_page;
+    encode_trampoline(TARGET_NR_sigreturn, tramp + 0);
+#endif
+
+    default_rt_sigreturn = sigtramp_page + 8;
+    encode_trampoline(TARGET_NR_rt_sigreturn, tramp + 2);
+
+    unlock_user(tramp, sigtramp_page, 2 * 8);
+}
-- 
2.25.1



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

* [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
@ 2021-06-16  1:12   ` Richard Henderson
  2021-06-16  1:11 ` [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
                     ` (20 subsequent siblings)
  21 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alex.bennee, laurent

Create and record the rt signal trampoline.

This fixes a bug wrt libgcc fallback unwinding.  It expects
the stack pointer to point to the siginfo_t, whereas we had
inexplicably placed our private signal trampoline at the start
of the signal frame instead of the end.  Now moot because we
have removed it from the stack frame entirely.

Cc: qemu-riscv@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/riscv/target_signal.h |  2 ++
 linux-user/riscv/signal.c        | 22 +++++++++++++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h
index f113ba9a55..3e36fddc9d 100644
--- a/linux-user/riscv/target_signal.h
+++ b/linux-user/riscv/target_signal.h
@@ -15,4 +15,6 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* RISCV_TARGET_SIGNAL_H */
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index 9405c7fd9a..4086dfa5d5 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -46,7 +46,6 @@ struct target_ucontext {
 };
 
 struct target_rt_sigframe {
-    uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */
     struct target_siginfo info;
     struct target_ucontext uc;
 };
@@ -104,12 +103,6 @@ static void setup_ucontext(struct target_ucontext *uc,
     setup_sigcontext(&uc->uc_mcontext, env);
 }
 
-static inline void install_sigtramp(uint32_t *tramp)
-{
-    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
-    __put_user(0x00000073, tramp + 1);  /* ecall */
-}
-
 void setup_rt_frame(int sig, struct target_sigaction *ka,
                     target_siginfo_t *info,
                     target_sigset_t *set, CPURISCVState *env)
@@ -126,14 +119,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     setup_ucontext(&frame->uc, env, set);
     tswap_siginfo(&frame->info, info);
-    install_sigtramp(frame->tramp);
 
     env->pc = ka->_sa_handler;
     env->gpr[xSP] = frame_addr;
     env->gpr[xA0] = sig;
     env->gpr[xA1] = frame_addr + offsetof(struct target_rt_sigframe, info);
     env->gpr[xA2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
-    env->gpr[xRA] = frame_addr + offsetof(struct target_rt_sigframe, tramp);
+    env->gpr[xRA] = default_rt_sigreturn;
 
     return;
 
@@ -202,3 +194,15 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return 0;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
+    assert(tramp != NULL);
+
+    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
+    __put_user(0x00000073, tramp + 1);  /* ecall */
+
+    default_rt_sigreturn = sigtramp_page;
+    unlock_user(tramp, sigtramp_page, 8);
+}
-- 
2.25.1



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

* [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
@ 2021-06-16  1:12   ` Richard Henderson
  0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, alex.bennee, qemu-riscv

Create and record the rt signal trampoline.

This fixes a bug wrt libgcc fallback unwinding.  It expects
the stack pointer to point to the siginfo_t, whereas we had
inexplicably placed our private signal trampoline at the start
of the signal frame instead of the end.  Now moot because we
have removed it from the stack frame entirely.

Cc: qemu-riscv@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/riscv/target_signal.h |  2 ++
 linux-user/riscv/signal.c        | 22 +++++++++++++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h
index f113ba9a55..3e36fddc9d 100644
--- a/linux-user/riscv/target_signal.h
+++ b/linux-user/riscv/target_signal.h
@@ -15,4 +15,6 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* RISCV_TARGET_SIGNAL_H */
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index 9405c7fd9a..4086dfa5d5 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -46,7 +46,6 @@ struct target_ucontext {
 };
 
 struct target_rt_sigframe {
-    uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */
     struct target_siginfo info;
     struct target_ucontext uc;
 };
@@ -104,12 +103,6 @@ static void setup_ucontext(struct target_ucontext *uc,
     setup_sigcontext(&uc->uc_mcontext, env);
 }
 
-static inline void install_sigtramp(uint32_t *tramp)
-{
-    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
-    __put_user(0x00000073, tramp + 1);  /* ecall */
-}
-
 void setup_rt_frame(int sig, struct target_sigaction *ka,
                     target_siginfo_t *info,
                     target_sigset_t *set, CPURISCVState *env)
@@ -126,14 +119,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     setup_ucontext(&frame->uc, env, set);
     tswap_siginfo(&frame->info, info);
-    install_sigtramp(frame->tramp);
 
     env->pc = ka->_sa_handler;
     env->gpr[xSP] = frame_addr;
     env->gpr[xA0] = sig;
     env->gpr[xA1] = frame_addr + offsetof(struct target_rt_sigframe, info);
     env->gpr[xA2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
-    env->gpr[xRA] = frame_addr + offsetof(struct target_rt_sigframe, tramp);
+    env->gpr[xRA] = default_rt_sigreturn;
 
     return;
 
@@ -202,3 +194,15 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return 0;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
+    assert(tramp != NULL);
+
+    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
+    __put_user(0x00000073, tramp + 1);  /* ecall */
+
+    default_rt_sigreturn = sigtramp_page;
+    unlock_user(tramp, sigtramp_page, 8);
+}
-- 
2.25.1



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

* [PATCH 17/21] linux-user/s390x: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (15 preceding siblings ...)
  2021-06-16  1:12   ` Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16 16:52   ` Philippe Mathieu-Daudé
  2021-06-16  1:12 ` [PATCH 18/21] linux-user/sh4: " Richard Henderson
                   ` (4 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, alex.bennee, laurent

Create and record the two signal trampolines.
Use them when the guest does not use SA_RESTORER.

Cc: qemu-s390x@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/s390x/target_signal.h |  2 ++
 linux-user/s390x/signal.c        | 24 ++++++++++++++++--------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h
index bbfc464d44..64f5f42201 100644
--- a/linux-user/s390x/target_signal.h
+++ b/linux-user/s390x/target_signal.h
@@ -19,4 +19,6 @@ typedef struct target_sigaltstack {
 #include "../generic/signal.h"
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* S390X_TARGET_SIGNAL_H */
diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c
index ef136dae33..806c09f921 100644
--- a/linux-user/s390x/signal.c
+++ b/linux-user/s390x/signal.c
@@ -67,7 +67,6 @@ typedef struct {
     target_sigregs sregs;
     int signo;
     target_sigregs_ext sregs_ext;
-    uint16_t retcode;
 } sigframe;
 
 #define TARGET_UC_VXRS 2
@@ -84,7 +83,6 @@ struct target_ucontext {
 
 typedef struct {
     uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
-    uint16_t retcode;
     struct target_siginfo info;
     struct target_ucontext uc;
 } rt_sigframe;
@@ -200,9 +198,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         restorer = ka->sa_restorer;
     } else {
-        restorer = frame_addr + offsetof(sigframe, retcode);
-        __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
-                   &frame->retcode);
+        restorer = default_sigreturn;
     }
 
     /* Set up registers for signal handler */
@@ -253,9 +249,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         restorer = ka->sa_restorer;
     } else {
-        restorer = frame_addr + offsetof(typeof(*frame), retcode);
-        __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
-                   &frame->retcode);
+        restorer = default_rt_sigreturn;
     }
 
     /* Create siginfo on the signal stack. */
@@ -377,3 +371,17 @@ long do_rt_sigreturn(CPUS390XState *env)
     unlock_user_struct(frame, frame_addr, 0);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, &tramp[0]);
+
+    default_rt_sigreturn = sigtramp_page + 2;
+    __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, &tramp[1]);
+
+    unlock_user(tramp, sigtramp_page, 4);
+}
-- 
2.25.1



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

* [PATCH 18/21] linux-user/sh4: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (16 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 17/21] linux-user/s390x: " Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16 16:53   ` Philippe Mathieu-Daudé
  2021-06-16  1:12 ` [PATCH 19/21] linux-user/sparc: " Richard Henderson
                   ` (3 subsequent siblings)
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Yoshinori Sato

Create and record the two signal trampolines.
Use them when the guest does not use SA_RESTORER.

Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sh4/target_signal.h |  2 ++
 linux-user/sh4/signal.c        | 40 +++++++++++++++++++---------------
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/linux-user/sh4/target_signal.h b/linux-user/sh4/target_signal.h
index d7309b7136..04069cba66 100644
--- a/linux-user/sh4/target_signal.h
+++ b/linux-user/sh4/target_signal.h
@@ -22,4 +22,6 @@ typedef struct target_sigaltstack {
 #include "../generic/signal.h"
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif /* SH4_TARGET_SIGNAL_H */
diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c
index 0451e65806..5a5ae69785 100644
--- a/linux-user/sh4/signal.c
+++ b/linux-user/sh4/signal.c
@@ -51,7 +51,6 @@ struct target_sigframe
 {
     struct target_sigcontext sc;
     target_ulong extramask[TARGET_NSIG_WORDS-1];
-    uint16_t retcode[3];
 };
 
 
@@ -67,7 +66,6 @@ struct target_rt_sigframe
 {
     struct target_siginfo info;
     struct target_ucontext uc;
-    uint16_t retcode[3];
 };
 
 
@@ -189,15 +187,9 @@ void setup_frame(int sig, struct target_sigaction *ka,
     /* Set up to return from userspace.  If provided, use a stub
        already in userspace.  */
     if (ka->sa_flags & TARGET_SA_RESTORER) {
-        regs->pr = (unsigned long) ka->sa_restorer;
+        regs->pr = ka->sa_restorer;
     } else {
-        /* Generate return code (system call to sigreturn) */
-        abi_ulong retcode_addr = frame_addr +
-                                 offsetof(struct target_sigframe, retcode);
-        __put_user(MOVW(2), &frame->retcode[0]);
-        __put_user(TRAP_NOARG, &frame->retcode[1]);
-        __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
-        regs->pr = (unsigned long) retcode_addr;
+        regs->pr = default_sigreturn;
     }
 
     /* Set up registers for signal handler */
@@ -247,15 +239,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     /* Set up to return from userspace.  If provided, use a stub
        already in userspace.  */
     if (ka->sa_flags & TARGET_SA_RESTORER) {
-        regs->pr = (unsigned long) ka->sa_restorer;
+        regs->pr = ka->sa_restorer;
     } else {
-        /* Generate return code (system call to sigreturn) */
-        abi_ulong retcode_addr = frame_addr +
-                                 offsetof(struct target_rt_sigframe, retcode);
-        __put_user(MOVW(2), &frame->retcode[0]);
-        __put_user(TRAP_NOARG, &frame->retcode[1]);
-        __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
-        regs->pr = (unsigned long) retcode_addr;
+        regs->pr = default_rt_sigreturn;
     }
 
     /* Set up registers for signal handler */
@@ -333,3 +319,21 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 6, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    __put_user(MOVW(2), &tramp[0]);
+    __put_user(TRAP_NOARG, &tramp[1]);
+    __put_user(TARGET_NR_sigreturn, &tramp[2]);
+
+    default_rt_sigreturn = sigtramp_page + 6;
+    __put_user(MOVW(2), &tramp[3]);
+    __put_user(TRAP_NOARG, &tramp[4]);
+    __put_user(TARGET_NR_rt_sigreturn, &tramp[5]);
+
+    unlock_user(tramp, sigtramp_page, 2 * 6);
+}
-- 
2.25.1



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

* [PATCH 19/21] linux-user/sparc: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (17 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 18/21] linux-user/sh4: " Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16  1:12 ` [PATCH 20/21] linux-user/xtensa: " Richard Henderson
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland, alex.bennee, laurent

Create and record the two signal trampolines.
Use them when the guest does not use SA_RESTORER.

Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc/target_signal.h |  4 ++++
 linux-user/sparc/signal.c        | 32 ++++++++++++++++++--------------
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/linux-user/sparc/target_signal.h b/linux-user/sparc/target_signal.h
index 34f9a12519..e661ddd6ab 100644
--- a/linux-user/sparc/target_signal.h
+++ b/linux-user/sparc/target_signal.h
@@ -69,6 +69,10 @@ typedef struct target_sigaltstack {
 
 #ifdef TARGET_ABI32
 #define TARGET_ARCH_HAS_SETUP_FRAME
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+#else
+/* For sparc64, use of KA_RESTORER is mandatory. */
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
 #endif
 
 /* bit-flags */
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index 0cc3db5570..65e9b7f8b4 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -290,13 +290,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     if (ka->ka_restorer) {
         env->regwptr[WREG_O7] = ka->ka_restorer;
     } else {
-        env->regwptr[WREG_O7] = sf_addr +
-                offsetof(struct target_signal_frame, insns) - 2 * 4;
-
-        /* mov __NR_sigreturn, %g1 */
-        __put_user(0x821020d8u, &sf->insns[0]);
-        /* t 0x10 */
-        __put_user(0x91d02010u, &sf->insns[1]);
+        env->regwptr[WREG_O7] = default_sigreturn;
     }
     unlock_user(sf, sf_addr, sf_size);
 }
@@ -357,13 +351,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     if (ka->ka_restorer) {
         env->regwptr[WREG_O7] = ka->ka_restorer;
     } else {
-        env->regwptr[WREG_O7] =
-            sf_addr + offsetof(struct target_rt_signal_frame, insns) - 2 * 4;
-
-        /* mov __NR_rt_sigreturn, %g1 */
-        __put_user(0x82102065u, &sf->insns[0]);
-        /* t 0x10 */
-        __put_user(0x91d02010u, &sf->insns[1]);
+        env->regwptr[WREG_O7] = default_rt_sigreturn;
     }
 #else
     env->regwptr[WREG_O7] = ka->ka_restorer;
@@ -774,4 +762,20 @@ do_sigsegv:
     unlock_user_struct(ucp, ucp_addr, 1);
     force_sig(TARGET_SIGSEGV);
 }
+#else
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    __put_user(0x821020d8u, &tramp[0]);   /* mov __NR_sigreturn, %g1 */
+    __put_user(0x91d02010u, &tramp[1]);   /* t 0x10 */
+
+    default_rt_sigreturn = sigtramp_page + 8;
+    __put_user(0x82102065u, &tramp[2]);   /* mov __NR_rt_sigreturn, %g1 */
+    __put_user(0x91d02010u, &tramp[3]);   /* t 0x10 */
+
+    unlock_user(tramp, sigtramp_page, 2 * 8);
+}
 #endif
-- 
2.25.1



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

* [PATCH 20/21] linux-user/xtensa: Implement setup_sigtramp
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (18 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 19/21] linux-user/sparc: " Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16 13:35   ` Max Filippov
  2021-06-16  1:12 ` [PATCH 21/21] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson
  2021-06-16 15:05 ` [PATCH 00/21] linux-user: Move signal trampolines to new page Alex Bennée
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Filippov, alex.bennee, laurent

Create and record the rt signal trampoline.
Use it when the guest does not use SA_RESTORER.

Cc: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/xtensa/target_signal.h |  2 ++
 linux-user/xtensa/signal.c        | 50 ++++++++++++++++++-------------
 2 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/linux-user/xtensa/target_signal.h b/linux-user/xtensa/target_signal.h
index c60bf656f6..1c7ee73154 100644
--- a/linux-user/xtensa/target_signal.h
+++ b/linux-user/xtensa/target_signal.h
@@ -20,4 +20,6 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
 #endif
diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c
index 72771e1294..fd57481bf5 100644
--- a/linux-user/xtensa/signal.c
+++ b/linux-user/xtensa/signal.c
@@ -163,26 +163,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         ra = ka->sa_restorer;
     } else {
-        ra = frame_addr + offsetof(struct target_rt_sigframe, retcode);
-#ifdef TARGET_WORDS_BIGENDIAN
-        /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
-        __put_user(0x22, &frame->retcode[0]);
-        __put_user(0x0a, &frame->retcode[1]);
-        __put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]);
-        /* Generate instruction:  SYSCALL */
-        __put_user(0x00, &frame->retcode[3]);
-        __put_user(0x05, &frame->retcode[4]);
-        __put_user(0x00, &frame->retcode[5]);
-#else
-        /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
-        __put_user(0x22, &frame->retcode[0]);
-        __put_user(0xa0, &frame->retcode[1]);
-        __put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]);
-        /* Generate instruction:  SYSCALL */
-        __put_user(0x00, &frame->retcode[3]);
-        __put_user(0x50, &frame->retcode[4]);
-        __put_user(0x00, &frame->retcode[5]);
-#endif
+        ra = default_rt_sigreturn;
     }
     memset(env->regs, 0, sizeof(env->regs));
     env->pc = ka->_sa_handler;
@@ -263,3 +244,32 @@ badframe:
     force_sig(TARGET_SIGSEGV);
     return -TARGET_QEMU_ESIGRETURN;
 }
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+    uint8_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6, 0);
+    assert(tramp != NULL);
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
+    __put_user(0x22, &tramp[0]);
+    __put_user(0x0a, &tramp[1]);
+    __put_user(TARGET_NR_rt_sigreturn, &tramp[2]);
+    /* Generate instruction:  SYSCALL */
+    __put_user(0x00, &tramp[3]);
+    __put_user(0x05, &tramp[4]);
+    __put_user(0x00, &tramp[5]);
+#else
+    /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
+    __put_user(0x22, &tramp[0]);
+    __put_user(0xa0, &tramp[1]);
+    __put_user(TARGET_NR_rt_sigreturn, &tramp[2]);
+    /* Generate instruction:  SYSCALL */
+    __put_user(0x00, &tramp[3]);
+    __put_user(0x50, &tramp[4]);
+    __put_user(0x00, &tramp[5]);
+#endif
+
+    default_rt_sigreturn = sigtramp_page;
+    unlock_user(tramp, sigtramp_page, 6);
+}
-- 
2.25.1



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

* [PATCH 21/21] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (19 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 20/21] linux-user/xtensa: " Richard Henderson
@ 2021-06-16  1:12 ` Richard Henderson
  2021-06-16 16:54   ` Philippe Mathieu-Daudé
  2021-06-16 15:05 ` [PATCH 00/21] linux-user: Move signal trampolines to new page Alex Bennée
  21 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16  1:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

All targets now define TARGET_ARCH_HAS_SIGTRAMP_PAGE.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/elfload.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 7bc67ac9cb..c0236a0b09 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -26,10 +26,6 @@
 #undef ELF_ARCH
 #endif
 
-#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE
-#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
-#endif
-
 #define ELF_OSABI   ELFOSABI_SYSV
 
 /* from personality.h */
-- 
2.25.1



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

* RE: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 07/21] linux-user/hexagon: " Richard Henderson
@ 2021-06-16  8:07   ` Taylor Simpson
  2021-06-16 15:05     ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: Taylor Simpson @ 2021-06-16  8:07 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent



> -----Original Message-----
> From: Richard Henderson <richard.henderson@linaro.org>
> Sent: Tuesday, June 15, 2021 7:12 PM
> To: qemu-devel@nongnu.org
> Cc: laurent@vivier.eu; alex.bennee@linaro.org; Taylor Simpson
> <tsimpson@quicinc.com>
> Subject: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
> 
> Continue to initialize the words on the stack, as documented.
> However, use the off-stack trampoline.
> 
> Cc: Taylor Simpson <tsimpson@quicinc.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> 
> diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c index
> 85eab5e943..bd0f9b1c85 100644
> --- a/linux-user/hexagon/signal.c
> +++ b/linux-user/hexagon/signal.c
> @@ -161,6 +161,11 @@ void setup_rt_frame(int sig, struct target_sigaction
> *ka,
> 
>      setup_ucontext(&frame->uc, env, set);
>      tswap_siginfo(&frame->info, info);
> +    /*
> +     * The on-stack signal trampoline is no longer executed;
> +     * however, the libgcc signal frame unwinding code checks
> +     * for the presence of these two numeric magic values.
> +     */

Hexagon uses musl, not libgcc.  So, I'm not sure if this is needed.  The signals.c test passes for me without this change.  Are you seeing it fail?


> +void setup_sigtramp(abi_ulong sigtramp_page) {
> +    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 2, 0);
> +    assert(tramp != NULL);
> +
> +    default_rt_sigreturn = sigtramp_page;
> +    install_sigtramp(tramp);
> +
> +    unlock_user(tramp, sigtramp_page, 4 * 2); }

Put the closing curly on a new line.


Thanks,
Taylor



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

* Re: [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp
  2021-06-16  1:11 ` [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
@ 2021-06-16 10:46   ` Philippe Mathieu-Daudé
  2021-06-16 21:16   ` Alex Bennée
  1 sibling, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 10:46 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Helge Deller, alex.bennee, laurent

+Helge

On 6/16/21 3:11 AM, Richard Henderson wrote:
> We cannot use a raw sigtramp page for hppa,
> but must wait for full vdso support.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/hppa/target_signal.h | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/linux-user/hppa/target_signal.h b/linux-user/hppa/target_signal.h
> index 7f525362e9..d558119ee7 100644
> --- a/linux-user/hppa/target_signal.h
> +++ b/linux-user/hppa/target_signal.h
> @@ -71,4 +71,18 @@ typedef struct target_sigaltstack {
>  /* mask for all SS_xxx flags */
>  #define TARGET_SS_FLAG_BITS  TARGET_SS_AUTODISARM
>  
> +/*
> + * We cannot use a bare sigtramp page for hppa-linux.
> + *
> + * Unlike other guests where we use the instructions at PC to validate
> + * an offset from SP, the hppa libgcc signal frame fallback unwinding uses
> + * the PC address itself to find the frame.  This is due to the fact that
> + * the hppa grows the stack upward, and the frame is of unknown size.
> + *
> + * TODO: We should be able to use a VDSO to address this, by providing
> + * proper unwind info for the sigtramp code, at which point the fallback
> + * unwinder will not be used.
> + */
> +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
> +
>  #endif /* HPPA_TARGET_SIGNAL_H */
> 

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


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

* Re: [PATCH 20/21] linux-user/xtensa: Implement setup_sigtramp
  2021-06-16  1:12 ` [PATCH 20/21] linux-user/xtensa: " Richard Henderson
@ 2021-06-16 13:35   ` Max Filippov
  0 siblings, 0 replies; 53+ messages in thread
From: Max Filippov @ 2021-06-16 13:35 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Alex Bennée, qemu-devel, Laurent Vivier

On Tue, Jun 15, 2021 at 6:12 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Create and record the rt signal trampoline.
> Use it when the guest does not use SA_RESTORER.
>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/xtensa/target_signal.h |  2 ++
>  linux-user/xtensa/signal.c        | 50 ++++++++++++++++++-------------
>  2 files changed, 32 insertions(+), 20 deletions(-)

Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>

-- 
Thanks.
-- Max


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

* Re: [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page
  2021-06-16  1:11 ` [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
@ 2021-06-16 13:36   ` Max Filippov
  0 siblings, 0 replies; 53+ messages in thread
From: Max Filippov @ 2021-06-16 13:36 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Alex Bennée, qemu-devel, Laurent Vivier

On Tue, Jun 15, 2021 at 6:20 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Allocate a page to hold the signal trampoline(s).
> Invoke a guest-specific hook to fill in the contents
> of the page before marking it read-execute again.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/qemu.h    |  7 +++++++
>  linux-user/elfload.c | 17 +++++++++++++++++
>  linux-user/signal.c  |  3 +++
>  3 files changed, 27 insertions(+)

Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>

-- 
Thanks.
-- Max


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

* Re: [PATCH 04/21] linux-user/arm: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 04/21] linux-user/arm: Implement setup_sigtramp Richard Henderson
@ 2021-06-16 13:46   ` Alex Bennée
  2021-06-16 13:49     ` Alex Bennée
  0 siblings, 1 reply; 53+ messages in thread
From: Alex Bennée @ 2021-06-16 13:46 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, qemu-devel, laurent

Richard Henderson <richard.henderson@linaro.org> writes:

> ARM is more complicated than the others, in that we also
> have trampolines for using SA_RESTORER with FDPIC, and
> we need to create trampolines for both ARM and Thumb modes.
>
> Cc: qemu-arm@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/arm/target_signal.h |   2 +
>  linux-user/arm/signal.c        | 170 +++++++++++++++++++--------------
>  2 files changed, 100 insertions(+), 72 deletions(-)
>
> +
> +    /* ARM sigframe */
> +    _Static_assert(SIGFRAME_FDPIC_OFS <= 0xfff);
> +    __put_user(0xe59d9000 | SIGFRAME_FDPIC_OFS, &tramp[i++]);
> +    __put_user(0xe8998200, &tramp[i++]);

Erm is this based on your c11 series?

> +
> +    /* Thumb sigframe */
> +    _Static_assert(SIGFRAME_FDPIC_OFS <= 0xff << 2);
> +    _Static_assert((SIGFRAME_FDPIC_OFS & 3) == 0);
> +    __put_user(0x9a00e9dd | (SIGFRAME_FDPIC_OFS << 14), &tramp[i++]);
> +    __put_user(0x46c04750, &tramp[i++]);
> +
> +    /* ARM rt_sigframe */
> +    _Static_assert(RT_SIGFRAME_FDPIC_OFS <= 0xfff);
> +    __put_user(0xe59d9000 | RT_SIGFRAME_FDPIC_OFS, &tramp[i++]);
> +    __put_user(0xe8998200, &tramp[i++]);
> +
> +    /* Thumb rt_sigframe */
> +    _Static_assert(RT_SIGFRAME_FDPIC_OFS <= 0xff << 2);
> +    _Static_assert((RT_SIGFRAME_FDPIC_OFS & 3) == 0);
> +    __put_user(0x9a00e9dd | (RT_SIGFRAME_FDPIC_OFS << 14), &tramp[i++]);
> +    __put_user(0x46c04750, &tramp[i++]);
> +
> +    unlock_user(tramp, sigtramp_page, total_size);
> +}

-- 
Alex Bennée


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

* Re: [PATCH 04/21] linux-user/arm: Implement setup_sigtramp
  2021-06-16 13:46   ` Alex Bennée
@ 2021-06-16 13:49     ` Alex Bennée
  2021-06-16 17:40       ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: Alex Bennée @ 2021-06-16 13:49 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, qemu-devel, laurent

Alex Bennée <alex.bennee@linaro.org> writes:

> Richard Henderson <richard.henderson@linaro.org> writes:
>
>> ARM is more complicated than the others, in that we also
>> have trampolines for using SA_RESTORER with FDPIC, and
>> we need to create trampolines for both ARM and Thumb modes.
>>
>> Cc: qemu-arm@nongnu.org
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>  linux-user/arm/target_signal.h |   2 +
>>  linux-user/arm/signal.c        | 170 +++++++++++++++++++--------------
>>  2 files changed, 100 insertions(+), 72 deletions(-)
>>
>> +
>> +    /* ARM sigframe */
>> +    _Static_assert(SIGFRAME_FDPIC_OFS <= 0xfff);
>> +    __put_user(0xe59d9000 | SIGFRAME_FDPIC_OFS, &tramp[i++]);
>> +    __put_user(0xe8998200, &tramp[i++]);
>
> Erm is this based on your c11 series?

Actually it's merged already so I'm seeing the following on hackbox:

  FAILED: libqemu-armeb-linux-user.fa.p/linux-user_arm_signal.c.o
  cc -Ilibqemu-armeb-linux-user.fa.p -I. -I../.. -Itarget/arm -I../../target/arm -I../../linux-user/host/x86_64 -Ilinux-user -I../../linux-user -Ilinux-user/arm -I../../linux-
  user/arm -I../../capstone/include/capstone -Itrace -Iqapi -Iui/shader -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fdiagnostics-color=auto -pipe -Wa
  ll -Winvalid-pch -Werror -std=gnu99 -O2 -g -isystem /home/alex.bennee/lsrc/qemu.git/linux-headers -isystem linux-headers -iquote . -iquote /home/alex.bennee/lsrc/qemu.git -i
  quote /home/alex.bennee/lsrc/qemu.git/include -iquote /home/alex.bennee/lsrc/qemu.git/disas/libvixl -iquote /home/alex.bennee/lsrc/qemu.git/tcg/i386 -pthread -U_FORTIFY_SOUR
  CE -D_FORTIFY_SOURCE=2 -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wundef -Wwrite-strings -Wmissing-prototype
  s -fno-strict-aliasing -fno-common -fwrapv -Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wemp
  ty-body -Wnested-externs -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2 -Wno-missing-include-dirs -Wno-shift-negative-value -Wno-psabi -fstack-protector-stro
  ng -isystem../../linux-headers -isystemlinux-headers -DNEED_CPU_H '-DCONFIG_TARGET="armeb-linux-user-config-target.h"' '-DCONFIG_DEVICES="armeb-linux-user-config-devices.h"'
   -MD -MQ libqemu-armeb-linux-user.fa.p/linux-user_arm_signal.c.o -MF libqemu-armeb-linux-user.fa.p/linux-user_arm_signal.c.o.d -o libqemu-armeb-linux-user.fa.p/linux-user_ar
  m_signal.c.o -c ../../linux-user/arm/signal.c
  ../../linux-user/arm/signal.c: In function ‘setup_sigtramp’:
  ../../linux-user/arm/signal.c:847:47: error: expected ‘,’ before ‘)’ token
       _Static_assert(SIGFRAME_FDPIC_OFS <= 0xfff);
                                                 ^
  ../../linux-user/arm/signal.c:852:51: error: expected ‘,’ before ‘)’ token
       _Static_assert(SIGFRAME_FDPIC_OFS <= 0xff << 2);
                                                     ^
  ../../linux-user/arm/signal.c:853:49: error: expected ‘,’ before ‘)’ token
       _Static_assert((SIGFRAME_FDPIC_OFS & 3) == 0);
                                                   ^
  ../../linux-user/arm/signal.c:858:50: error: expected ‘,’ before ‘)’ token
       _Static_assert(RT_SIGFRAME_FDPIC_OFS <= 0xfff);
                                                    ^
  ../../linux-user/arm/signal.c:863:54: error: expected ‘,’ before ‘)’ token
       _Static_assert(RT_SIGFRAME_FDPIC_OFS <= 0xff << 2);
                                                        ^
  ../../linux-user/arm/signal.c:864:52: error: expected ‘,’ before ‘)’ token
       _Static_assert((RT_SIGFRAME_FDPIC_OFS & 3) == 0);

-- 
Alex Bennée


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

* Re: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
  2021-06-16  8:07   ` Taylor Simpson
@ 2021-06-16 15:05     ` Richard Henderson
  2021-06-16 15:50       ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16 15:05 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 1:07 AM, Taylor Simpson wrote:
>> +    /*
>> +     * The on-stack signal trampoline is no longer executed;
>> +     * however, the libgcc signal frame unwinding code checks
>> +     * for the presence of these two numeric magic values.
>> +     */
> 
> Hexagon uses musl, not libgcc.  So, I'm not sure if this is needed.  The signals.c test passes for me without this change.  Are you seeing it fail?

I copied the comment from the kernel source.


>> +void setup_sigtramp(abi_ulong sigtramp_page) {
>> +    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 2, 0);
>> +    assert(tramp != NULL);
>> +
>> +    default_rt_sigreturn = sigtramp_page;
>> +    install_sigtramp(tramp);
>> +
>> +    unlock_user(tramp, sigtramp_page, 4 * 2); }
> 
> Put the closing curly on a new line.

That's your mailer.  It's correct in the original.


r~


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

* Re: [PATCH 00/21] linux-user: Move signal trampolines to new page
  2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (20 preceding siblings ...)
  2021-06-16  1:12 ` [PATCH 21/21] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson
@ 2021-06-16 15:05 ` Alex Bennée
  2021-06-16 15:09   ` Richard Henderson
  21 siblings, 1 reply; 53+ messages in thread
From: Alex Bennée @ 2021-06-16 15:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent

Richard Henderson <richard.henderson@linaro.org> writes:

> It is my guess that the majority of the flakiness with the
> linux-user signals.c test is due to a race condition between
> translation and page writes.  I vaguely recall a bug report
> about this, but I cannot find it now.
>
> Since the vast majority of "self-modifying code" is due to
> signal delivery, work around this by allocating a new page,
> into which we write the signal handlers.
>
> A better workaround would be to implement the vdso that is
> required by many guests.  However, that is a much larger
> problem, and some guests do not define a vdso in upstream
> linux.  This serves as a decent fallback.
>
> Neither bit of work, I will note, solves the posited race
> condition described above.

Well this certainly solves the failures I was seeing with
s390x-on-s390x:

  retry.py -n 500 -c -- ./qemu-s390x ./tests/tcg/s390x-linux-user/signals
  Results summary:
  0: 500 times (100.00%), avg time 2.253 (0.00 varience/0.00 deviation)
  Ran command 500 times, 500 passes

However qemu-hppa (on x86_64 host) still has the stuborn 1% failure rate
(-static build):

  Results summary:
  0: 198 times (99.00%), avg time 2.255 (0.00 varience/0.00 deviation)
  -4: 2 times (1.00%), avg time 0.252 (0.00 varience/0.00 deviation)
  Ran command 200 times, 198 passes

So have a:

Tested-by: Alex Bennée <alex.bennee@linaro.org>
(for s390x at least)

-- 
Alex Bennée


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

* Re: [PATCH 00/21] linux-user: Move signal trampolines to new page
  2021-06-16 15:05 ` [PATCH 00/21] linux-user: Move signal trampolines to new page Alex Bennée
@ 2021-06-16 15:09   ` Richard Henderson
  0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16 15:09 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-devel, laurent

On 6/16/21 8:05 AM, Alex Bennée wrote:
> However qemu-hppa (on x86_64 host) still has the stuborn 1% failure rate...

Have a squizzle at patch 8.  I wasn't able to do anything with hppa yet.


r~


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

* Re: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
  2021-06-16 15:05     ` Richard Henderson
@ 2021-06-16 15:50       ` Richard Henderson
  2021-06-16 21:37         ` Taylor Simpson
  0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-06-16 15:50 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 8:05 AM, Richard Henderson wrote:
> On 6/16/21 1:07 AM, Taylor Simpson wrote:
>>> +    /*
>>> +     * The on-stack signal trampoline is no longer executed;
>>> +     * however, the libgcc signal frame unwinding code checks
>>> +     * for the presence of these two numeric magic values.
>>> +     */
>>
>> Hexagon uses musl, not libgcc.  So, I'm not sure if this is needed.  The signals.c test 
>> passes for me without this change.  Are you seeing it fail?
> 
> I copied the comment from the kernel source.

Also, I think you're confusing libc and libgcc.


r~


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

* Re: [PATCH 06/21] linux-user/cris: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 06/21] linux-user/cris: " Richard Henderson
@ 2021-06-16 16:37   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:37 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Edgar E . Iglesias, alex.bennee, laurent

On 6/16/21 3:11 AM, Richard Henderson wrote:
> Split out setup_sigreturn so that we can continue to
> initialize the words on the stack, as documented.
> However, use the off-stack trampoline.
> 
> Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/cris/target_signal.h |  2 ++
>  linux-user/cris/signal.c        | 29 +++++++++++++++++++++--------
>  2 files changed, 23 insertions(+), 8 deletions(-)

> +void setup_sigtramp(abi_ulong sigtramp_page)
> +{
> +    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 2, 0);

3 * 2?

> +    assert(tramp != NULL);
> +
> +    default_sigreturn = sigtramp_page;
> +    setup_sigreturn(tramp);
> +
> +    unlock_user(tramp, sigtramp_page, 4 * 2);

Ditto.

> +}
> 



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

* Re: [PATCH 10/21] linux-user/m68k: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 10/21] linux-user/m68k: " Richard Henderson
@ 2021-06-16 16:42   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:42 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 3:11 AM, Richard Henderson wrote:
> Create and record the two signal trampolines.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/m68k/target_signal.h |  2 ++
>  linux-user/m68k/signal.c        | 47 +++++++++++++++------------------
>  2 files changed, 24 insertions(+), 25 deletions(-)

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


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

* Re: [PATCH 11/21] linux-user/microblaze: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 11/21] linux-user/microblaze: " Richard Henderson
@ 2021-06-16 16:43   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:43 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Edgar E . Iglesias, alex.bennee, laurent

On 6/16/21 3:11 AM, Richard Henderson wrote:
> Create and record the rt signal trampoline.
> 
> Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/microblaze/target_signal.h |  2 ++
>  linux-user/microblaze/signal.c        | 24 +++++++++++++++++-------
>  2 files changed, 19 insertions(+), 7 deletions(-)

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


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

* Re: [PATCH 12/21] linux-user/mips: Implement setup_sigtramp
  2021-06-16  1:12 ` [PATCH 12/21] linux-user/mips: " Richard Henderson
@ 2021-06-16 16:48   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 3:12 AM, Richard Henderson wrote:
> Create and record the two signal trampolines.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/mips/target_signal.h   |  1 +
>  linux-user/mips64/target_signal.h |  2 ++
>  linux-user/mips/signal.c          | 39 ++++++++++++++++++++-----------
>  3 files changed, 28 insertions(+), 14 deletions(-)

> diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
> index e6be807a81..234f85905b 100644
> --- a/linux-user/mips/signal.c
> +++ b/linux-user/mips/signal.c
> @@ -86,10 +86,8 @@ struct target_rt_sigframe {
>  };
>  
>  /* Install trampoline to jump back from signal handler */
> -static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
> +static void install_sigtramp(unsigned int *tramp, unsigned int syscall)

Preferably modifying install_sigtramp() in previous patch,
changing tramp as uint32_t*:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

>  {
> -    int err = 0;
> -
>      /*
>       * Set up the return code ...
>       *
> @@ -99,7 +97,6 @@ static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
>  
>      __put_user(0x24020000 + syscall, tramp + 0);
>      __put_user(0x0000000c          , tramp + 1);
> -    return err;
>  }


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

* Re: [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp
  2021-06-16  1:12 ` [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
@ 2021-06-16 16:49   ` Philippe Mathieu-Daudé
  2021-06-17  0:24   ` Stafford Horne
  1 sibling, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:49 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Stafford Horne, alex.bennee, laurent

On 6/16/21 3:12 AM, Richard Henderson wrote:
> Create and record the rt signal trampoline.
> 
> Cc: Stafford Horne <shorne@gmail.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/openrisc/target_signal.h |  2 ++
>  linux-user/openrisc/signal.c        | 24 ++++++++++++++++--------
>  2 files changed, 18 insertions(+), 8 deletions(-)

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


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

* Re: [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
  2021-06-16  1:12   ` Richard Henderson
@ 2021-06-16 16:50     ` Philippe Mathieu-Daudé
  -1 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:50 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, qemu-riscv, laurent

On 6/16/21 3:12 AM, Richard Henderson wrote:
> Create and record the rt signal trampoline.
> 
> This fixes a bug wrt libgcc fallback unwinding.  It expects
> the stack pointer to point to the siginfo_t, whereas we had
> inexplicably placed our private signal trampoline at the start
> of the signal frame instead of the end.  Now moot because we
> have removed it from the stack frame entirely.
> 
> Cc: qemu-riscv@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/riscv/target_signal.h |  2 ++
>  linux-user/riscv/signal.c        | 22 +++++++++++++---------
>  2 files changed, 15 insertions(+), 9 deletions(-)

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


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

* Re: [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
@ 2021-06-16 16:50     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:50 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alex.bennee, laurent

On 6/16/21 3:12 AM, Richard Henderson wrote:
> Create and record the rt signal trampoline.
> 
> This fixes a bug wrt libgcc fallback unwinding.  It expects
> the stack pointer to point to the siginfo_t, whereas we had
> inexplicably placed our private signal trampoline at the start
> of the signal frame instead of the end.  Now moot because we
> have removed it from the stack frame entirely.
> 
> Cc: qemu-riscv@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/riscv/target_signal.h |  2 ++
>  linux-user/riscv/signal.c        | 22 +++++++++++++---------
>  2 files changed, 15 insertions(+), 9 deletions(-)

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


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

* Re: [PATCH 17/21] linux-user/s390x: Implement setup_sigtramp
  2021-06-16  1:12 ` [PATCH 17/21] linux-user/s390x: " Richard Henderson
@ 2021-06-16 16:52   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:52 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x, alex.bennee, laurent

On 6/16/21 3:12 AM, Richard Henderson wrote:
> Create and record the two signal trampolines.
> Use them when the guest does not use SA_RESTORER.
> 
> Cc: qemu-s390x@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/s390x/target_signal.h |  2 ++
>  linux-user/s390x/signal.c        | 24 ++++++++++++++++--------
>  2 files changed, 18 insertions(+), 8 deletions(-)

> +void setup_sigtramp(abi_ulong sigtramp_page)
> +{
> +    uint16_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4, 0);

4 -> 2 + 2 seems clearer (applies to some other targets in this series).

> +    assert(tramp != NULL);
> +
> +    default_sigreturn = sigtramp_page;
> +    __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, &tramp[0]);
> +
> +    default_rt_sigreturn = sigtramp_page + 2;
> +    __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, &tramp[1]);
> +
> +    unlock_user(tramp, sigtramp_page, 4);

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

> +}
> 



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

* Re: [PATCH 18/21] linux-user/sh4: Implement setup_sigtramp
  2021-06-16  1:12 ` [PATCH 18/21] linux-user/sh4: " Richard Henderson
@ 2021-06-16 16:53   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:53 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent, Yoshinori Sato

On 6/16/21 3:12 AM, Richard Henderson wrote:
> Create and record the two signal trampolines.
> Use them when the guest does not use SA_RESTORER.
> 
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/sh4/target_signal.h |  2 ++
>  linux-user/sh4/signal.c        | 40 +++++++++++++++++++---------------
>  2 files changed, 24 insertions(+), 18 deletions(-)

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


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

* Re: [PATCH 21/21] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE
  2021-06-16  1:12 ` [PATCH 21/21] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson
@ 2021-06-16 16:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:54 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 3:12 AM, Richard Henderson wrote:
> All targets now define TARGET_ARCH_HAS_SIGTRAMP_PAGE.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/elfload.c | 4 ----
>  1 file changed, 4 deletions(-)

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


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

* Re: [PATCH 05/21] linux-user/alpha: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 05/21] linux-user/alpha: " Richard Henderson
@ 2021-06-16 16:56   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 16:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 3:11 AM, Richard Henderson wrote:
> Create and record the two signal trampolines.
> Use them when the guest does not use ka_restorer.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/alpha/target_signal.h |  1 +
>  linux-user/alpha/signal.c        | 34 +++++++++++++++++++-------------
>  2 files changed, 21 insertions(+), 14 deletions(-)

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


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

* Re: [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp
  2021-06-16  1:11 ` [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
@ 2021-06-16 17:00   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 17:00 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-arm, laurent

On 6/16/21 3:11 AM, Richard Henderson wrote:
> Create and record the rt signal trampoline.
> Use it when the guest does not use SA_RESTORER.
> 
> Cc: qemu-arm@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/aarch64/target_signal.h |  2 ++
>  linux-user/aarch64/signal.c        | 28 ++++++++++++++++++----------
>  2 files changed, 20 insertions(+), 10 deletions(-)

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


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

* Re: [PATCH 03/21] linux-user/arm: Force v2 frames for fdpic
  2021-06-16  1:11 ` [PATCH 03/21] linux-user/arm: Force v2 frames for fdpic Richard Henderson
@ 2021-06-16 17:01   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-16 17:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-arm, laurent

Hi Richard,

On 6/16/21 3:11 AM, Richard Henderson wrote:
> The value of get_os_release may be controlled by a command
> line option.  Since fdpic was added in v4.14, and v2 frame
> were added in v2.6.12, this makes no change under normal conditions.
> 
> Split out a helper function to perform the test.
> 
> Cc: qemu-arm@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/arm/signal.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
> index 32b68ee302..2d30345fc2 100644
> --- a/linux-user/arm/signal.c
> +++ b/linux-user/arm/signal.c
> @@ -165,6 +165,18 @@ static inline int valid_user_regs(CPUARMState *regs)
>      return 1;
>  }
>  
> +static bool v2_frame(void)
> +{
> +    /*
> +     * We do not create fdpic trampolines for v1 frames.
> +     * Thus we force v2 frames, regardless of what uname says.
> +     * Support for fdpic dates from Linux 4.14, so this is not
> +     * really a behaviour change.
> +     */
> +    int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
> +    return is_fdpic || get_osversion() >= 0x020612;
> +}

Could you refactor v2_frame() in a previous patch and add the
is_fdpic check in another one please?


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

* Re: [PATCH 04/21] linux-user/arm: Implement setup_sigtramp
  2021-06-16 13:49     ` Alex Bennée
@ 2021-06-16 17:40       ` Richard Henderson
  0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16 17:40 UTC (permalink / raw)
  To: Alex Bennée; +Cc: qemu-arm, qemu-devel, laurent

On 6/16/21 6:49 AM, Alex Bennée wrote:
>    ../../linux-user/arm/signal.c: In function ‘setup_sigtramp’:
>    ../../linux-user/arm/signal.c:847:47: error: expected ‘,’ before ‘)’ token
>         _Static_assert(SIGFRAME_FDPIC_OFS <= 0xfff);

Heh.  Apparently, _Static_assert with no message parameter is a further extension, present 
in c17 but not c11.  I presume it's enabled with gnu11 on my compiler version, but not yours.

I'll change to use QEMU_BUILD_BUG_ON, and give up on removing that macro for a while.


r~


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

* Re: [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp
  2021-06-16  1:11 ` [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
  2021-06-16 10:46   ` Philippe Mathieu-Daudé
@ 2021-06-16 21:16   ` Alex Bennée
  1 sibling, 0 replies; 53+ messages in thread
From: Alex Bennée @ 2021-06-16 21:16 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent


Richard Henderson <richard.henderson@linaro.org> writes:

> We cannot use a raw sigtramp page for hppa,
> but must wait for full vdso support.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  linux-user/hppa/target_signal.h | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/linux-user/hppa/target_signal.h b/linux-user/hppa/target_signal.h
> index 7f525362e9..d558119ee7 100644
> --- a/linux-user/hppa/target_signal.h
> +++ b/linux-user/hppa/target_signal.h
> @@ -71,4 +71,18 @@ typedef struct target_sigaltstack {
>  /* mask for all SS_xxx flags */
>  #define TARGET_SS_FLAG_BITS  TARGET_SS_AUTODISARM
>  
> +/*
> + * We cannot use a bare sigtramp page for hppa-linux.
> + *
> + * Unlike other guests where we use the instructions at PC to validate
> + * an offset from SP, the hppa libgcc signal frame fallback unwinding uses
> + * the PC address itself to find the frame.  This is due to the fact that
> + * the hppa grows the stack upward, and the frame is of unknown size.
> + *
> + * TODO: We should be able to use a VDSO to address this, by providing
> + * proper unwind info for the sigtramp code, at which point the fallback
> + * unwinder will not be used.
> + */
> +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
> +
>  #endif /* HPPA_TARGET_SIGNAL_H */


-- 
Alex Bennée


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

* RE: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
  2021-06-16 15:50       ` Richard Henderson
@ 2021-06-16 21:37         ` Taylor Simpson
  2021-06-16 23:15           ` Richard Henderson
  0 siblings, 1 reply; 53+ messages in thread
From: Taylor Simpson @ 2021-06-16 21:37 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent



> -----Original Message-----
> From: Richard Henderson <richard.henderson@linaro.org>
> Sent: Wednesday, June 16, 2021 9:51 AM
> To: Taylor Simpson <tsimpson@quicinc.com>; qemu-devel@nongnu.org
> Cc: laurent@vivier.eu; alex.bennee@linaro.org
> Subject: Re: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
> 
> On 6/16/21 8:05 AM, Richard Henderson wrote:
> > On 6/16/21 1:07 AM, Taylor Simpson wrote:
> >>> +    /*
> >>> +     * The on-stack signal trampoline is no longer executed;
> >>> +     * however, the libgcc signal frame unwinding code checks
> >>> +     * for the presence of these two numeric magic values.
> >>> +     */
> >>
> >> Hexagon uses musl, not libgcc.  So, I'm not sure if this is needed.
> >> The signals.c test passes for me without this change.  Are you seeing it
> fail?
> >
> > I copied the comment from the kernel source.
> 
> Also, I think you're confusing libc and libgcc.

Yes, I'm confused.  Why is signal frame unwinding in libgcc?

Also FWIW, we use LLVM's compiler-rt instead of libgcc.

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

* Re: [PATCH 07/21] linux-user/hexagon: Implement setup_sigtramp
  2021-06-16 21:37         ` Taylor Simpson
@ 2021-06-16 23:15           ` Richard Henderson
  0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-16 23:15 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel; +Cc: alex.bennee, laurent

On 6/16/21 2:37 PM, Taylor Simpson wrote:
> Yes, I'm confused.  Why is signal frame unwinding in libgcc?

Because it's tied to the compiler, and it was a decent solution back in 1997.

I see llvm calls it libunwind, and only has special signal frame support for aarch64.  I 
wonder if ever other target is expecting unwind info in a vdso?


r~


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

* Re: [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp
  2021-06-16  1:12 ` [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
  2021-06-16 16:49   ` Philippe Mathieu-Daudé
@ 2021-06-17  0:24   ` Stafford Horne
  1 sibling, 0 replies; 53+ messages in thread
From: Stafford Horne @ 2021-06-17  0:24 UTC (permalink / raw)
  To: Richard Henderson; +Cc: alex.bennee, qemu-devel, laurent

On Tue, Jun 15, 2021 at 06:12:02PM -0700, Richard Henderson wrote:
> Create and record the rt signal trampoline.
> 
> Cc: Stafford Horne <shorne@gmail.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Stafford Horne <shorne@gmail.com>

> ---
>  linux-user/openrisc/target_signal.h |  2 ++
>  linux-user/openrisc/signal.c        | 24 ++++++++++++++++--------
>  2 files changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/linux-user/openrisc/target_signal.h b/linux-user/openrisc/target_signal.h
> index 8283eaf544..077ec3d5e8 100644
> --- a/linux-user/openrisc/target_signal.h
> +++ b/linux-user/openrisc/target_signal.h
> @@ -26,4 +26,6 @@ typedef struct target_sigaltstack {
>  
>  #include "../generic/signal.h"
>  
> +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
> +
>  #endif /* OPENRISC_TARGET_SIGNAL_H */
> diff --git a/linux-user/openrisc/signal.c b/linux-user/openrisc/signal.c
> index 5c5640a284..b411b01864 100644
> --- a/linux-user/openrisc/signal.c
> +++ b/linux-user/openrisc/signal.c
> @@ -37,7 +37,6 @@ typedef struct target_ucontext {
>  typedef struct target_rt_sigframe {
>      struct target_siginfo info;
>      target_ucontext uc;
> -    uint32_t retcode[4];  /* trampoline code */
>  } target_rt_sigframe;
>  
>  static void restore_sigcontext(CPUOpenRISCState *env, target_sigcontext *sc)
> @@ -115,14 +114,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
>          __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
>      }
>  
> -    /* This is l.ori r11,r0,__NR_sigreturn; l.sys 1; l.nop; l.nop */
> -    __put_user(0xa9600000 | TARGET_NR_rt_sigreturn, frame->retcode + 0);
> -    __put_user(0x20000001, frame->retcode + 1);
> -    __put_user(0x15000000, frame->retcode + 2);
> -    __put_user(0x15000000, frame->retcode + 3);
> -
>      /* Set up registers for signal handler */
> -    cpu_set_gpr(env, 9, frame_addr + offsetof(target_rt_sigframe, retcode));
> +    cpu_set_gpr(env, 9, default_rt_sigreturn);
>      cpu_set_gpr(env, 3, sig);
>      cpu_set_gpr(env, 4, frame_addr + offsetof(target_rt_sigframe, info));
>      cpu_set_gpr(env, 5, frame_addr + offsetof(target_rt_sigframe, uc));
> @@ -168,3 +161,18 @@ long do_rt_sigreturn(CPUOpenRISCState *env)
>      force_sig(TARGET_SIGSEGV);
>      return 0;
>  }
> +
> +void setup_sigtramp(abi_ulong sigtramp_page)
> +{
> +    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 4, 0);
> +    assert(tramp != NULL);
> +
> +    /* This is l.ori r11,r0,__NR_sigreturn; l.sys 1; l.nop; l.nop */
> +    __put_user(0xa9600000 | TARGET_NR_rt_sigreturn, tramp + 0);
> +    __put_user(0x20000001, tramp + 1);
> +    __put_user(0x15000000, tramp + 2);
> +    __put_user(0x15000000, tramp + 3);
> +
> +    default_rt_sigreturn = sigtramp_page;
> +    unlock_user(tramp, sigtramp_page, 4 * 4);
> +}
> -- 
> 2.25.1
> 


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

* Re: [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
  2021-06-16  1:12   ` Richard Henderson
@ 2021-06-18  1:29     ` Alistair Francis
  -1 siblings, 0 replies; 53+ messages in thread
From: Alistair Francis @ 2021-06-18  1:29 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Alex Bennée, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Laurent Vivier

On Wed, Jun 16, 2021 at 11:22 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Create and record the rt signal trampoline.
>
> This fixes a bug wrt libgcc fallback unwinding.  It expects
> the stack pointer to point to the siginfo_t, whereas we had
> inexplicably placed our private signal trampoline at the start
> of the signal frame instead of the end.  Now moot because we
> have removed it from the stack frame entirely.
>
> Cc: qemu-riscv@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  linux-user/riscv/target_signal.h |  2 ++
>  linux-user/riscv/signal.c        | 22 +++++++++++++---------
>  2 files changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h
> index f113ba9a55..3e36fddc9d 100644
> --- a/linux-user/riscv/target_signal.h
> +++ b/linux-user/riscv/target_signal.h
> @@ -15,4 +15,6 @@ typedef struct target_sigaltstack {
>
>  #include "../generic/signal.h"
>
> +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
> +
>  #endif /* RISCV_TARGET_SIGNAL_H */
> diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
> index 9405c7fd9a..4086dfa5d5 100644
> --- a/linux-user/riscv/signal.c
> +++ b/linux-user/riscv/signal.c
> @@ -46,7 +46,6 @@ struct target_ucontext {
>  };
>
>  struct target_rt_sigframe {
> -    uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */
>      struct target_siginfo info;
>      struct target_ucontext uc;
>  };
> @@ -104,12 +103,6 @@ static void setup_ucontext(struct target_ucontext *uc,
>      setup_sigcontext(&uc->uc_mcontext, env);
>  }
>
> -static inline void install_sigtramp(uint32_t *tramp)
> -{
> -    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
> -    __put_user(0x00000073, tramp + 1);  /* ecall */
> -}
> -
>  void setup_rt_frame(int sig, struct target_sigaction *ka,
>                      target_siginfo_t *info,
>                      target_sigset_t *set, CPURISCVState *env)
> @@ -126,14 +119,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
>
>      setup_ucontext(&frame->uc, env, set);
>      tswap_siginfo(&frame->info, info);
> -    install_sigtramp(frame->tramp);
>
>      env->pc = ka->_sa_handler;
>      env->gpr[xSP] = frame_addr;
>      env->gpr[xA0] = sig;
>      env->gpr[xA1] = frame_addr + offsetof(struct target_rt_sigframe, info);
>      env->gpr[xA2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
> -    env->gpr[xRA] = frame_addr + offsetof(struct target_rt_sigframe, tramp);
> +    env->gpr[xRA] = default_rt_sigreturn;
>
>      return;
>
> @@ -202,3 +194,15 @@ badframe:
>      force_sig(TARGET_SIGSEGV);
>      return 0;
>  }
> +
> +void setup_sigtramp(abi_ulong sigtramp_page)
> +{
> +    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
> +    assert(tramp != NULL);
> +
> +    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
> +    __put_user(0x00000073, tramp + 1);  /* ecall */
> +
> +    default_rt_sigreturn = sigtramp_page;
> +    unlock_user(tramp, sigtramp_page, 8);
> +}
> --
> 2.25.1
>
>


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

* Re: [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
@ 2021-06-18  1:29     ` Alistair Francis
  0 siblings, 0 replies; 53+ messages in thread
From: Alistair Francis @ 2021-06-18  1:29 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
	Alex Bennée, Laurent Vivier

On Wed, Jun 16, 2021 at 11:22 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Create and record the rt signal trampoline.
>
> This fixes a bug wrt libgcc fallback unwinding.  It expects
> the stack pointer to point to the siginfo_t, whereas we had
> inexplicably placed our private signal trampoline at the start
> of the signal frame instead of the end.  Now moot because we
> have removed it from the stack frame entirely.
>
> Cc: qemu-riscv@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  linux-user/riscv/target_signal.h |  2 ++
>  linux-user/riscv/signal.c        | 22 +++++++++++++---------
>  2 files changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h
> index f113ba9a55..3e36fddc9d 100644
> --- a/linux-user/riscv/target_signal.h
> +++ b/linux-user/riscv/target_signal.h
> @@ -15,4 +15,6 @@ typedef struct target_sigaltstack {
>
>  #include "../generic/signal.h"
>
> +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
> +
>  #endif /* RISCV_TARGET_SIGNAL_H */
> diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
> index 9405c7fd9a..4086dfa5d5 100644
> --- a/linux-user/riscv/signal.c
> +++ b/linux-user/riscv/signal.c
> @@ -46,7 +46,6 @@ struct target_ucontext {
>  };
>
>  struct target_rt_sigframe {
> -    uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */
>      struct target_siginfo info;
>      struct target_ucontext uc;
>  };
> @@ -104,12 +103,6 @@ static void setup_ucontext(struct target_ucontext *uc,
>      setup_sigcontext(&uc->uc_mcontext, env);
>  }
>
> -static inline void install_sigtramp(uint32_t *tramp)
> -{
> -    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
> -    __put_user(0x00000073, tramp + 1);  /* ecall */
> -}
> -
>  void setup_rt_frame(int sig, struct target_sigaction *ka,
>                      target_siginfo_t *info,
>                      target_sigset_t *set, CPURISCVState *env)
> @@ -126,14 +119,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
>
>      setup_ucontext(&frame->uc, env, set);
>      tswap_siginfo(&frame->info, info);
> -    install_sigtramp(frame->tramp);
>
>      env->pc = ka->_sa_handler;
>      env->gpr[xSP] = frame_addr;
>      env->gpr[xA0] = sig;
>      env->gpr[xA1] = frame_addr + offsetof(struct target_rt_sigframe, info);
>      env->gpr[xA2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
> -    env->gpr[xRA] = frame_addr + offsetof(struct target_rt_sigframe, tramp);
> +    env->gpr[xRA] = default_rt_sigreturn;
>
>      return;
>
> @@ -202,3 +194,15 @@ badframe:
>      force_sig(TARGET_SIGSEGV);
>      return 0;
>  }
> +
> +void setup_sigtramp(abi_ulong sigtramp_page)
> +{
> +    uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
> +    assert(tramp != NULL);
> +
> +    __put_user(0x08b00893, tramp + 0);  /* li a7, 139 = __NR_rt_sigreturn */
> +    __put_user(0x00000073, tramp + 1);  /* ecall */
> +
> +    default_rt_sigreturn = sigtramp_page;
> +    unlock_user(tramp, sigtramp_page, 8);
> +}
> --
> 2.25.1
>
>


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

end of thread, other threads:[~2021-06-18  1:32 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-16  1:11 [PATCH 00/21] linux-user: Move signal trampolines to new page Richard Henderson
2021-06-16  1:11 ` [PATCH 01/21] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
2021-06-16 13:36   ` Max Filippov
2021-06-16  1:11 ` [PATCH 02/21] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
2021-06-16 17:00   ` Philippe Mathieu-Daudé
2021-06-16  1:11 ` [PATCH 03/21] linux-user/arm: Force v2 frames for fdpic Richard Henderson
2021-06-16 17:01   ` Philippe Mathieu-Daudé
2021-06-16  1:11 ` [PATCH 04/21] linux-user/arm: Implement setup_sigtramp Richard Henderson
2021-06-16 13:46   ` Alex Bennée
2021-06-16 13:49     ` Alex Bennée
2021-06-16 17:40       ` Richard Henderson
2021-06-16  1:11 ` [PATCH 05/21] linux-user/alpha: " Richard Henderson
2021-06-16 16:56   ` Philippe Mathieu-Daudé
2021-06-16  1:11 ` [PATCH 06/21] linux-user/cris: " Richard Henderson
2021-06-16 16:37   ` Philippe Mathieu-Daudé
2021-06-16  1:11 ` [PATCH 07/21] linux-user/hexagon: " Richard Henderson
2021-06-16  8:07   ` Taylor Simpson
2021-06-16 15:05     ` Richard Henderson
2021-06-16 15:50       ` Richard Henderson
2021-06-16 21:37         ` Taylor Simpson
2021-06-16 23:15           ` Richard Henderson
2021-06-16  1:11 ` [PATCH 08/21] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
2021-06-16 10:46   ` Philippe Mathieu-Daudé
2021-06-16 21:16   ` Alex Bennée
2021-06-16  1:11 ` [PATCH 09/21] linux-user/i386: Implement setup_sigtramp Richard Henderson
2021-06-16  1:11 ` [PATCH 10/21] linux-user/m68k: " Richard Henderson
2021-06-16 16:42   ` Philippe Mathieu-Daudé
2021-06-16  1:11 ` [PATCH 11/21] linux-user/microblaze: " Richard Henderson
2021-06-16 16:43   ` Philippe Mathieu-Daudé
2021-06-16  1:12 ` [PATCH 12/21] linux-user/mips: " Richard Henderson
2021-06-16 16:48   ` Philippe Mathieu-Daudé
2021-06-16  1:12 ` [PATCH 13/21] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
2021-06-16  1:12 ` [PATCH 14/21] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
2021-06-16 16:49   ` Philippe Mathieu-Daudé
2021-06-17  0:24   ` Stafford Horne
2021-06-16  1:12 ` [PATCH 15/21] linux-user/ppc: " Richard Henderson
2021-06-16  1:12 ` [PATCH 16/21] linux-user/riscv: " Richard Henderson
2021-06-16  1:12   ` Richard Henderson
2021-06-16 16:50   ` Philippe Mathieu-Daudé
2021-06-16 16:50     ` Philippe Mathieu-Daudé
2021-06-18  1:29   ` Alistair Francis
2021-06-18  1:29     ` Alistair Francis
2021-06-16  1:12 ` [PATCH 17/21] linux-user/s390x: " Richard Henderson
2021-06-16 16:52   ` Philippe Mathieu-Daudé
2021-06-16  1:12 ` [PATCH 18/21] linux-user/sh4: " Richard Henderson
2021-06-16 16:53   ` Philippe Mathieu-Daudé
2021-06-16  1:12 ` [PATCH 19/21] linux-user/sparc: " Richard Henderson
2021-06-16  1:12 ` [PATCH 20/21] linux-user/xtensa: " Richard Henderson
2021-06-16 13:35   ` Max Filippov
2021-06-16  1:12 ` [PATCH 21/21] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson
2021-06-16 16:54   ` Philippe Mathieu-Daudé
2021-06-16 15:05 ` [PATCH 00/21] linux-user: Move signal trampolines to new page Alex Bennée
2021-06-16 15:09   ` Richard Henderson

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