Home | History | Annotate | Line # | Download | only in rumpkern
signals.c revision 1.10.14.3
      1  1.10.14.1       tls /*	$NetBSD: signals.c,v 1.10.14.3 2017/12/03 11:39:16 jdolecek Exp $	*/
      2        1.1     pooka 
      3        1.7     pooka /*-
      4        1.7     pooka  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
      5        1.1     pooka  *
      6        1.1     pooka  * Redistribution and use in source and binary forms, with or without
      7        1.1     pooka  * modification, are permitted provided that the following conditions
      8        1.1     pooka  * are met:
      9        1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     10        1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     11        1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12        1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     13        1.1     pooka  *    documentation and/or other materials provided with the distribution.
     14        1.1     pooka  *
     15        1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16        1.1     pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17        1.1     pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18        1.1     pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19        1.1     pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20        1.1     pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21        1.1     pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22        1.1     pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23        1.1     pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24        1.1     pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25        1.1     pooka  * SUCH DAMAGE.
     26        1.1     pooka  */
     27        1.1     pooka 
     28        1.1     pooka #include <sys/cdefs.h>
     29  1.10.14.1       tls __KERNEL_RCSID(0, "$NetBSD: signals.c,v 1.10.14.3 2017/12/03 11:39:16 jdolecek Exp $");
     30        1.1     pooka 
     31        1.1     pooka #include <sys/param.h>
     32        1.1     pooka #include <sys/atomic.h>
     33        1.1     pooka #include <sys/event.h>
     34        1.1     pooka #include <sys/proc.h>
     35        1.1     pooka #include <sys/signal.h>
     36        1.1     pooka 
     37  1.10.14.3  jdolecek #include <rump-sys/kern.h>
     38  1.10.14.3  jdolecek 
     39        1.1     pooka #include <rump/rump.h>
     40        1.1     pooka #include <rump/rumpuser.h>
     41        1.1     pooka 
     42        1.5     pooka const struct filterops sig_filtops = {
     43        1.5     pooka 	.f_attach = (void *)eopnotsupp,
     44        1.5     pooka };
     45        1.5     pooka 
     46        1.2     pooka sigset_t sigcantmask;
     47        1.1     pooka 
     48        1.7     pooka static void
     49        1.7     pooka pgrp_apply(struct pgrp *pgrp, int signo, void (*apply)(struct proc *p, int))
     50        1.7     pooka {
     51        1.7     pooka 	struct proc *p;
     52        1.7     pooka 
     53        1.7     pooka 	KASSERT(mutex_owned(proc_lock));
     54        1.7     pooka 
     55        1.7     pooka 	LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
     56        1.7     pooka 		mutex_enter(p->p_lock);
     57        1.7     pooka 		apply(p, signo);
     58        1.7     pooka 		mutex_exit(p->p_lock);
     59        1.7     pooka 	}
     60        1.7     pooka }
     61        1.7     pooka 
     62        1.1     pooka /* RUMP_SIGMODEL_PANIC */
     63        1.1     pooka 
     64        1.1     pooka static void
     65        1.7     pooka rumpsig_panic(struct proc *p, int signo)
     66        1.1     pooka {
     67        1.1     pooka 
     68        1.1     pooka 	switch (signo) {
     69        1.1     pooka 	case SIGSYS:
     70        1.6     pooka 	case SIGPIPE:
     71        1.1     pooka 		break;
     72        1.1     pooka 	default:
     73        1.1     pooka 		panic("unhandled signal %d", signo);
     74        1.1     pooka 	}
     75        1.1     pooka }
     76        1.1     pooka 
     77        1.1     pooka /* RUMP_SIGMODEL_IGNORE */
     78        1.1     pooka 
     79        1.1     pooka static void
     80        1.7     pooka rumpsig_ignore(struct proc *p, int signo)
     81        1.1     pooka {
     82        1.1     pooka 
     83        1.1     pooka 	return;
     84        1.1     pooka }
     85        1.1     pooka 
     86        1.1     pooka /* RUMP_SIGMODEL_RAISE */
     87        1.1     pooka 
     88        1.1     pooka static void
     89        1.7     pooka rumpsig_raise(struct proc *p, int signo)
     90        1.1     pooka {
     91        1.1     pooka 
     92        1.7     pooka 	if (RUMP_LOCALPROC_P(p)) {
     93  1.10.14.2       tls 		rumpuser_kill(p->p_pid, signo);
     94        1.7     pooka 	} else {
     95  1.10.14.3  jdolecek 		rump_sysproxy_raise(RUMP_SPVM2CTL(p->p_vmspace), signo);
     96        1.7     pooka 	}
     97        1.1     pooka }
     98        1.1     pooka 
     99        1.4     pooka static void
    100        1.7     pooka rumpsig_record(struct proc *p, int signo)
    101        1.4     pooka {
    102        1.4     pooka 
    103        1.7     pooka 	if (!sigismember(&p->p_sigctx.ps_sigignore, signo)) {
    104        1.7     pooka 		sigaddset(&p->p_sigpend.sp_set, signo);
    105        1.4     pooka 	}
    106        1.4     pooka }
    107        1.4     pooka 
    108        1.7     pooka typedef void (*rumpsig_fn)(struct proc *, int);
    109        1.1     pooka 
    110        1.8     pooka static rumpsig_fn rumpsig = rumpsig_raise;
    111        1.1     pooka 
    112        1.1     pooka /*
    113        1.1     pooka  * Set signal delivery model.  It would be nice if we could
    114        1.1     pooka  * take a functional argument.  But then we'd need some
    115        1.1     pooka  * OS independent way to represent a signal number and also
    116        1.1     pooka  * a method for easy processing (parsing is boring).
    117        1.1     pooka  *
    118        1.1     pooka  * Plus, upcalls from the rump kernel into process space except
    119        1.1     pooka  * via rumpuser is a somewhat gray area now.
    120        1.1     pooka  */
    121        1.1     pooka void
    122        1.1     pooka rump_boot_setsigmodel(enum rump_sigmodel model)
    123        1.1     pooka {
    124        1.1     pooka 
    125        1.1     pooka 	switch (model) {
    126        1.1     pooka 	case RUMP_SIGMODEL_PANIC:
    127        1.4     pooka 		rumpsig = rumpsig_panic;
    128        1.1     pooka 		break;
    129        1.1     pooka 	case RUMP_SIGMODEL_IGNORE:
    130        1.4     pooka 		rumpsig = rumpsig_ignore;
    131        1.1     pooka 		break;
    132        1.1     pooka 	case RUMP_SIGMODEL_RAISE:
    133        1.4     pooka 		rumpsig = rumpsig_raise;
    134        1.4     pooka 		break;
    135        1.4     pooka 	case RUMP_SIGMODEL_RECORD:
    136        1.4     pooka 		rumpsig = rumpsig_record;
    137        1.1     pooka 		break;
    138  1.10.14.2       tls 
    139  1.10.14.2       tls 	/* for compat, though I doubt anyone is using it */
    140  1.10.14.2       tls 	case RUMP_SIGMODEL__HOST_NOTANYMORE:
    141  1.10.14.2       tls 		rumpsig = rumpsig_raise;
    142  1.10.14.2       tls 		break;
    143        1.1     pooka 	}
    144        1.1     pooka }
    145        1.1     pooka 
    146        1.1     pooka void
    147        1.1     pooka psignal(struct proc *p, int sig)
    148        1.1     pooka {
    149        1.1     pooka 
    150        1.7     pooka 	rumpsig(p, sig);
    151        1.1     pooka }
    152        1.1     pooka 
    153        1.1     pooka void
    154        1.1     pooka pgsignal(struct pgrp *pgrp, int sig, int checktty)
    155        1.1     pooka {
    156        1.1     pooka 
    157        1.7     pooka 	pgrp_apply(pgrp, sig, rumpsig);
    158        1.1     pooka }
    159        1.1     pooka 
    160        1.1     pooka void
    161        1.1     pooka kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
    162        1.1     pooka {
    163        1.1     pooka 
    164        1.7     pooka 	rumpsig(p, ksi->ksi_signo);
    165        1.1     pooka }
    166        1.1     pooka 
    167        1.1     pooka void
    168        1.1     pooka kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty)
    169        1.1     pooka {
    170        1.1     pooka 
    171        1.7     pooka 	pgrp_apply(pgrp, ksi->ksi_signo, rumpsig);
    172        1.1     pooka }
    173        1.1     pooka 
    174        1.1     pooka int
    175        1.1     pooka sigispending(struct lwp *l, int signo)
    176        1.1     pooka {
    177        1.4     pooka 	struct proc *p = l->l_proc;
    178        1.4     pooka 	sigset_t tset;
    179        1.4     pooka 
    180        1.4     pooka 	tset = p->p_sigpend.sp_set;
    181        1.1     pooka 
    182        1.4     pooka 	if (signo == 0) {
    183        1.4     pooka 		if (firstsig(&tset) != 0)
    184        1.4     pooka 			return EINTR;
    185        1.4     pooka 	} else if (sigismember(&tset, signo))
    186        1.4     pooka 		return EINTR;
    187        1.1     pooka 	return 0;
    188        1.1     pooka }
    189        1.1     pooka 
    190        1.1     pooka void
    191        1.1     pooka sigpending1(struct lwp *l, sigset_t *ss)
    192        1.1     pooka {
    193        1.4     pooka 	struct proc *p = l->l_proc;
    194        1.1     pooka 
    195        1.4     pooka 	mutex_enter(p->p_lock);
    196        1.4     pooka 	*ss = l->l_proc->p_sigpend.sp_set;
    197        1.4     pooka 	mutex_exit(p->p_lock);
    198        1.1     pooka }
    199        1.1     pooka 
    200        1.1     pooka int
    201        1.1     pooka sigismasked(struct lwp *l, int sig)
    202        1.1     pooka {
    203        1.1     pooka 
    204        1.4     pooka 	return sigismember(&l->l_proc->p_sigctx.ps_sigignore, sig);
    205        1.4     pooka }
    206        1.4     pooka 
    207        1.4     pooka void
    208        1.4     pooka sigclear(sigpend_t *sp, const sigset_t *mask, ksiginfoq_t *kq)
    209        1.4     pooka {
    210        1.4     pooka 
    211        1.4     pooka 	if (mask == NULL)
    212        1.4     pooka 		sigemptyset(&sp->sp_set);
    213        1.4     pooka 	else
    214        1.4     pooka 		sigminusset(mask, &sp->sp_set);
    215        1.1     pooka }
    216        1.1     pooka 
    217        1.1     pooka void
    218        1.1     pooka sigclearall(struct proc *p, const sigset_t *mask, ksiginfoq_t *kq)
    219        1.1     pooka {
    220        1.1     pooka 
    221        1.4     pooka 	/* don't assert proc lock, hence callable from user context */
    222        1.4     pooka 	sigclear(&p->p_sigpend, mask, kq);
    223        1.1     pooka }
    224        1.1     pooka 
    225        1.1     pooka void
    226        1.1     pooka ksiginfo_queue_drain0(ksiginfoq_t *kq)
    227        1.1     pooka {
    228        1.1     pooka 
    229  1.10.14.2       tls 	if (!(TAILQ_EMPTY(kq)))
    230        1.1     pooka 		panic("how did that get there?");
    231        1.1     pooka }
    232        1.3     pooka 
    233        1.4     pooka int
    234        1.4     pooka sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
    235        1.4     pooka {
    236        1.4     pooka 	sigset_t *mask = &l->l_proc->p_sigctx.ps_sigignore;
    237        1.4     pooka 
    238        1.4     pooka 	KASSERT(mutex_owned(l->l_proc->p_lock));
    239        1.4     pooka 
    240        1.4     pooka 	if (oss)
    241        1.4     pooka 		*oss = *mask;
    242        1.4     pooka 
    243        1.4     pooka 	if (nss) {
    244        1.4     pooka 		switch (how) {
    245        1.4     pooka 		case SIG_BLOCK:
    246        1.4     pooka 			sigplusset(nss, mask);
    247        1.4     pooka 			break;
    248        1.4     pooka 		case SIG_UNBLOCK:
    249        1.4     pooka 			sigminusset(nss, mask);
    250        1.4     pooka 			break;
    251        1.4     pooka 		case SIG_SETMASK:
    252        1.4     pooka 			*mask = *nss;
    253        1.4     pooka 			break;
    254        1.4     pooka 		default:
    255        1.4     pooka 			return EINVAL;
    256        1.4     pooka 		}
    257        1.4     pooka 	}
    258        1.4     pooka 
    259        1.4     pooka 	return 0;
    260        1.4     pooka }
    261        1.4     pooka 
    262        1.3     pooka void
    263        1.3     pooka siginit(struct proc *p)
    264        1.3     pooka {
    265        1.3     pooka 
    266        1.4     pooka 	sigemptyset(&p->p_sigctx.ps_sigignore);
    267        1.4     pooka 	sigemptyset(&p->p_sigpend.sp_set);
    268        1.3     pooka }
    269        1.9  christos 
    270        1.9  christos void
    271        1.9  christos sigsuspendsetup(struct lwp *l, const sigset_t *ss)
    272        1.9  christos {
    273       1.10      tron 	/* XXX: Partial copy of kernel code, remove and use the kernel code. */
    274        1.9  christos 	struct proc *p = l->l_proc;
    275        1.9  christos 
    276        1.9  christos 	mutex_enter(p->p_lock);
    277        1.9  christos 	l->l_sigrestore = 1;
    278        1.9  christos 	l->l_sigoldmask = l->l_sigmask;
    279        1.9  christos 	l->l_sigmask = *ss;
    280        1.9  christos 	sigminusset(&sigcantmask, &l->l_sigmask);
    281        1.9  christos 	mutex_exit(p->p_lock);
    282        1.9  christos }
    283       1.10      tron 
    284       1.10      tron void
    285       1.10      tron sigsuspendteardown(struct lwp *l)
    286       1.10      tron {
    287       1.10      tron 	/* XXX: Copy of kernel code, remove and use the kernel code. */
    288       1.10      tron 	struct proc *p = l->l_proc;
    289       1.10      tron 
    290       1.10      tron 	mutex_enter(p->p_lock);
    291       1.10      tron 	if (l->l_sigrestore) {
    292       1.10      tron 		l->l_sigrestore = 0;
    293       1.10      tron 		l->l_sigmask = l->l_sigoldmask;
    294       1.10      tron 	}
    295       1.10      tron 	mutex_exit(p->p_lock);
    296       1.10      tron }
    297