Fixed a bug in tt mode which resulted in signals being blocked in userspace.
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 71ef2ac..07b0d15 100644
@@ -112,12 +112,18 @@
static void new_thread_handler(int sig)
+ unsigned long disable;
int (*fn)(void *);
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;
@@ -140,6 +146,19 @@
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.
@@ -151,7 +170,7 @@
* 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
@@ -38,6 +38,7 @@
+ SC_OFFSET("SC_SIGMASK", oldmask);