Skip to content

Commit e7ab658

Browse files
committed
Merge remote-tracking branch 'remotes/vivier/tags/linux-user-for-6.2-pull-request' into staging
Pull request linux-user 20211004 Move signal trampolines to new page # gpg: Signature made Mon 04 Oct 2021 12:43:53 AM PDT # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "[email protected]" # gpg: Good signature from "Laurent Vivier <[email protected]>" [full] # gpg: aka "Laurent Vivier <[email protected]>" [full] # gpg: aka "Laurent Vivier (Red Hat) <[email protected]>" [full] * remotes/vivier/tags/linux-user-for-6.2-pull-request: (26 commits) tests/tcg/multiarch: Re-enable signals test for most guests linux-user: Remove default for TARGET_ARCH_HAS_SIGTRAMP_PAGE linux-user/xtensa: Implement setup_sigtramp linux-user/sparc: Implement setup_sigtramp linux-user/sh4: Implement setup_sigtramp linux-user/s390x: Implement setup_sigtramp linux-user/riscv: Implement setup_sigtramp linux-user/ppc: Implement setup_sigtramp linux-user/ppc: Simplify encode_trampoline linux-user/openrisc: Implement setup_sigtramp linux-user/nios2: Document non-use of setup_sigtramp linux-user/mips: Implement setup_sigtramp linux-user/mips: Tidy install_sigtramp linux-user/microblaze: Implement setup_sigtramp linux-user/m68k: Implement setup_sigtramp linux-user/x86_64: Raise SIGSEGV if SA_RESTORER not set linux-user/i386: Implement setup_sigtramp linux-user/hppa: Document non-use of setup_sigtramp linux-user/hexagon: Implement setup_sigtramp linux-user/cris: Implement setup_sigtramp ... Signed-off-by: Richard Henderson <[email protected]>
2 parents 30bd1db + efee71c commit e7ab658

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+559
-550
lines changed

linux-user/aarch64/signal.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ struct target_rt_sigframe {
109109
struct target_rt_frame_record {
110110
uint64_t fp;
111111
uint64_t lr;
112-
uint32_t tramp[2];
113112
};
114113

115114
static void target_setup_general_frame(struct target_rt_sigframe *sf,
@@ -461,9 +460,9 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
461460
layout.total_size = MAX(layout.total_size,
462461
sizeof(struct target_rt_sigframe));
463462

464-
/* Reserve space for the return code. On a real system this would
465-
* be within the VDSO. So, despite the name this is not a "real"
466-
* record within the frame.
463+
/*
464+
* Reserve space for the standard frame unwind pair: fp, lr.
465+
* Despite the name this is not a "real" record within the frame.
467466
*/
468467
fr_ofs = layout.total_size;
469468
layout.total_size += sizeof(struct target_rt_frame_record);
@@ -496,15 +495,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
496495
if (ka->sa_flags & TARGET_SA_RESTORER) {
497496
return_addr = ka->sa_restorer;
498497
} else {
499-
/*
500-
* mov x8,#__NR_rt_sigreturn; svc #0
501-
* Since these are instructions they need to be put as little-endian
502-
* regardless of target default or current CPU endianness.
503-
*/
504-
__put_user_e(0xd2801168, &fr->tramp[0], le);
505-
__put_user_e(0xd4000001, &fr->tramp[1], le);
506-
return_addr = frame_addr + fr_ofs
507-
+ offsetof(struct target_rt_frame_record, tramp);
498+
return_addr = default_rt_sigreturn;
508499
}
509500
env->xregs[0] = usig;
510501
env->xregs[29] = frame_addr + fr_ofs;
@@ -577,3 +568,20 @@ long do_sigreturn(CPUARMState *env)
577568
{
578569
return do_rt_sigreturn(env);
579570
}
571+
572+
void setup_sigtramp(abi_ulong sigtramp_page)
573+
{
574+
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
575+
assert(tramp != NULL);
576+
577+
/*
578+
* mov x8,#__NR_rt_sigreturn; svc #0
579+
* Since these are instructions they need to be put as little-endian
580+
* regardless of target default or current CPU endianness.
581+
*/
582+
__put_user_e(0xd2801168, &tramp[0], le);
583+
__put_user_e(0xd4000001, &tramp[1], le);
584+
585+
default_rt_sigreturn = sigtramp_page;
586+
unlock_user(tramp, sigtramp_page, 8);
587+
}

linux-user/aarch64/target_signal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@ typedef struct target_sigaltstack {
2525
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
2626

2727
#define TARGET_ARCH_HAS_SETUP_FRAME
28+
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
29+
2830
#endif /* AARCH64_TARGET_SIGNAL_H */

linux-user/alpha/signal.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,11 @@ struct target_ucontext {
5555

5656
struct target_sigframe {
5757
struct target_sigcontext sc;
58-
unsigned int retcode[3];
5958
};
6059

6160
struct target_rt_sigframe {
6261
target_siginfo_t info;
6362
struct target_ucontext uc;
64-
unsigned int retcode[3];
6563
};
6664

6765
#define INSN_MOV_R30_R16 0x47fe0410
@@ -142,12 +140,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
142140
if (ka->ka_restorer) {
143141
r26 = ka->ka_restorer;
144142
} else {
145-
__put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
146-
__put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
147-
&frame->retcode[1]);
148-
__put_user(INSN_CALLSYS, &frame->retcode[2]);
149-
/* imb() */
150-
r26 = frame_addr + offsetof(struct target_sigframe, retcode);
143+
r26 = default_sigreturn;
151144
}
152145

153146
unlock_user_struct(frame, frame_addr, 1);
@@ -196,12 +189,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
196189
if (ka->ka_restorer) {
197190
r26 = ka->ka_restorer;
198191
} else {
199-
__put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
200-
__put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
201-
&frame->retcode[1]);
202-
__put_user(INSN_CALLSYS, &frame->retcode[2]);
203-
/* imb(); */
204-
r26 = frame_addr + offsetof(struct target_rt_sigframe, retcode);
192+
r26 = default_rt_sigreturn;
205193
}
206194

207195
if (err) {
@@ -269,3 +257,21 @@ long do_rt_sigreturn(CPUAlphaState *env)
269257
force_sig(TARGET_SIGSEGV);
270258
return -TARGET_QEMU_ESIGRETURN;
271259
}
260+
261+
void setup_sigtramp(abi_ulong sigtramp_page)
262+
{
263+
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6 * 4, 0);
264+
assert(tramp != NULL);
265+
266+
default_sigreturn = sigtramp_page;
267+
__put_user(INSN_MOV_R30_R16, &tramp[0]);
268+
__put_user(INSN_LDI_R0 + TARGET_NR_sigreturn, &tramp[1]);
269+
__put_user(INSN_CALLSYS, &tramp[2]);
270+
271+
default_rt_sigreturn = sigtramp_page + 3 * 4;
272+
__put_user(INSN_MOV_R30_R16, &tramp[3]);
273+
__put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn, &tramp[4]);
274+
__put_user(INSN_CALLSYS, &tramp[5]);
275+
276+
unlock_user(tramp, sigtramp_page, 6 * 4);
277+
}

linux-user/alpha/target_signal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ typedef struct target_sigaltstack {
9393

9494
#define TARGET_ARCH_HAS_SETUP_FRAME
9595
#define TARGET_ARCH_HAS_KA_RESTORER
96+
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
9697

9798
/* bit-flags */
9899
#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */

0 commit comments

Comments
 (0)