xref: /netbsd/sys/rump/librump/rumpkern/signals.c (revision 14b4bbb2)
1*14b4bbb2Sad /*	$NetBSD: signals.c,v 1.17 2020/05/23 23:42:44 ad Exp $	*/
277c91f33Spooka 
3b6788a4aSpooka /*-
4b6788a4aSpooka  * 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*14b4bbb2Sad __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 
37ff225a39Spooka #include <rump-sys/kern.h>
38ff225a39Spooka 
3977c91f33Spooka #include <rump/rump.h>
4077c91f33Spooka #include <rump/rumpuser.h>
4177c91f33Spooka 
4242387e80Spooka const struct filterops sig_filtops = {
4342387e80Spooka 	.f_attach = (void *)eopnotsupp,
4442387e80Spooka };
4542387e80Spooka 
46516d9bdeSpooka sigset_t sigcantmask;
4777c91f33Spooka 
48b6788a4aSpooka static void
pgrp_apply(struct pgrp * pgrp,int signo,void (* apply)(struct proc * p,int))49b6788a4aSpooka pgrp_apply(struct pgrp *pgrp, int signo, void (*apply)(struct proc *p, int))
50b6788a4aSpooka {
51b6788a4aSpooka 	struct proc *p;
52b6788a4aSpooka 
53*14b4bbb2Sad 	KASSERT(mutex_owned(&proc_lock));
54b6788a4aSpooka 
55b6788a4aSpooka 	LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
56b6788a4aSpooka 		mutex_enter(p->p_lock);
57b6788a4aSpooka 		apply(p, signo);
58b6788a4aSpooka 		mutex_exit(p->p_lock);
59b6788a4aSpooka 	}
60b6788a4aSpooka }
61b6788a4aSpooka 
6277c91f33Spooka /* RUMP_SIGMODEL_PANIC */
6377c91f33Spooka 
6477c91f33Spooka static void
rumpsig_panic(struct proc * p,int signo)65b6788a4aSpooka rumpsig_panic(struct proc *p, int signo)
6677c91f33Spooka {
6777c91f33Spooka 
6877c91f33Spooka 	switch (signo) {
6977c91f33Spooka 	case SIGSYS:
7068247628Spooka 	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)80b6788a4aSpooka 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)89b6788a4aSpooka rumpsig_raise(struct proc *p, int signo)
9077c91f33Spooka {
9177c91f33Spooka 
92b6788a4aSpooka 	if (RUMP_LOCALPROC_P(p)) {
93f55f4185Spooka 		rumpuser_kill(p->p_pid, signo);
94b6788a4aSpooka 	} else {
95a385a11aSpooka 		rump_sysproxy_raise(RUMP_SPVM2CTL(p->p_vmspace), signo);
96b6788a4aSpooka 	}
9777c91f33Spooka }
9877c91f33Spooka 
9900ab7eebSpooka static void
rumpsig_record(struct proc * p,int signo)100b6788a4aSpooka rumpsig_record(struct proc *p, int signo)
10100ab7eebSpooka {
10200ab7eebSpooka 
103b6788a4aSpooka 	if (!sigismember(&p->p_sigctx.ps_sigignore, signo)) {
104b6788a4aSpooka 		sigaddset(&p->p_sigpend.sp_set, signo);
10500ab7eebSpooka 	}
10600ab7eebSpooka }
10700ab7eebSpooka 
108b6788a4aSpooka typedef void (*rumpsig_fn)(struct proc *, int);
10977c91f33Spooka 
110d9cef087Spooka 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;
138f55f4185Spooka 
139f55f4185Spooka 	/* for compat, though I doubt anyone is using it */
140f55f4185Spooka 	case RUMP_SIGMODEL__HOST_NOTANYMORE:
141f55f4185Spooka 		rumpsig = rumpsig_raise;
142f55f4185Spooka 		break;
14377c91f33Spooka 	}
14477c91f33Spooka }
14577c91f33Spooka 
14677c91f33Spooka void
psignal(struct proc * p,int sig)14777c91f33Spooka psignal(struct proc *p, int sig)
14877c91f33Spooka {
14977c91f33Spooka 
150b6788a4aSpooka 	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 
157b6788a4aSpooka 	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 
164b6788a4aSpooka 	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 
171b6788a4aSpooka 	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 
229acb689caSchristos 	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 }
269d03b76d3Schristos 
270d03b76d3Schristos void
sigsuspendsetup(struct lwp * l,const sigset_t * ss)271d03b76d3Schristos sigsuspendsetup(struct lwp *l, const sigset_t *ss)
272d03b76d3Schristos {
273084feec1Stron 	/* XXX: Partial copy of kernel code, remove and use the kernel code. */
274d03b76d3Schristos 	struct proc *p = l->l_proc;
275d03b76d3Schristos 
276d03b76d3Schristos 	mutex_enter(p->p_lock);
277d03b76d3Schristos 	l->l_sigrestore = 1;
278d03b76d3Schristos 	l->l_sigoldmask = l->l_sigmask;
279d03b76d3Schristos 	l->l_sigmask = *ss;
280d03b76d3Schristos 	sigminusset(&sigcantmask, &l->l_sigmask);
281d03b76d3Schristos 	mutex_exit(p->p_lock);
282d03b76d3Schristos }
283084feec1Stron 
284084feec1Stron void
sigsuspendteardown(struct lwp * l)285084feec1Stron sigsuspendteardown(struct lwp *l)
286084feec1Stron {
287084feec1Stron 	/* XXX: Copy of kernel code, remove and use the kernel code. */
288084feec1Stron 	struct proc *p = l->l_proc;
289084feec1Stron 
290084feec1Stron 	mutex_enter(p->p_lock);
291084feec1Stron 	if (l->l_sigrestore) {
292084feec1Stron 		l->l_sigrestore = 0;
293084feec1Stron 		l->l_sigmask = l->l_sigoldmask;
294084feec1Stron 	}
295084feec1Stron 	mutex_exit(p->p_lock);
296084feec1Stron }
297