diff --git a/kernel-src/io/poll.c b/kernel-src/io/poll.c index 1775fe08..f1108172 100644 --- a/kernel-src/io/poll.c +++ b/kernel-src/io/poll.c @@ -112,6 +112,8 @@ int poll_dowait(polldesc_t *desc, size_t ustimeout) { __assert(ret || spinlock_try(&desc->lock) == false); if (ret == SCHED_WAKEUP_REASON_INTERRUPTED) { + // future note: if this deadlocks, check the caller to see if + // desc is not being reset spinlock_acquire(&desc->wakeuplock); ret = EINTR; } diff --git a/kernel-src/sys/signal.c b/kernel-src/sys/signal.c index 725e2314..fa399aba 100644 --- a/kernel-src/sys/signal.c +++ b/kernel-src/sys/signal.c @@ -594,13 +594,16 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin SIGNAL_SETON(&thread->signals.mask, i); } - // configure return context - memset(context, 0, sizeof(context_t)); - CTX_INIT(context, true, true); - CTX_IP(context) = (uint64_t)action->address; - CTX_SP(context) = (uint64_t)stack; - CTX_ARG0(context) = signal; - set_siginfo_ucontext(context, stack); + // do not sync the context until after the usercopy. + // context may point at thread->context, which a page + // fault may overwrite for sleeping. + context_t handler_context; + memset(&handler_context, 0, sizeof(context_t)); + CTX_INIT(&handler_context, true, true); + CTX_IP(&handler_context) = (uint64_t)action->address; + CTX_SP(&handler_context) = (uint64_t)stack; + CTX_ARG0(&handler_context) = signal; + set_siginfo_ucontext(&handler_context, stack); // reset handler if asked for if (action->flags & SA_RESETHAND) @@ -619,6 +622,7 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin proc_terminate(SIGSEGV); } + *context = handler_context; return retry; }