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