xref: /netbsd-src/sys/rump/librump/rumpkern/signals.c (revision 0eaaa024ea5a271b8f91fe07fe846a86f31dd9b9)
1*0eaaa024Sad /*	$NetBSD: signals.c,v 1.17 2020/05/23 23:42:44 ad Exp $	*/
277c91f33Spooka 
3cf864401Spooka /*-
4cf864401Spooka  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
577c91f33Spooka  *
677c91f33Spooka  * Redistribution and use in source and binary forms, with or without
777c91f33Spooka  * modification, are permitted provided that the following conditions
877c91f33Spooka  * are met:
977c91f33Spooka  * 1. Redistributions of source code must retain the above copyright
1077c91f33Spooka  *    notice, this list of conditions and the following disclaimer.
1177c91f33Spooka  * 2. Redistributions in binary form must reproduce the above copyright
1277c91f33Spooka  *    notice, this list of conditions and the following disclaimer in the
1377c91f33Spooka  *    documentation and/or other materials provided with the distribution.
1477c91f33Spooka  *
1577c91f33Spooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1677c91f33Spooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1777c91f33Spooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1877c91f33Spooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1977c91f33Spooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2077c91f33Spooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2177c91f33Spooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2277c91f33Spooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2377c91f33Spooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2477c91f33Spooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2577c91f33Spooka  * SUCH DAMAGE.
2677c91f33Spooka  */
2777c91f33Spooka 
2877c91f33Spooka #include <sys/cdefs.h>
29*0eaaa024Sad __KERNEL_RCSID(0, "$NetBSD: signals.c,v 1.17 2020/05/23 23:42:44 ad Exp $");
3077c91f33Spooka 
3177c91f33Spooka #include <sys/param.h>
3277c91f33Spooka #include <sys/atomic.h>
3377c91f33Spooka #include <sys/event.h>
3477c91f33Spooka #include <sys/proc.h>
3577c91f33Spooka #include <sys/signal.h>
3677c91f33Spooka 
376bb51422Spooka #include <rump-sys/kern.h>
386bb51422Spooka 
3977c91f33Spooka #include <rump/rump.h>
4077c91f33Spooka #include <rump/rumpuser.h>
4177c91f33Spooka 
427766a795Spooka const struct filterops sig_filtops = {
437766a795Spooka 	.f_attach = (void *)eopnotsupp,
447766a795Spooka };
457766a795Spooka 
46516d9bdeSpooka sigset_t sigcantmask;
4777c91f33Spooka 
48cf864401Spooka static void
pgrp_apply(struct pgrp * pgrp,int signo,void (* apply)(struct proc * p,int))49cf864401Spooka pgrp_apply(struct pgrp *pgrp, int signo, void (*apply)(struct proc *p, int))
50cf864401Spooka {
51cf864401Spooka 	struct proc *p;
52cf864401Spooka 
53*0eaaa024Sad 	KASSERT(mutex_owned(&proc_lock));
54cf864401Spooka 
55cf864401Spooka 	LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
56cf864401Spooka 		mutex_enter(p->p_lock);
57cf864401Spooka 		apply(p, signo);
58cf864401Spooka 		mutex_exit(p->p_lock);
59cf864401Spooka 	}
60cf864401Spooka }
61cf864401Spooka 
6277c91f33Spooka /* RUMP_SIGMODEL_PANIC */
6377c91f33Spooka 
6477c91f33Spooka static void
rumpsig_panic(struct proc * p,int signo)65cf864401Spooka rumpsig_panic(struct proc *p, int signo)
6677c91f33Spooka {
6777c91f33Spooka 
6877c91f33Spooka 	switch (signo) {
6977c91f33Spooka 	case SIGSYS:
70712b8046Spooka 	case SIGPIPE:
7177c91f33Spooka 		break;
7277c91f33Spooka 	default:
7377c91f33Spooka 		panic("unhandled signal %d", signo);
7477c91f33Spooka 	}
7577c91f33Spooka }
7677c91f33Spooka 
7777c91f33Spooka /* RUMP_SIGMODEL_IGNORE */
7877c91f33Spooka 
7977c91f33Spooka static void
rumpsig_ignore(struct proc * p,int signo)80cf864401Spooka rumpsig_ignore(struct proc *p, int signo)
8177c91f33Spooka {
8277c91f33Spooka 
8377c91f33Spooka 	return;
8477c91f33Spooka }
8577c91f33Spooka 
8677c91f33Spooka /* RUMP_SIGMODEL_RAISE */
8777c91f33Spooka 
8877c91f33Spooka static void
rumpsig_raise(struct proc * p,int signo)89cf864401Spooka rumpsig_raise(struct proc *p, int signo)
9077c91f33Spooka {
9177c91f33Spooka 
92cf864401Spooka 	if (RUMP_LOCALPROC_P(p)) {
9347693a47Spooka 		rumpuser_kill(p->p_pid, signo);
94cf864401Spooka 	} else {
956195daadSpooka 		rump_sysproxy_raise(RUMP_SPVM2CTL(p->p_vmspace), signo);
96cf864401Spooka 	}
9777c91f33Spooka }
9877c91f33Spooka 
9900ab7eebSpooka static void
rumpsig_record(struct proc * p,int signo)100cf864401Spooka rumpsig_record(struct proc *p, int signo)
10100ab7eebSpooka {
10200ab7eebSpooka 
103cf864401Spooka 	if (!sigismember(&p->p_sigctx.ps_sigignore, signo)) {
104cf864401Spooka 		sigaddset(&p->p_sigpend.sp_set, signo);
10500ab7eebSpooka 	}
10600ab7eebSpooka }
10700ab7eebSpooka 
108cf864401Spooka typedef void (*rumpsig_fn)(struct proc *, int);
10977c91f33Spooka 
110dd69b8ebSpooka static rumpsig_fn rumpsig = rumpsig_raise;
11177c91f33Spooka 
11277c91f33Spooka /*
11377c91f33Spooka  * Set signal delivery model.  It would be nice if we could
11477c91f33Spooka  * take a functional argument.  But then we'd need some
11577c91f33Spooka  * OS independent way to represent a signal number and also
11677c91f33Spooka  * a method for easy processing (parsing is boring).
11777c91f33Spooka  *
11877c91f33Spooka  * Plus, upcalls from the rump kernel into process space except
11977c91f33Spooka  * via rumpuser is a somewhat gray area now.
12077c91f33Spooka  */
12177c91f33Spooka void
rump_boot_setsigmodel(enum rump_sigmodel model)12277c91f33Spooka rump_boot_setsigmodel(enum rump_sigmodel model)
12377c91f33Spooka {
12477c91f33Spooka 
12577c91f33Spooka 	switch (model) {
12677c91f33Spooka 	case RUMP_SIGMODEL_PANIC:
12700ab7eebSpooka 		rumpsig = rumpsig_panic;
12877c91f33Spooka 		break;
12977c91f33Spooka 	case RUMP_SIGMODEL_IGNORE:
13000ab7eebSpooka 		rumpsig = rumpsig_ignore;
13177c91f33Spooka 		break;
13277c91f33Spooka 	case RUMP_SIGMODEL_RAISE:
13300ab7eebSpooka 		rumpsig = rumpsig_raise;
13400ab7eebSpooka 		break;
13500ab7eebSpooka 	case RUMP_SIGMODEL_RECORD:
13600ab7eebSpooka 		rumpsig = rumpsig_record;
13777c91f33Spooka 		break;
13847693a47Spooka 
13947693a47Spooka 	/* for compat, though I doubt anyone is using it */
14047693a47Spooka 	case RUMP_SIGMODEL__HOST_NOTANYMORE:
14147693a47Spooka 		rumpsig = rumpsig_raise;
14247693a47Spooka 		break;
14377c91f33Spooka 	}
14477c91f33Spooka }
14577c91f33Spooka 
14677c91f33Spooka void
psignal(struct proc * p,int sig)14777c91f33Spooka psignal(struct proc *p, int sig)
14877c91f33Spooka {
14977c91f33Spooka 
150cf864401Spooka 	rumpsig(p, sig);
15177c91f33Spooka }
15277c91f33Spooka 
15377c91f33Spooka void
pgsignal(struct pgrp * pgrp,int sig,int checktty)15477c91f33Spooka pgsignal(struct pgrp *pgrp, int sig, int checktty)
15577c91f33Spooka {
15677c91f33Spooka 
157cf864401Spooka 	pgrp_apply(pgrp, sig, rumpsig);
15877c91f33Spooka }
15977c91f33Spooka 
16077c91f33Spooka void
kpsignal(struct proc * p,ksiginfo_t * ksi,void * data)16177c91f33Spooka kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
16277c91f33Spooka {
16377c91f33Spooka 
164cf864401Spooka 	rumpsig(p, ksi->ksi_signo);
16577c91f33Spooka }
16677c91f33Spooka 
16777c91f33Spooka void
kpgsignal(struct pgrp * pgrp,ksiginfo_t * ksi,void * data,int checkctty)16877c91f33Spooka kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty)
16977c91f33Spooka {
17077c91f33Spooka 
171cf864401Spooka 	pgrp_apply(pgrp, ksi->ksi_signo, rumpsig);
17277c91f33Spooka }
17377c91f33Spooka 
17477c91f33Spooka int
sigispending(struct lwp * l,int signo)17577c91f33Spooka sigispending(struct lwp *l, int signo)
17677c91f33Spooka {
17700ab7eebSpooka 	struct proc *p = l->l_proc;
17800ab7eebSpooka 	sigset_t tset;
17977c91f33Spooka 
18000ab7eebSpooka 	tset = p->p_sigpend.sp_set;
18100ab7eebSpooka 
18200ab7eebSpooka 	if (signo == 0) {
18300ab7eebSpooka 		if (firstsig(&tset) != 0)
18400ab7eebSpooka 			return EINTR;
18500ab7eebSpooka 	} else if (sigismember(&tset, signo))
18600ab7eebSpooka 		return EINTR;
18777c91f33Spooka 	return 0;
18877c91f33Spooka }
18977c91f33Spooka 
19077c91f33Spooka void
sigpending1(struct lwp * l,sigset_t * ss)19177c91f33Spooka sigpending1(struct lwp *l, sigset_t *ss)
19277c91f33Spooka {
19300ab7eebSpooka 	struct proc *p = l->l_proc;
19477c91f33Spooka 
19500ab7eebSpooka 	mutex_enter(p->p_lock);
19600ab7eebSpooka 	*ss = l->l_proc->p_sigpend.sp_set;
19700ab7eebSpooka 	mutex_exit(p->p_lock);
19877c91f33Spooka }
19977c91f33Spooka 
20077c91f33Spooka int
sigismasked(struct lwp * l,int sig)20177c91f33Spooka sigismasked(struct lwp *l, int sig)
20277c91f33Spooka {
20377c91f33Spooka 
20400ab7eebSpooka 	return sigismember(&l->l_proc->p_sigctx.ps_sigignore, sig);
20500ab7eebSpooka }
20600ab7eebSpooka 
20700ab7eebSpooka void
sigclear(sigpend_t * sp,const sigset_t * mask,ksiginfoq_t * kq)20800ab7eebSpooka sigclear(sigpend_t *sp, const sigset_t *mask, ksiginfoq_t *kq)
20900ab7eebSpooka {
21000ab7eebSpooka 
21100ab7eebSpooka 	if (mask == NULL)
21200ab7eebSpooka 		sigemptyset(&sp->sp_set);
21300ab7eebSpooka 	else
21400ab7eebSpooka 		sigminusset(mask, &sp->sp_set);
21577c91f33Spooka }
21677c91f33Spooka 
21777c91f33Spooka void
sigclearall(struct proc * p,const sigset_t * mask,ksiginfoq_t * kq)21877c91f33Spooka sigclearall(struct proc *p, const sigset_t *mask, ksiginfoq_t *kq)
21977c91f33Spooka {
22077c91f33Spooka 
22100ab7eebSpooka 	/* don't assert proc lock, hence callable from user context */
22200ab7eebSpooka 	sigclear(&p->p_sigpend, mask, kq);
22377c91f33Spooka }
22477c91f33Spooka 
22577c91f33Spooka void
ksiginfo_queue_drain0(ksiginfoq_t * kq)22677c91f33Spooka ksiginfo_queue_drain0(ksiginfoq_t *kq)
22777c91f33Spooka {
22877c91f33Spooka 
22992afcdc1Schristos 	if (!(TAILQ_EMPTY(kq)))
23077c91f33Spooka 		panic("how did that get there?");
23177c91f33Spooka }
232eacf4402Spooka 
23300ab7eebSpooka int
sigprocmask1(struct lwp * l,int how,const sigset_t * nss,sigset_t * oss)23400ab7eebSpooka sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
23500ab7eebSpooka {
23600ab7eebSpooka 	sigset_t *mask = &l->l_proc->p_sigctx.ps_sigignore;
23700ab7eebSpooka 
23800ab7eebSpooka 	KASSERT(mutex_owned(l->l_proc->p_lock));
23900ab7eebSpooka 
24000ab7eebSpooka 	if (oss)
24100ab7eebSpooka 		*oss = *mask;
24200ab7eebSpooka 
24300ab7eebSpooka 	if (nss) {
24400ab7eebSpooka 		switch (how) {
24500ab7eebSpooka 		case SIG_BLOCK:
24600ab7eebSpooka 			sigplusset(nss, mask);
24700ab7eebSpooka 			break;
24800ab7eebSpooka 		case SIG_UNBLOCK:
24900ab7eebSpooka 			sigminusset(nss, mask);
25000ab7eebSpooka 			break;
25100ab7eebSpooka 		case SIG_SETMASK:
25200ab7eebSpooka 			*mask = *nss;
25300ab7eebSpooka 			break;
25400ab7eebSpooka 		default:
25500ab7eebSpooka 			return EINVAL;
25600ab7eebSpooka 		}
25700ab7eebSpooka 	}
25800ab7eebSpooka 
25900ab7eebSpooka 	return 0;
26000ab7eebSpooka }
26100ab7eebSpooka 
262eacf4402Spooka void
siginit(struct proc * p)263eacf4402Spooka siginit(struct proc *p)
264eacf4402Spooka {
265eacf4402Spooka 
26600ab7eebSpooka 	sigemptyset(&p->p_sigctx.ps_sigignore);
26700ab7eebSpooka 	sigemptyset(&p->p_sigpend.sp_set);
268eacf4402Spooka }
2696009929cSchristos 
2706009929cSchristos void
sigsuspendsetup(struct lwp * l,const sigset_t * ss)2716009929cSchristos sigsuspendsetup(struct lwp *l, const sigset_t *ss)
2726009929cSchristos {
2738bcd25a1Stron 	/* XXX: Partial copy of kernel code, remove and use the kernel code. */
2746009929cSchristos 	struct proc *p = l->l_proc;
2756009929cSchristos 
2766009929cSchristos 	mutex_enter(p->p_lock);
2776009929cSchristos 	l->l_sigrestore = 1;
2786009929cSchristos 	l->l_sigoldmask = l->l_sigmask;
2796009929cSchristos 	l->l_sigmask = *ss;
2806009929cSchristos 	sigminusset(&sigcantmask, &l->l_sigmask);
2816009929cSchristos 	mutex_exit(p->p_lock);
2826009929cSchristos }
2838bcd25a1Stron 
2848bcd25a1Stron void
sigsuspendteardown(struct lwp * l)2858bcd25a1Stron sigsuspendteardown(struct lwp *l)
2868bcd25a1Stron {
2878bcd25a1Stron 	/* XXX: Copy of kernel code, remove and use the kernel code. */
2888bcd25a1Stron 	struct proc *p = l->l_proc;
2898bcd25a1Stron 
2908bcd25a1Stron 	mutex_enter(p->p_lock);
2918bcd25a1Stron 	if (l->l_sigrestore) {
2928bcd25a1Stron 		l->l_sigrestore = 0;
2938bcd25a1Stron 		l->l_sigmask = l->l_sigoldmask;
2948bcd25a1Stron 	}
2958bcd25a1Stron 	mutex_exit(p->p_lock);
2968bcd25a1Stron }
297