diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 7ec5b57dcf7a..183b60729f33 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -1425,44 +1425,50 @@ thread_schedule_upcall(struct thread *td, struct kse_upcall *ku) return (td2); /* bogus.. should be a void function */ } -/* - * Schedule an upcall to notify a KSE process recieved signals. - * - * XXX - Modifying a sigset_t like this is totally bogus. - */ -struct thread * -signal_upcall(struct proc *p, int sig) +void +thread_signal_add(struct thread *td, int sig) { -#if 0 - struct thread *td, *td2; - struct kse *ke; + struct kse_upcall *ku; + struct proc *p; sigset_t ss; int error; -#endif - PROC_LOCK_ASSERT(p, MA_OWNED); -return (NULL); -#if 0 - td = FIRST_THREAD_IN_PROC(p); - ke = td->td_kse; + PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + td = curthread; + ku = td->td_upcall; + p = td->td_proc; + PROC_UNLOCK(p); - error = copyin(&ke->ke_mailbox->km_sigscaught, &ss, sizeof(sigset_t)); - PROC_LOCK(p); + error = copyin(&ku->ku_mailbox->km_sigscaught, &ss, sizeof(sigset_t)); if (error) - return (NULL); + goto error; + SIGADDSET(ss, sig); - PROC_UNLOCK(p); - error = copyout(&ss, &ke->ke_mailbox->km_sigscaught, sizeof(sigset_t)); - PROC_LOCK(p); + + error = copyout(&ss, &ku->ku_mailbox->km_sigscaught, sizeof(sigset_t)); if (error) - return (NULL); - if (td->td_standin == NULL) - thread_alloc_spare(td, NULL); + goto error; + + PROC_LOCK(p); + return; +error: + PROC_LOCK(p); + sigexit(td, SIGILL); +} + + +/* + * Schedule an upcall to notify a KSE process recieved signals. + * + */ +void +thread_signal_upcall(struct thread *td) +{ mtx_lock_spin(&sched_lock); - td2 = thread_schedule_upcall(td, ke); /* Bogus JRE */ + td->td_flags |= TDF_UPCALLING; mtx_unlock_spin(&sched_lock); - return (td2); -#endif + + return; } /* diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 8aaf3d9daba5..80df09cff3d0 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1910,9 +1910,10 @@ postsig(sig) p->p_sig = 0; } if (p->p_flag & P_KSES) - if (signal_upcall(p, sig)) - return; - (*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code); + thread_signal_add(curthread, sig); + else + (*p->p_sysent->sv_sendsig)(action, sig, + &returnmask, code); } } diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 7ec5b57dcf7a..183b60729f33 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -1425,44 +1425,50 @@ thread_schedule_upcall(struct thread *td, struct kse_upcall *ku) return (td2); /* bogus.. should be a void function */ } -/* - * Schedule an upcall to notify a KSE process recieved signals. - * - * XXX - Modifying a sigset_t like this is totally bogus. - */ -struct thread * -signal_upcall(struct proc *p, int sig) +void +thread_signal_add(struct thread *td, int sig) { -#if 0 - struct thread *td, *td2; - struct kse *ke; + struct kse_upcall *ku; + struct proc *p; sigset_t ss; int error; -#endif - PROC_LOCK_ASSERT(p, MA_OWNED); -return (NULL); -#if 0 - td = FIRST_THREAD_IN_PROC(p); - ke = td->td_kse; + PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + td = curthread; + ku = td->td_upcall; + p = td->td_proc; + PROC_UNLOCK(p); - error = copyin(&ke->ke_mailbox->km_sigscaught, &ss, sizeof(sigset_t)); - PROC_LOCK(p); + error = copyin(&ku->ku_mailbox->km_sigscaught, &ss, sizeof(sigset_t)); if (error) - return (NULL); + goto error; + SIGADDSET(ss, sig); - PROC_UNLOCK(p); - error = copyout(&ss, &ke->ke_mailbox->km_sigscaught, sizeof(sigset_t)); - PROC_LOCK(p); + + error = copyout(&ss, &ku->ku_mailbox->km_sigscaught, sizeof(sigset_t)); if (error) - return (NULL); - if (td->td_standin == NULL) - thread_alloc_spare(td, NULL); + goto error; + + PROC_LOCK(p); + return; +error: + PROC_LOCK(p); + sigexit(td, SIGILL); +} + + +/* + * Schedule an upcall to notify a KSE process recieved signals. + * + */ +void +thread_signal_upcall(struct thread *td) +{ mtx_lock_spin(&sched_lock); - td2 = thread_schedule_upcall(td, ke); /* Bogus JRE */ + td->td_flags |= TDF_UPCALLING; mtx_unlock_spin(&sched_lock); - return (td2); -#endif + + return; } /* diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 7ffb9682f912..c0c0fd58de6a 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -247,10 +247,17 @@ ast(struct trapframe *framep) mtx_unlock_spin(&sched_lock); } if (sflag & PS_NEEDSIGCHK) { + int sigs; + + sigs = 0; PROC_LOCK(p); - while ((sig = cursig(td)) != 0) + while ((sig = cursig(td)) != 0) { postsig(sig); + sigs++; + } PROC_UNLOCK(p); + if (p->p_flag & P_KSES && sigs) + thread_signal_upcall(td); } userret(td, framep, sticks); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 8a18d2c9cfc2..afb225d8ef83 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -915,7 +915,8 @@ void kse_link(struct kse *ke, struct ksegrp *kg); void kse_unlink(struct kse *ke); void ksegrp_link(struct ksegrp *kg, struct proc *p); void ksegrp_unlink(struct ksegrp *kg); -struct thread *signal_upcall(struct proc *p, int sig); +void thread_signal_add(struct thread *td, int sig); +void thread_signal_upcall(struct thread *td); struct thread *thread_alloc(void); void thread_exit(void) __dead2; int thread_export_context(struct thread *td);