aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-07-26 18:36:04 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-07-26 18:36:05 +0100
commit0c6f3e948cbeb4f4f4a335d80293aa3736eeba2f (patch)
tree7b352053272100d776034988ef56d2241afba8db
parentfff3159900d2b95613a9cb75fc3703e67a674729 (diff)
parent5bfce0b74fbd5d53089bb866919d685c47edad9e (diff)
downloadqemu-0c6f3e948cbeb4f4f4a335d80293aa3736eeba2f.zip
qemu-0c6f3e948cbeb4f4f4a335d80293aa3736eeba2f.tar.gz
qemu-0c6f3e948cbeb4f4f4a335d80293aa3736eeba2f.tar.bz2
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.1-pull-request' into staging
Fix multi-threaded go runtime crash # gpg: Signature made Fri 26 Jul 2019 18:34:00 BST # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-4.1-pull-request: linux-user: Make sigaltstack stacks per-thread Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--linux-user/hppa/signal.c3
-rw-r--r--linux-user/main.c5
-rw-r--r--linux-user/qemu.h2
-rw-r--r--linux-user/signal-common.h1
-rw-r--r--linux-user/signal.c35
5 files changed, 28 insertions, 18 deletions
diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c
index b6927ee..d1a58fe 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;
diff --git a/linux-user/main.c b/linux-user/main.c
index a59ae94..8ffc525 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -180,6 +180,11 @@ void stop_all_tasks(void)
void init_task_state(TaskState *ts)
{
ts->used = 1;
+ ts->sigaltstack_used = (struct target_sigaltstack) {
+ .ss_sp = 0,
+ .ss_size = 0,
+ .ss_flags = TARGET_SS_DISABLE,
+ };
}
CPUArchState *cpu_copy(CPUArchState *env)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 4258e41..aac0334 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -151,6 +151,8 @@ typedef struct TaskState {
*/
int signal_pending;
+ /* This thread's sigaltstack, if it has one */
+ struct target_sigaltstack sigaltstack_used;
} __attribute__((aligned(16))) TaskState;
extern char *exec_path;
diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h
index 51030a9..1df1068 100644
--- a/linux-user/signal-common.h
+++ b/linux-user/signal-common.h
@@ -19,7 +19,6 @@
#ifndef SIGNAL_COMMON_H
#define SIGNAL_COMMON_H
-extern struct target_sigaltstack target_sigaltstack_used;
int on_sig_stack(unsigned long sp);
int sas_ss_flags(unsigned long sp);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 5cd23783..5ca6d62 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -25,12 +25,6 @@
#include "trace.h"
#include "signal-common.h"
-struct target_sigaltstack target_sigaltstack_used = {
- .ss_sp = 0,
- .ss_size = 0,
- .ss_flags = TARGET_SS_DISABLE,
-};
-
static struct target_sigaction sigact_table[TARGET_NSIG];
static void host_signal_handler(int host_signum, siginfo_t *info,
@@ -251,13 +245,17 @@ void set_sigmask(const sigset_t *set)
int on_sig_stack(unsigned long sp)
{
- return (sp - target_sigaltstack_used.ss_sp
- < target_sigaltstack_used.ss_size);
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+ return (sp - ts->sigaltstack_used.ss_sp
+ < ts->sigaltstack_used.ss_size);
}
int sas_ss_flags(unsigned long sp)
{
- return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+ return (ts->sigaltstack_used.ss_size == 0 ? SS_DISABLE
: on_sig_stack(sp) ? SS_ONSTACK : 0);
}
@@ -266,17 +264,21 @@ abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka)
/*
* This is the X/Open sanctioned signal stack switching.
*/
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
+
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
- return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ return ts->sigaltstack_used.ss_sp + ts->sigaltstack_used.ss_size;
}
return sp;
}
void target_save_altstack(target_stack_t *uss, CPUArchState *env)
{
- __put_user(target_sigaltstack_used.ss_sp, &uss->ss_sp);
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+ __put_user(ts->sigaltstack_used.ss_sp, &uss->ss_sp);
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), &uss->ss_flags);
- __put_user(target_sigaltstack_used.ss_size, &uss->ss_size);
+ __put_user(ts->sigaltstack_used.ss_size, &uss->ss_size);
}
/* siginfo conversion */
@@ -708,12 +710,13 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
{
int ret;
struct target_sigaltstack oss;
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
/* XXX: test errors */
if(uoss_addr)
{
- __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
- __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
+ __put_user(ts->sigaltstack_used.ss_sp, &oss.ss_sp);
+ __put_user(ts->sigaltstack_used.ss_size, &oss.ss_size);
__put_user(sas_ss_flags(sp), &oss.ss_flags);
}
@@ -760,8 +763,8 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
}
}
- target_sigaltstack_used.ss_sp = ss.ss_sp;
- target_sigaltstack_used.ss_size = ss.ss_size;
+ ts->sigaltstack_used.ss_sp = ss.ss_sp;
+ ts->sigaltstack_used.ss_size = ss.ss_size;
}
if (uoss_addr) {