qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/23] linux-user: Move signal trampolines to new page
@ 2021-06-18 19:29 Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
                   ` (22 more replies)
  0 siblings, 23 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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.

Changes for v2:
  * Add r-b tags
  * Split arm v2_frame patch (phil)
  * Split mips install_sigtramp patch (phil)
  * Fix some arithmetic in a couple of setup_sigtramp (phil)


r~


Richard Henderson (23):
  linux-user: Add infrastructure for a signal trampoline page
  linux-user/aarch64: Implement setup_sigtramp
  linux-user/arm: Split out v2_frame
  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: Tidy install_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] 43+ messages in thread

* [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-19  9:33   ` Philippe Mathieu-Daudé
  2021-06-29 13:30   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
                   ` (21 subsequent siblings)
  22 siblings, 2 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Filippov, 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.

Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
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] 43+ messages in thread

* [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-29 13:36   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 03/23] linux-user/arm: Split out v2_frame Richard Henderson
                   ` (20 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-arm, alex.bennee, laurent, Philippe Mathieu-Daudé

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

Cc: qemu-arm@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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] 43+ messages in thread

* [PATCH v2 03/23] linux-user/arm: Split out v2_frame
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-29 13:53   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 04/23] linux-user/arm: Force v2 frames for fdpic Richard Henderson
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-arm, alex.bennee, laurent

Split out a helper function to test for a v2 signal frame.

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

diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index 32b68ee302..cb65623965 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -165,6 +165,11 @@ static inline int valid_user_regs(CPUARMState *regs)
     return 1;
 }
 
+static bool v2_frame(void)
+{
+    return get_osversion() >= 0x020612;
+}
+
 static void
 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
                  CPUARMState *env, abi_ulong mask)
@@ -422,7 +427,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 +521,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 +739,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 +828,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] 43+ messages in thread

* [PATCH v2 04/23] linux-user/arm: Force v2 frames for fdpic
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (2 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 03/23] linux-user/arm: Split out v2_frame Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-29 13:54   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp Richard Henderson
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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.

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

diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index cb65623965..2d30345fc2 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -167,7 +167,14 @@ static inline int valid_user_regs(CPUARMState *regs)
 
 static bool v2_frame(void)
 {
-    return get_osversion() >= 0x020612;
+    /*
+     * 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
-- 
2.25.1



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

* [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (3 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 04/23] linux-user/arm: Force v2 frames for fdpic Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-29 14:09   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 06/23] linux-user/alpha: " Richard Henderson
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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..63bdd59ab9 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 */
+    QEMU_BUILD_BUG_ON(SIGFRAME_FDPIC_OFS > 0xfff);
+    __put_user(0xe59d9000 | SIGFRAME_FDPIC_OFS, &tramp[i++]);
+    __put_user(0xe8998200, &tramp[i++]);
+
+    /* Thumb sigframe */
+    QEMU_BUILD_BUG_ON(SIGFRAME_FDPIC_OFS > 0xff << 2);
+    QEMU_BUILD_BUG_ON(SIGFRAME_FDPIC_OFS & 3);
+    __put_user(0x9a00e9dd | (SIGFRAME_FDPIC_OFS << 14), &tramp[i++]);
+    __put_user(0x46c04750, &tramp[i++]);
+
+    /* ARM rt_sigframe */
+    QEMU_BUILD_BUG_ON(RT_SIGFRAME_FDPIC_OFS > 0xfff);
+    __put_user(0xe59d9000 | RT_SIGFRAME_FDPIC_OFS, &tramp[i++]);
+    __put_user(0xe8998200, &tramp[i++]);
+
+    /* Thumb rt_sigframe */
+    QEMU_BUILD_BUG_ON(RT_SIGFRAME_FDPIC_OFS > 0xff << 2);
+    QEMU_BUILD_BUG_ON(RT_SIGFRAME_FDPIC_OFS & 3);
+    __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] 43+ messages in thread

* [PATCH v2 06/23] linux-user/alpha: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (4 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 07/23] linux-user/cris: " Richard Henderson
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Philippe Mathieu-Daudé

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

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* [PATCH v2 07/23] linux-user/cris: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (5 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 06/23] linux-user/alpha: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-19  9:33   ` Philippe Mathieu-Daudé
  2021-06-18 19:29 ` [PATCH v2 08/23] linux-user/hexagon: " Richard Henderson
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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..9dad50f31f 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, 6, 0);
+    assert(tramp != NULL);
+
+    default_sigreturn = sigtramp_page;
+    setup_sigreturn(tramp);
+
+    unlock_user(tramp, sigtramp_page, 6);
+}
-- 
2.25.1



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

* [PATCH v2 08/23] linux-user/hexagon: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (6 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 07/23] linux-user/cris: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-19  9:31   ` Philippe Mathieu-Daudé
  2021-06-18 19:29 ` [PATCH v2 09/23] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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] 43+ messages in thread

* [PATCH v2 09/23] linux-user/hppa: Document non-use of setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (7 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 08/23] linux-user/hexagon: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp Richard Henderson
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Philippe Mathieu-Daudé

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

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (8 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 09/23] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-29 14:40   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 11/23] linux-user/m68k: " Richard Henderson
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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] 43+ messages in thread

* [PATCH v2 11/23] linux-user/m68k: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (9 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 12/23] linux-user/microblaze: " Richard Henderson
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Philippe Mathieu-Daudé

Create and record the two signal trampolines.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* [PATCH v2 12/23] linux-user/microblaze: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (10 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 11/23] linux-user/m68k: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 13/23] linux-user/mips: Tidy install_sigtramp Richard Henderson
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Edgar E . Iglesias, alex.bennee, laurent, Philippe Mathieu-Daudé

Create and record the rt signal trampoline.

Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* [PATCH v2 13/23] linux-user/mips: Tidy install_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (11 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 12/23] linux-user/microblaze: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-19  9:29   ` Philippe Mathieu-Daudé
  2021-06-18 19:29 ` [PATCH v2 14/23] linux-user/mips: Implement setup_sigtramp Richard Henderson
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent

The return value is constant 0, and unused as well -- change to void.
Drop inline marker.  Change tramp type to uint32_t* for clarity.

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

diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index e6be807a81..7cad7526ea 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(uint32_t *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,
-- 
2.25.1



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

* [PATCH v2 14/23] linux-user/mips: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (12 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 13/23] linux-user/mips: Tidy install_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 15/23] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Philippe Mathieu-Daudé

Create and record the two signal trampolines.

Reviewed-by: 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          | 34 ++++++++++++++++++++++---------
 3 files changed, 27 insertions(+), 10 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 7cad7526ea..a3db08bfec 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -208,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++) {
@@ -230,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 */
@@ -304,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);
@@ -334,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);
@@ -378,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] 43+ messages in thread

* [PATCH v2 15/23] linux-user/nios2: Document non-use of setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (13 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 14/23] linux-user/mips: Implement setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-19  9:35   ` Philippe Mathieu-Daudé
  2021-06-18 19:29 ` [PATCH v2 16/23] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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] 43+ messages in thread

* [PATCH v2 16/23] linux-user/openrisc: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (14 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 15/23] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 17/23] linux-user/ppc: " Richard Henderson
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stafford Horne, alex.bennee, laurent, Philippe Mathieu-Daudé

Create and record the rt signal trampoline.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* [PATCH v2 17/23] linux-user/ppc: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (15 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 16/23] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-29 14:52   ` Peter Maydell
  2021-06-18 19:29 ` [PATCH v2 18/23] linux-user/riscv: " Richard Henderson
                   ` (5 subsequent siblings)
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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] 43+ messages in thread

* [PATCH v2 18/23] linux-user/riscv: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (16 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 17/23] linux-user/ppc: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 19/23] linux-user/s390x: " Richard Henderson
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alistair Francis, alex.bennee, laurent, Philippe Mathieu-Daudé

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.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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] 43+ messages in thread

* [PATCH v2 19/23] linux-user/s390x: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (17 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 18/23] linux-user/riscv: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 20/23] linux-user/sh4: " Richard Henderson
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, alex.bennee, laurent, Philippe Mathieu-Daudé

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

Cc: qemu-s390x@nongnu.org
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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..372861d6d8 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, 2 + 2, 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, 2 + 2);
+}
-- 
2.25.1



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

* [PATCH v2 20/23] linux-user/sh4: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (18 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 19/23] linux-user/s390x: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 21/23] linux-user/sparc: " Richard Henderson
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, laurent, Yoshinori Sato, Philippe Mathieu-Daudé

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

Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* [PATCH v2 21/23] linux-user/sparc: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (19 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 20/23] linux-user/sh4: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-07-02  9:05   ` Philippe Mathieu-Daudé
  2021-06-18 19:29 ` [PATCH v2 22/23] linux-user/xtensa: " Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 23/23] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson
  22 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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] 43+ messages in thread

* [PATCH v2 22/23] linux-user/xtensa: Implement setup_sigtramp
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (20 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 21/23] linux-user/sparc: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  2021-06-18 19:29 ` [PATCH v2 23/23] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 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.

Reviewed-by: 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] 43+ messages in thread

* [PATCH v2 23/23] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE
  2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
                   ` (21 preceding siblings ...)
  2021-06-18 19:29 ` [PATCH v2 22/23] linux-user/xtensa: " Richard Henderson
@ 2021-06-18 19:29 ` Richard Henderson
  22 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-18 19:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, laurent, Philippe Mathieu-Daudé

All targets now define TARGET_ARCH_HAS_SIGTRAMP_PAGE.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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] 43+ messages in thread

* Re: [PATCH v2 13/23] linux-user/mips: Tidy install_sigtramp
  2021-06-18 19:29 ` [PATCH v2 13/23] linux-user/mips: Tidy install_sigtramp Richard Henderson
@ 2021-06-19  9:29   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, laurent

On 6/18/21 9:29 PM, Richard Henderson wrote:
> The return value is constant 0, and unused as well -- change to void.
> Drop inline marker.  Change tramp type to uint32_t* for clarity.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/mips/signal.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)

Thanks :)

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


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

* Re: [PATCH v2 08/23] linux-user/hexagon: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 08/23] linux-user/hexagon: " Richard Henderson
@ 2021-06-19  9:31   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Taylor Simpson, alex.bennee, laurent

On 6/18/21 9:29 PM, Richard Henderson wrote:
> 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(-)

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


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

* Re: [PATCH v2 07/23] linux-user/cris: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 07/23] linux-user/cris: " Richard Henderson
@ 2021-06-19  9:33   ` Philippe Mathieu-Daudé
  2021-06-19 12:55     ` Richard Henderson
  0 siblings, 1 reply; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Edgar E . Iglesias, alex.bennee, laurent

On 6/18/21 9:29 PM, 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(-)

Nitpicking, 6 -> 3 * 2? :)

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


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

* Re: [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page
  2021-06-18 19:29 ` [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
@ 2021-06-19  9:33   ` Philippe Mathieu-Daudé
  2021-06-29 13:30   ` Peter Maydell
  1 sibling, 0 replies; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Max Filippov, alex.bennee, laurent

On 6/18/21 9:29 PM, Richard Henderson 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.
> 
> Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
> 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: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 15/23] linux-user/nios2: Document non-use of setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 15/23] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
@ 2021-06-19  9:35   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19  9:35 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Marek Vasut, Chris Wulff, alex.bennee, laurent

On 6/18/21 9:29 PM, Richard Henderson wrote:
> 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(+)

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


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

* Re: [PATCH v2 07/23] linux-user/cris: Implement setup_sigtramp
  2021-06-19  9:33   ` Philippe Mathieu-Daudé
@ 2021-06-19 12:55     ` Richard Henderson
  2021-06-19 14:17       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 43+ messages in thread
From: Richard Henderson @ 2021-06-19 12:55 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Edgar E . Iglesias, alex.bennee, laurent

On 6/19/21 2:33 AM, Philippe Mathieu-Daudé wrote:
> On 6/18/21 9:29 PM, 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(-)
> 
> Nitpicking, 6 -> 3 * 2? :)

Elsewhere I have used <bytes-per-tramp> * 2 if we have two trampolines, not 
<bytes-per-insn> * <n-insns>.

r~

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



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

* Re: [PATCH v2 07/23] linux-user/cris: Implement setup_sigtramp
  2021-06-19 12:55     ` Richard Henderson
@ 2021-06-19 14:17       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19 14:17 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Edgar E . Iglesias, alex.bennee, laurent

On 6/19/21 2:55 PM, Richard Henderson wrote:
> On 6/19/21 2:33 AM, Philippe Mathieu-Daudé wrote:
>> On 6/18/21 9:29 PM, 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(-)
>>
>> Nitpicking, 6 -> 3 * 2? :)
> 
> Elsewhere I have used <bytes-per-tramp> * 2 if we have two trampolines,
> not <bytes-per-insn> * <n-insns>.

Oh, OK :)

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


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

* Re: [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page
  2021-06-18 19:29 ` [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
  2021-06-19  9:33   ` Philippe Mathieu-Daudé
@ 2021-06-29 13:30   ` Peter Maydell
  1 sibling, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 13:30 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Max Filippov, Alex Bennée, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:32, 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.
>
> Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
> 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: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
@ 2021-06-29 13:36   ` Peter Maydell
  2021-07-01 19:27     ` Richard Henderson
  0 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 13:36 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Philippe Mathieu-Daudé, qemu-arm, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:33, 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: qemu-arm@nongnu.org
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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,


A little way up from here there's a comment:

    /* Reserve space for the return code.  On a real system this would
     * be within the VDSO.  So, despite the name this is not a "real"
     * record within the frame.
     */
    fr_ofs = layout.total_size;
    layout.total_size += sizeof(struct target_rt_frame_record);

That now needs updating, because we're no longer putting the return
code in that target_rt_frame_record.

I think the 'struct target_rt_frame_record' now does correspond
to the kernel's 'struct frame_record', right?

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

thanks
-- PMM


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

* Re: [PATCH v2 03/23] linux-user/arm: Split out v2_frame
  2021-06-18 19:29 ` [PATCH v2 03/23] linux-user/arm: Split out v2_frame Richard Henderson
@ 2021-06-29 13:53   ` Peter Maydell
  2021-06-29 14:30     ` Richard Henderson
  0 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 13:53 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-arm, Alex Bennée, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:32, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Split out a helper function to test for a v2 signal frame.
>
> Cc: qemu-arm@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/arm/signal.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
> index 32b68ee302..cb65623965 100644
> --- a/linux-user/arm/signal.c
> +++ b/linux-user/arm/signal.c
> @@ -165,6 +165,11 @@ static inline int valid_user_regs(CPUARMState *regs)
>      return 1;
>  }
>
> +static bool v2_frame(void)
> +{
> +    return get_osversion() >= 0x020612;
> +}

Not sure how much we care about supporting claiming to be a 15-year-old
kernel any more (especially since we set UNAME_MINIMUM_RELEASE to 2.6.32...)
so it's awfully tempting to just blow away the v1 frame support instead...

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

thanks
-- PMM


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

* Re: [PATCH v2 04/23] linux-user/arm: Force v2 frames for fdpic
  2021-06-18 19:29 ` [PATCH v2 04/23] linux-user/arm: Force v2 frames for fdpic Richard Henderson
@ 2021-06-29 13:54   ` Peter Maydell
  0 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 13:54 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-arm, Alex Bennée, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:32, Richard Henderson
<richard.henderson@linaro.org> 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.
>
> Cc: qemu-arm@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

thanks
-- PMM


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

* Re: [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp Richard Henderson
@ 2021-06-29 14:09   ` Peter Maydell
  2021-06-29 18:32     ` Richard Henderson
  0 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 14:09 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:33, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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(-)

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

though I'm not 100% confident I checked all the details. Do you have
test programs that checked all the different trampolines ?

thanks
-- PMM


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

* Re: [PATCH v2 03/23] linux-user/arm: Split out v2_frame
  2021-06-29 13:53   ` Peter Maydell
@ 2021-06-29 14:30     ` Richard Henderson
  0 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-29 14:30 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, Alex Bennée, QEMU Developers, Laurent Vivier

On 6/29/21 6:53 AM, Peter Maydell wrote:
> On Fri, 18 Jun 2021 at 20:32, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Split out a helper function to test for a v2 signal frame.
>>
>> Cc: qemu-arm@nongnu.org
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   linux-user/arm/signal.c | 13 +++++++++----
>>   1 file changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
>> index 32b68ee302..cb65623965 100644
>> --- a/linux-user/arm/signal.c
>> +++ b/linux-user/arm/signal.c
>> @@ -165,6 +165,11 @@ static inline int valid_user_regs(CPUARMState *regs)
>>       return 1;
>>   }
>>
>> +static bool v2_frame(void)
>> +{
>> +    return get_osversion() >= 0x020612;
>> +}
> 
> Not sure how much we care about supporting claiming to be a 15-year-old
> kernel any more (especially since we set UNAME_MINIMUM_RELEASE to 2.6.32...)
> so it's awfully tempting to just blow away the v1 frame support instead...
> 
> Anyway
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

I hadn't noticed the minimum release setting.  Yes, I think it would be better to remove 
the v1 support instead of bodging around it like this.


r~


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

* Re: [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp Richard Henderson
@ 2021-06-29 14:40   ` Peter Maydell
  2021-06-29 18:30     ` Richard Henderson
  0 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 14:40 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Alex Bennée, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:38, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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);
>

In the kernel in arch/x86/kernel/signal.c there is a comment:

        /*
         * This is popl %eax ; movl $__NR_sigreturn, %eax ; int $0x80
         *
         * WE DO NOT USE IT ANY MORE! It's only left here for historical
         * reasons and because gdb uses it as a signature to notice
         * signal handler stack frames.
         */

which suggests that we also should continue to fill in the
retcode bytes in the signal frame for gdb's benefit even though
we don't actually execute them any more.

thanks
-- PMM


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

* Re: [PATCH v2 17/23] linux-user/ppc: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 17/23] linux-user/ppc: " Richard Henderson
@ 2021-06-29 14:52   ` Peter Maydell
  0 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2021-06-29 14:52 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Alex Bennée, qemu-ppc, QEMU Developers, Laurent Vivier

On Fri, 18 Jun 2021 at 20:47, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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(-)

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

encode_trampoline() returns doing nothing if its first argument is zero.
It's not clear to me why it does that (it seems to have been that
way since the ppc signal handling code was added in 2009 in commit
bcd4933a23f1db). Is this because in some configurations there is no
NR_sigreturn syscall, only NR_rt_sigreturn (or vice-versa)? If so,
it would be better to handle that by not setting up the default_sigreturn
pointer, and assert()ing that it's not NULL if we ever try to use it.
(I would vaguely have expected that to result in NR_rt_whatever not
being defined, rather than it being defined to 0, though.)
If there is no way that the first argument to encode_trampoline()
can ever be non-zero, we should delete the unnecessary if().

thanks
-- PMM


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

* Re: [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp
  2021-06-29 14:40   ` Peter Maydell
@ 2021-06-29 18:30     ` Richard Henderson
  0 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-29 18:30 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Alex Bennée, QEMU Developers, Laurent Vivier

On 6/29/21 7:40 AM, Peter Maydell wrote:
> On Fri, 18 Jun 2021 at 20:38, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> 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);
>>
> 
> In the kernel in arch/x86/kernel/signal.c there is a comment:
> 
>          /*
>           * This is popl %eax ; movl $__NR_sigreturn, %eax ; int $0x80
>           *
>           * WE DO NOT USE IT ANY MORE! It's only left here for historical
>           * reasons and because gdb uses it as a signature to notice
>           * signal handler stack frames.
>           */
> 
> which suggests that we also should continue to fill in the
> retcode bytes in the signal frame for gdb's benefit even though
> we don't actually execute them any more.

Point.  I noticed the same for several other targets, but didn't actually look at the 
kernel code for i386.


r~


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

* Re: [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp
  2021-06-29 14:09   ` Peter Maydell
@ 2021-06-29 18:32     ` Richard Henderson
  0 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-06-29 18:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, QEMU Developers, Laurent Vivier

On 6/29/21 7:09 AM, Peter Maydell wrote:
> On Fri, 18 Jun 2021 at 20:33, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> 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(-)
> 
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 
> though I'm not 100% confident I checked all the details. Do you have
> test programs that checked all the different trampolines ?

No, I have no fdpic testcases, and wasn't keen to spend an afternoon building the toolchain.


r~


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

* Re: [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp
  2021-06-29 13:36   ` Peter Maydell
@ 2021-07-01 19:27     ` Richard Henderson
  0 siblings, 0 replies; 43+ messages in thread
From: Richard Henderson @ 2021-07-01 19:27 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Philippe Mathieu-Daudé, qemu-arm, QEMU Developers, Laurent Vivier

On 6/29/21 6:36 AM, Peter Maydell wrote:
> A little way up from here there's a comment:
> 
>      /* Reserve space for the return code.  On a real system this would
>       * be within the VDSO.  So, despite the name this is not a "real"
>       * record within the frame.
>       */
>      fr_ofs = layout.total_size;
>      layout.total_size += sizeof(struct target_rt_frame_record);
> 
> That now needs updating, because we're no longer putting the return
> code in that target_rt_frame_record.

Updated to

    /*
     * Reserve space for the standard frame unwind pair: fp, lr.
     * Despite the name this is not a "real" record within the frame.
     */


> I think the 'struct target_rt_frame_record' now does correspond
> to the kernel's 'struct frame_record', right?

Yes.


r~


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

* Re: [PATCH v2 21/23] linux-user/sparc: Implement setup_sigtramp
  2021-06-18 19:29 ` [PATCH v2 21/23] linux-user/sparc: " Richard Henderson
@ 2021-07-02  9:05   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 43+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-02  9:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, Mark Cave-Ayland, laurent

On 6/18/21 9:29 PM, Richard Henderson wrote:
> 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(-)

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


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

end of thread, other threads:[~2021-07-02  9:07 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-18 19:29 [PATCH v2 00/23] linux-user: Move signal trampolines to new page Richard Henderson
2021-06-18 19:29 ` [PATCH v2 01/23] linux-user: Add infrastructure for a signal trampoline page Richard Henderson
2021-06-19  9:33   ` Philippe Mathieu-Daudé
2021-06-29 13:30   ` Peter Maydell
2021-06-18 19:29 ` [PATCH v2 02/23] linux-user/aarch64: Implement setup_sigtramp Richard Henderson
2021-06-29 13:36   ` Peter Maydell
2021-07-01 19:27     ` Richard Henderson
2021-06-18 19:29 ` [PATCH v2 03/23] linux-user/arm: Split out v2_frame Richard Henderson
2021-06-29 13:53   ` Peter Maydell
2021-06-29 14:30     ` Richard Henderson
2021-06-18 19:29 ` [PATCH v2 04/23] linux-user/arm: Force v2 frames for fdpic Richard Henderson
2021-06-29 13:54   ` Peter Maydell
2021-06-18 19:29 ` [PATCH v2 05/23] linux-user/arm: Implement setup_sigtramp Richard Henderson
2021-06-29 14:09   ` Peter Maydell
2021-06-29 18:32     ` Richard Henderson
2021-06-18 19:29 ` [PATCH v2 06/23] linux-user/alpha: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 07/23] linux-user/cris: " Richard Henderson
2021-06-19  9:33   ` Philippe Mathieu-Daudé
2021-06-19 12:55     ` Richard Henderson
2021-06-19 14:17       ` Philippe Mathieu-Daudé
2021-06-18 19:29 ` [PATCH v2 08/23] linux-user/hexagon: " Richard Henderson
2021-06-19  9:31   ` Philippe Mathieu-Daudé
2021-06-18 19:29 ` [PATCH v2 09/23] linux-user/hppa: Document non-use of setup_sigtramp Richard Henderson
2021-06-18 19:29 ` [PATCH v2 10/23] linux-user/i386: Implement setup_sigtramp Richard Henderson
2021-06-29 14:40   ` Peter Maydell
2021-06-29 18:30     ` Richard Henderson
2021-06-18 19:29 ` [PATCH v2 11/23] linux-user/m68k: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 12/23] linux-user/microblaze: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 13/23] linux-user/mips: Tidy install_sigtramp Richard Henderson
2021-06-19  9:29   ` Philippe Mathieu-Daudé
2021-06-18 19:29 ` [PATCH v2 14/23] linux-user/mips: Implement setup_sigtramp Richard Henderson
2021-06-18 19:29 ` [PATCH v2 15/23] linux-user/nios2: Document non-use of setup_sigtramp Richard Henderson
2021-06-19  9:35   ` Philippe Mathieu-Daudé
2021-06-18 19:29 ` [PATCH v2 16/23] linux-user/openrisc: Implement setup_sigtramp Richard Henderson
2021-06-18 19:29 ` [PATCH v2 17/23] linux-user/ppc: " Richard Henderson
2021-06-29 14:52   ` Peter Maydell
2021-06-18 19:29 ` [PATCH v2 18/23] linux-user/riscv: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 19/23] linux-user/s390x: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 20/23] linux-user/sh4: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 21/23] linux-user/sparc: " Richard Henderson
2021-07-02  9:05   ` Philippe Mathieu-Daudé
2021-06-18 19:29 ` [PATCH v2 22/23] linux-user/xtensa: " Richard Henderson
2021-06-18 19:29 ` [PATCH v2 23/23] linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).