aboutsummaryrefslogtreecommitdiff
path: root/linux-user/hppa
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-07-25 14:16:45 +0100
committerLaurent Vivier <laurent@vivier.eu>2019-07-26 19:24:33 +0200
commit5bfce0b74fbd5d53089bb866919d685c47edad9e (patch)
tree7b352053272100d776034988ef56d2241afba8db /linux-user/hppa
parentfff3159900d2b95613a9cb75fc3703e67a674729 (diff)
linux-user: Make sigaltstack stacks per-thread
The alternate signal stack set up by the sigaltstack syscall is supposed to be per-thread. We were incorrectly implementing it as process-wide. This causes problems for guest binaries that rely on this. Notably the Go runtime does, and so we were seeing crashes caused by races where two guest threads might incorrectly both execute on the same stack simultaneously. Replace the global target_sigaltstack_used with a field sigaltstack_used in the TaskState, and make all the references to the old global instead get a pointer to the TaskState and use the field. Fixes: https://bugs.launchpad.net/qemu/+bug/1696773 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20190725131645.19501-1-peter.maydell@linaro.org> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user/hppa')
-rw-r--r--linux-user/hppa/signal.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c
index b6927ee673..d1a58feeb3 100644
--- a/linux-user/hppa/signal.c
+++ b/linux-user/hppa/signal.c
@@ -111,10 +111,11 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
abi_ulong frame_addr, sp, haddr;
struct target_rt_sigframe *frame;
int i;
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
sp = get_sp_from_cpustate(env);
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
- sp = (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
+ sp = (ts->sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
}
frame_addr = QEMU_ALIGN_UP(sp, 64);
sp = frame_addr + PARISC_RT_SIGFRAME_SIZE32;