diff options
author | jdike <jdike> | 2003-09-18 14:14:11 +0000 |
---|---|---|
committer | jdike <jdike> | 2003-09-18 14:14:11 +0000 |
commit | 8169d7c672c4ac421f6e5dc563ac29bf4a749a96 (patch) | |
tree | e1f1421c4297fbc05b1ad7ea6d75b44c2c3cee70 | |
parent | b2a035dbf1ad05d29ef439db9b7cfcff61db9458 (diff) | |
download | uml-history-8169d7c672c4ac421f6e5dc563ac29bf4a749a96.tar.gz |
Fixed a bug in tt mode which resulted in signals being blocked in userspace.
-rw-r--r-- | arch/um/kernel/tt/process_kern.c | 21 | ||||
-rw-r--r-- | arch/um/sys-i386/util/mk_sc.c | 1 |
2 files changed, 21 insertions, 1 deletions
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 71ef2ac..07b0d15 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -112,12 +112,18 @@ extern void schedule_tail(struct task_struct *prev); static void new_thread_handler(int sig) { + unsigned long disable; int (*fn)(void *); void *arg; fn = current->thread.request.u.thread.proc; arg = current->thread.request.u.thread.arg; + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); + disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) | + (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1)); + SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable; + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); init_new_thread_signals(1); @@ -140,6 +146,19 @@ static void new_thread_handler(int sig) static int new_thread_proc(void *stack) { + /* cli is needed to block out signals until this thread is properly + * scheduled. Otherwise, the tracing thread will get mighty upset + * about any signals that arrive before that. + * This has the complication that it sets the saved signal mask in + * the sigcontext to block signals. This gets restored when this + * thread (or a descendant, since they get a copy of this sigcontext) + * returns to userspace. + * So, this is compensated for elsewhere. + * XXX There is still a small window until cli() actually finishes + * where signals are possible - shouldn't be a problem in practice + * since SIGIO hasn't been forwarded here yet, and the cli should + * finish before a SIGVTALRM has time to be delivered. + */ cli(); init_new_thread_stack(stack, new_thread_handler); os_usr1_process(os_getpid()); @@ -151,7 +170,7 @@ static int new_thread_proc(void *stack) * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off, * so it is blocked before it's called. They are re-enabled on sigreturn * despite the fact that they were blocked when the SIGUSR1 was issued because - * copy_thread copies the parent's signcontext, including the signal mask + * copy_thread copies the parent's sigcontext, including the signal mask * onto the signal frame. */ diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c index 224b6ad..85cbd30 100644 --- a/arch/um/sys-i386/util/mk_sc.c +++ b/arch/um/sys-i386/util/mk_sc.c @@ -38,6 +38,7 @@ int main(int argc, char **argv) SC_OFFSET("SC_ERR", err); SC_OFFSET("SC_CR2", cr2); SC_OFFSET("SC_FPSTATE", fpstate); + SC_OFFSET("SC_SIGMASK", oldmask); SC_FP_OFFSET("SC_FP_CW", cw); SC_FP_OFFSET("SC_FP_SW", sw); SC_FP_OFFSET("SC_FP_TAG", tag); |