summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-09-18 14:14:11 +0000
committerjdike <jdike>2003-09-18 14:14:11 +0000
commit8169d7c672c4ac421f6e5dc563ac29bf4a749a96 (patch)
treee1f1421c4297fbc05b1ad7ea6d75b44c2c3cee70
parentb2a035dbf1ad05d29ef439db9b7cfcff61db9458 (diff)
downloaduml-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.c21
-rw-r--r--arch/um/sys-i386/util/mk_sc.c1
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(&current->thread.regs.regs) = (void *) (&sig + 1);
+ disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
+ (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
+ SC_SIGMASK(UPT_SC(&current->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);