- Merge struct procsig with struct sigacts.

- Move struct sigacts out of the u-area and malloc() it using the
  M_SUBPROC malloc bucket.
- Add a small sigacts_*() API for managing sigacts structures: sigacts_alloc(),
  sigacts_free(), sigacts_copy(), sigacts_share(), and sigacts_shared().
- Remove the p_sigignore, p_sigacts, and p_sigcatch macros.
- Add a mutex to struct sigacts that protects all the members of the struct.
- Add sigacts locking.
- Remove Giant from nosys(), kill(), killpg(), and kern_sigaction() now
  that sigacts is locked.
- Several in-kernel functions such as psignal(), tdsignal(), trapsignal(),
  and thread_stopped() are now MP safe.

Reviewed by:	arch@
Approved by:	re (rwatson)
This commit is contained in:
John Baldwin 2003-05-13 20:36:02 +00:00
parent 3ecb3802ee
commit 90af4afacb
34 changed files with 364 additions and 248 deletions

View File

@ -1133,11 +1133,13 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
td = curthread; td = curthread;
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
frame = td->td_frame; frame = td->td_frame;
oonstack = sigonstack(alpha_pal_rdusp());
fsize = sizeof ksi; fsize = sizeof ksi;
rndfsize = ((fsize + 15) / 16) * 16; rndfsize = ((fsize + 15) / 16) * 16;
psp = p->p_sigacts; oonstack = sigonstack(alpha_pal_rdusp());
/* /*
* Allocate and validate space for the signal handler * Allocate and validate space for the signal handler
@ -1155,6 +1157,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#endif #endif
} else } else
sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize); sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize);
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -1210,7 +1213,8 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_A0] = sig; frame->tf_regs[FRAME_A0] = sig;
frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */ frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
PROC_LOCK(p); PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) mtx_lock(&psp->ps_mtx);
if (SIGISMEMBER(psp->ps_siginfo, sig))
frame->tf_regs[FRAME_A1] = (u_int64_t)sip; frame->tf_regs[FRAME_A1] = (u_int64_t)sip;
else else
frame->tf_regs[FRAME_A1] = code; frame->tf_regs[FRAME_A1] = code;
@ -1235,6 +1239,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
frame = td->td_frame; frame = td->td_frame;
oonstack = sigonstack(alpha_pal_rdusp()); oonstack = sigonstack(alpha_pal_rdusp());
@ -1276,6 +1281,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#endif #endif
} else } else
sfp = (struct sigframe4 *)(alpha_pal_rdusp() - rndfsize); sfp = (struct sigframe4 *)(alpha_pal_rdusp() - rndfsize);
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* save the floating-point state, if necessary, then copy it. */ /* save the floating-point state, if necessary, then copy it. */
@ -1311,7 +1317,8 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_PC] = PS_STRINGS - szfreebsd4_sigcode; frame->tf_regs[FRAME_PC] = PS_STRINGS - szfreebsd4_sigcode;
frame->tf_regs[FRAME_A0] = sig; frame->tf_regs[FRAME_A0] = sig;
PROC_LOCK(p); PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { mtx_lock(&psp->ps_mtx);
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si); frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
/* Fill in POSIX parts */ /* Fill in POSIX parts */
@ -1343,6 +1350,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
#ifdef COMPAT_FREEBSD4 #ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) { if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
freebsd4_sendsig(catcher, sig, mask, code); freebsd4_sendsig(catcher, sig, mask, code);
@ -1397,6 +1405,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#endif #endif
} else } else
sfp = (struct sigframe *)(alpha_pal_rdusp() - rndfsize); sfp = (struct sigframe *)(alpha_pal_rdusp() - rndfsize);
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* save the floating-point state, if necessary, then copy it. */ /* save the floating-point state, if necessary, then copy it. */
@ -1432,7 +1441,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_PC] = PS_STRINGS - szsigcode; frame->tf_regs[FRAME_PC] = PS_STRINGS - szsigcode;
frame->tf_regs[FRAME_A0] = sig; frame->tf_regs[FRAME_A0] = sig;
PROC_LOCK(p); PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { mtx_lock(&psp->ps_mtx);
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si); frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
/* Fill in POSIX parts */ /* Fill in POSIX parts */

View File

@ -471,6 +471,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
frame = td->td_frame; frame = td->td_frame;
oonstack = sigonstack(alpha_pal_rdusp()); oonstack = sigonstack(alpha_pal_rdusp());
@ -490,6 +491,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
p->p_sigstk.ss_flags |= SS_ONSTACK; p->p_sigstk.ss_flags |= SS_ONSTACK;
} else } else
sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize); sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize);
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -551,6 +553,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */ frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
alpha_pal_wrusp((unsigned long)sip); alpha_pal_wrusp((unsigned long)sip);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }

View File

@ -235,6 +235,7 @@ sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_rsp); oonstack = sigonstack(regs->tf_rsp);
@ -262,7 +263,6 @@ sendsig(catcher, sig, mask, code)
sp = (char *)regs->tf_rsp - sizeof(struct sigframe) - 128; sp = (char *)regs->tf_rsp - sizeof(struct sigframe) - 128;
/* Align to 16 bytes. */ /* Align to 16 bytes. */
sfp = (struct sigframe *)((unsigned long)sp & ~0xF); sfp = (struct sigframe *)((unsigned long)sp & ~0xF);
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -271,8 +271,7 @@ sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
regs->tf_rdi = sig; /* arg 1 in %rdi */ regs->tf_rdi = sig; /* arg 1 in %rdi */
regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */ regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */ regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -287,6 +286,7 @@ sendsig(catcher, sig, mask, code)
regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */ regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -305,6 +305,7 @@ sendsig(catcher, sig, mask, code)
regs->tf_rflags &= ~PSL_T; regs->tf_rflags &= ~PSL_T;
regs->tf_cs = _ucodesel; regs->tf_cs = _ucodesel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
/* /*

View File

@ -547,6 +547,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
char *state; char *state;
segsz_t lsize; segsz_t lsize;
struct thread *td2; struct thread *td2;
struct sigacts *ps;
int i; int i;
PROC_LOCK(p); PROC_LOCK(p);
@ -653,8 +654,11 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
* relation to struct proc, so SigBlk is left unimplemented. * relation to struct proc, so SigBlk is left unimplemented.
*/ */
sbuf_printf(sb, "SigBlk:\t%08x\n", 0); /* XXX */ sbuf_printf(sb, "SigBlk:\t%08x\n", 0); /* XXX */
sbuf_printf(sb, "SigIgn:\t%08x\n", p->p_sigignore.__bits[0]); ps = p->p_sigacts;
sbuf_printf(sb, "SigCgt:\t%08x\n", p->p_sigcatch.__bits[0]); mtx_lock(&ps->ps_mtx);
sbuf_printf(sb, "SigIgn:\t%08x\n", ps->ps_sigignore.__bits[0]);
sbuf_printf(sb, "SigCgt:\t%08x\n", ps->ps_sigcatch.__bits[0]);
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*

View File

@ -132,10 +132,21 @@ svr4_sys_read(td, uap)
DPRINTF(("svr4_read(%d, 0x%0x, %d) = %d\n", DPRINTF(("svr4_read(%d, 0x%0x, %d) = %d\n",
uap->fd, uap->buf, uap->nbyte, rv)); uap->fd, uap->buf, uap->nbyte, rv));
if (rv == EAGAIN) { if (rv == EAGAIN) {
#ifdef DEBUG_SVR4
struct sigacts *ps;
PROC_LOCK(td->td_proc);
ps = td->td_proc->p_sigacts;
mtx_lock(&ps->ps_mtx);
#endif
DPRINTF(("sigmask = 0x%x\n", td->td_sigmask)); DPRINTF(("sigmask = 0x%x\n", td->td_sigmask));
DPRINTF(("sigignore = 0x%x\n", td->td_proc->p_sigignore)); DPRINTF(("sigignore = 0x%x\n", ps->ps_sigignore));
DPRINTF(("sigcaught = 0x%x\n", td->td_proc->p_sigcatch)); DPRINTF(("sigcaught = 0x%x\n", ps->ps_sigcatch));
DPRINTF(("siglist = 0x%x\n", td->td_siglist)); DPRINTF(("siglist = 0x%x\n", td->td_siglist));
#ifdef DEBUG_SVR4
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(td->td_proc);
#endif
} }
#if defined(GROTTY_READ_HACK) #if defined(GROTTY_READ_HACK)

View File

@ -1363,12 +1363,8 @@ loop:
sx_xunlock(&proctree_lock); sx_xunlock(&proctree_lock);
PROC_LOCK(q); PROC_LOCK(q);
if (--q->p_procsig->ps_refcnt == 0) { sigacts_free(q->p_sigacts);
if (q->p_sigacts != &q->p_uarea->u_sigacts) q->p_sigacts = NULL;
FREE(q->p_sigacts, M_SUBPROC);
FREE(q->p_procsig, M_SUBPROC);
q->p_procsig = NULL;
}
PROC_UNLOCK(q); PROC_UNLOCK(q);
/* /*

View File

@ -295,6 +295,7 @@ osendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -308,7 +309,6 @@ osendsig(catcher, sig, mask, code)
#endif #endif
} else } else
fp = (struct osigframe *)regs->tf_esp - 1; fp = (struct osigframe *)regs->tf_esp - 1;
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -317,8 +317,7 @@ osendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_arg2 = (register_t)&fp->sf_siginfo; sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig; sf.sf_siginfo.si_signo = sig;
@ -330,6 +329,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* Save most if not all of trap frame. */ /* Save most if not all of trap frame. */
@ -402,6 +402,7 @@ osendsig(catcher, sig, mask, code)
load_gs(_udatasel); load_gs(_udatasel);
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#endif /* COMPAT_43 */ #endif /* COMPAT_43 */
@ -424,6 +425,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -447,7 +449,6 @@ freebsd4_sendsig(catcher, sig, mask, code)
#endif #endif
} else } else
sfp = (struct sigframe4 *)regs->tf_esp - 1; sfp = (struct sigframe4 *)regs->tf_esp - 1;
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -456,8 +457,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc; sf.sf_ucontext = (register_t)&sfp->sf_uc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_siginfo = (register_t)&sfp->sf_si;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -472,6 +472,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -523,6 +524,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#endif /* COMPAT_FREEBSD4 */ #endif /* COMPAT_FREEBSD4 */
@ -545,6 +547,7 @@ sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
#ifdef COMPAT_FREEBSD4 #ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) { if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
freebsd4_sendsig(catcher, sig, mask, code); freebsd4_sendsig(catcher, sig, mask, code);
@ -585,7 +588,6 @@ sendsig(catcher, sig, mask, code)
sp = (char *)regs->tf_esp - sizeof(struct sigframe); sp = (char *)regs->tf_esp - sizeof(struct sigframe);
/* Align to 16 bytes. */ /* Align to 16 bytes. */
sfp = (struct sigframe *)((unsigned int)sp & ~0xF); sfp = (struct sigframe *)((unsigned int)sp & ~0xF);
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -594,8 +596,7 @@ sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc; sf.sf_ucontext = (register_t)&sfp->sf_uc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_siginfo = (register_t)&sfp->sf_si;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -610,6 +611,7 @@ sendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -661,6 +663,7 @@ sendsig(catcher, sig, mask, code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
/* /*

View File

@ -273,11 +273,14 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
{ {
struct thread *td = curthread; struct thread *td = curthread;
struct proc *p = td->td_proc; struct proc *p = td->td_proc;
struct sigacts *psp;
struct trapframe *regs; struct trapframe *regs;
struct l_rt_sigframe *fp, frame; struct l_rt_sigframe *fp, frame;
int oonstack; int oonstack;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -290,11 +293,12 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
* Allocate space for the signal handler context. * Allocate space for the signal handler context.
*/ */
if ((p->p_flag & P_ALTSTACK) && !oonstack && if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct l_rt_sigframe *)(p->p_sigstk.ss_sp + fp = (struct l_rt_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct l_rt_sigframe)); p->p_sigstk.ss_size - sizeof(struct l_rt_sigframe));
} else } else
fp = (struct l_rt_sigframe *)regs->tf_esp - 1; fp = (struct l_rt_sigframe *)regs->tf_esp - 1;
mtx_unlock(&psp->ps_mtx);
/* /*
* Build the argument list for the signal handler. * Build the argument list for the signal handler.
@ -383,6 +387,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
@ -401,13 +406,16 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
{ {
struct thread *td = curthread; struct thread *td = curthread;
struct proc *p = td->td_proc; struct proc *p = td->td_proc;
struct sigacts *psp;
struct trapframe *regs; struct trapframe *regs;
struct l_sigframe *fp, frame; struct l_sigframe *fp, frame;
l_sigset_t lmask; l_sigset_t lmask;
int oonstack, i; int oonstack, i;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
linux_rt_sendsig(catcher, sig, mask, code); linux_rt_sendsig(catcher, sig, mask, code);
return; return;
@ -426,11 +434,12 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
* Allocate space for the signal handler context. * Allocate space for the signal handler context.
*/ */
if ((p->p_flag & P_ALTSTACK) && !oonstack && if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct l_sigframe *)(p->p_sigstk.ss_sp + fp = (struct l_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct l_sigframe)); p->p_sigstk.ss_size - sizeof(struct l_sigframe));
} else } else
fp = (struct l_sigframe *)regs->tf_esp - 1; fp = (struct l_sigframe *)regs->tf_esp - 1;
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -494,6 +503,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
/* /*

View File

@ -428,6 +428,7 @@ svr4_sendsig(catcher, sig, mask, code)
#endif #endif
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame; tf = td->td_frame;
oonstack = sigonstack(tf->tf_esp); oonstack = sigonstack(tf->tf_esp);
@ -443,6 +444,7 @@ svr4_sendsig(catcher, sig, mask, code)
} else { } else {
fp = (struct svr4_sigframe *)tf->tf_esp - 1; fp = (struct svr4_sigframe *)tf->tf_esp - 1;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -505,6 +507,7 @@ svr4_sendsig(catcher, sig, mask, code)
load_gs(_udatasel); load_gs(_udatasel);
tf->tf_ss = _udatasel; tf->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
#endif #endif
} }

View File

@ -756,6 +756,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
frame = td->td_frame; frame = td->td_frame;
oonstack = sigonstack(frame->tf_r[FRAME_SP]); oonstack = sigonstack(frame->tf_r[FRAME_SP]);
rndfsize = ((sizeof(sf) + 15) / 16) * 16; rndfsize = ((sizeof(sf) + 15) / 16) * 16;
@ -822,6 +823,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#endif #endif
} else } else
sfp = (struct sigframe *)(frame->tf_r[FRAME_SP] - rndfsize); sfp = (struct sigframe *)(frame->tf_r[FRAME_SP] - rndfsize);
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
#ifdef DEBUG #ifdef DEBUG
@ -870,7 +872,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_cr_iip = PS_STRINGS - (esigcode - sigcode); frame->tf_cr_iip = PS_STRINGS - (esigcode - sigcode);
frame->tf_r[FRAME_R1] = sig; frame->tf_r[FRAME_R1] = sig;
PROC_LOCK(p); PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { mtx_lock(&psp->ps_mtx);
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
frame->tf_r[FRAME_R15] = (u_int64_t)&(sfp->sf_si); frame->tf_r[FRAME_R15] = (u_int64_t)&(sfp->sf_si);
/* Fill in POSIX parts */ /* Fill in POSIX parts */

View File

@ -90,7 +90,6 @@ struct proc proc0;
struct thread thread0; struct thread thread0;
struct kse kse0; struct kse kse0;
struct ksegrp ksegrp0; struct ksegrp ksegrp0;
static struct procsig procsig0;
static struct filedesc0 filedesc0; static struct filedesc0 filedesc0;
static struct plimit limit0; static struct plimit limit0;
struct vmspace vmspace0; struct vmspace vmspace0;
@ -399,9 +398,8 @@ proc0_init(void *dummy __unused)
#endif #endif
td->td_ucred = crhold(p->p_ucred); td->td_ucred = crhold(p->p_ucred);
/* Create procsig. */ /* Create sigacts. */
p->p_procsig = &procsig0; p->p_sigacts = sigacts_alloc();
p->p_procsig->ps_refcnt = 1;
/* Initialize signal state for process 0. */ /* Initialize signal state for process 0. */
siginit(&proc0); siginit(&proc0);
@ -441,11 +439,10 @@ proc0_init(void *dummy __unused)
vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0); vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
/* /*
* We continue to place resource usage info and signal * We continue to place resource usage info
* actions in the user struct so they're pageable. * in the user struct so that it's pageable.
*/ */
p->p_stats = &p->p_uarea->u_stats; p->p_stats = &p->p_uarea->u_stats;
p->p_sigacts = &p->p_uarea->u_sigacts;
/* /*
* Charge root for one process. * Charge root for one process.

View File

@ -146,7 +146,9 @@ cv_switch_catch(struct thread *td)
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
p = td->td_proc; p = td->td_proc;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
sig = cursig(td); sig = cursig(td);
mtx_unlock(&p->p_sigacts->ps_mtx);
if (thread_suspend_check(1)) if (thread_suspend_check(1))
sig = SIGSTOP; sig = SIGSTOP;
mtx_lock_spin(&sched_lock); mtx_lock_spin(&sched_lock);
@ -283,6 +285,7 @@ cv_wait_sig(struct cv *cvp, struct mtx *mp)
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
if (sig == 0) if (sig == 0)
sig = cursig(td); /* XXXKSE */ sig = cursig(td); /* XXXKSE */
if (sig != 0) { if (sig != 0) {
@ -291,6 +294,7 @@ cv_wait_sig(struct cv *cvp, struct mtx *mp)
else else
rval = ERESTART; rval = ERESTART;
} }
mtx_unlock(&p->p_sigacts->ps_mtx);
if (p->p_flag & P_WEXIT) if (p->p_flag & P_WEXIT)
rval = EINTR; rval = EINTR;
PROC_UNLOCK(p); PROC_UNLOCK(p);
@ -446,6 +450,7 @@ cv_timedwait_sig(struct cv *cvp, struct mtx *mp, int timo)
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
if (sig == 0) if (sig == 0)
sig = cursig(td); sig = cursig(td);
if (sig != 0) { if (sig != 0) {
@ -454,6 +459,7 @@ cv_timedwait_sig(struct cv *cvp, struct mtx *mp, int timo)
else else
rval = ERESTART; rval = ERESTART;
} }
mtx_unlock(&p->p_sigacts->ps_mtx);
if (p->p_flag & P_WEXIT) if (p->p_flag & P_WEXIT)
rval = EINTR; rval = EINTR;
PROC_UNLOCK(p); PROC_UNLOCK(p);

View File

@ -163,7 +163,7 @@ kern_execve(td, fname, argv, envv, mac_p)
struct vattr attr; struct vattr attr;
int (*img_first)(struct image_params *); int (*img_first)(struct image_params *);
struct pargs *oldargs = NULL, *newargs = NULL; struct pargs *oldargs = NULL, *newargs = NULL;
struct procsig *oldprocsig, *newprocsig; struct sigacts *oldsigacts, *newsigacts;
#ifdef KTRACE #ifdef KTRACE
struct vnode *tracevp = NULL; struct vnode *tracevp = NULL;
struct ucred *tracecred = NULL; struct ucred *tracecred = NULL;
@ -409,23 +409,16 @@ interpret:
* reset. * reset.
*/ */
PROC_LOCK(p); PROC_LOCK(p);
mp_fixme("procsig needs a lock"); if (sigacts_shared(p->p_sigacts)) {
if (p->p_procsig->ps_refcnt > 1) { oldsigacts = p->p_sigacts;
oldprocsig = p->p_procsig;
PROC_UNLOCK(p); PROC_UNLOCK(p);
MALLOC(newprocsig, struct procsig *, sizeof(struct procsig), newsigacts = sigacts_alloc();
M_SUBPROC, M_WAITOK); sigacts_copy(newsigacts, oldsigacts);
bcopy(oldprocsig, newprocsig, sizeof(*newprocsig));
newprocsig->ps_refcnt = 1;
oldprocsig->ps_refcnt--;
PROC_LOCK(p); PROC_LOCK(p);
p->p_procsig = newprocsig; p->p_sigacts = newsigacts;
if (p->p_sigacts == &p->p_uarea->u_sigacts) } else
panic("shared procsig but private sigacts?"); oldsigacts = NULL;
p->p_uarea->u_sigacts = *p->p_sigacts;
p->p_sigacts = &p->p_uarea->u_sigacts;
}
/* Stop profiling */ /* Stop profiling */
stopprofclock(p); stopprofclock(p);
@ -624,6 +617,8 @@ done1:
pargs_drop(oldargs); pargs_drop(oldargs);
if (newargs != NULL) if (newargs != NULL)
pargs_drop(newargs); pargs_drop(newargs);
if (oldsigacts != NULL)
sigacts_free(oldsigacts);
exec_fail_dealloc: exec_fail_dealloc:

View File

@ -431,9 +431,11 @@ exit1(struct thread *td, int rv)
* 1 instead (and hope it will handle this situation). * 1 instead (and hope it will handle this situation).
*/ */
PROC_LOCK(p->p_pptr); PROC_LOCK(p->p_pptr);
if (p->p_pptr->p_procsig->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) { mtx_lock(&p->p_pptr->p_sigacts->ps_mtx);
if (p->p_pptr->p_sigacts->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) {
struct proc *pp; struct proc *pp;
mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
pp = p->p_pptr; pp = p->p_pptr;
PROC_UNLOCK(pp); PROC_UNLOCK(pp);
proc_reparent(p, initproc); proc_reparent(p, initproc);
@ -445,7 +447,8 @@ exit1(struct thread *td, int rv)
*/ */
if (LIST_EMPTY(&pp->p_children)) if (LIST_EMPTY(&pp->p_children))
wakeup(pp); wakeup(pp);
} } else
mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
if (p->p_sigparent && p->p_pptr != initproc) if (p->p_sigparent && p->p_pptr != initproc)
psignal(p->p_pptr, p->p_sigparent); psignal(p->p_pptr, p->p_sigparent);
@ -656,23 +659,14 @@ loop:
(void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0);
/* /*
* Free up credentials. * Free credentials, arguments, and sigacts
*/ */
crfree(p->p_ucred); crfree(p->p_ucred);
p->p_ucred = NULL; /* XXX: why? */ p->p_ucred = NULL;
/*
* Remove unused arguments
*/
pargs_drop(p->p_args); pargs_drop(p->p_args);
p->p_args = NULL; p->p_args = NULL;
sigacts_free(p->p_sigacts);
if (--p->p_procsig->ps_refcnt == 0) { p->p_sigacts = NULL;
if (p->p_sigacts != &p->p_uarea->u_sigacts)
FREE(p->p_sigacts, M_SUBPROC);
FREE(p->p_procsig, M_SUBPROC);
p->p_procsig = NULL;
}
/* /*
* do any thread-system specific cleanups * do any thread-system specific cleanups

View File

@ -214,7 +214,6 @@ fork1(td, flags, pages, procp)
struct kse *ke2; struct kse *ke2;
struct ksegrp *kg2; struct ksegrp *kg2;
struct sigacts *newsigacts; struct sigacts *newsigacts;
struct procsig *newprocsig;
int error; int error;
/* Can't copy and clear */ /* Can't copy and clear */
@ -412,15 +411,10 @@ again:
/* /*
* Malloc things while we don't hold any locks. * Malloc things while we don't hold any locks.
*/ */
if (flags & RFSIGSHARE) { if (flags & RFSIGSHARE)
MALLOC(newsigacts, struct sigacts *,
sizeof(struct sigacts), M_SUBPROC, M_WAITOK);
newprocsig = NULL;
} else {
newsigacts = NULL; newsigacts = NULL;
MALLOC(newprocsig, struct procsig *, sizeof(struct procsig), else
M_SUBPROC, M_WAITOK); newsigacts = sigacts_alloc();
}
/* /*
* Copy filedesc. * Copy filedesc.
@ -477,7 +471,7 @@ again:
/* /*
* Duplicate sub-structures as needed. * Duplicate sub-structures as needed.
* Increase reference counts on shared objects. * Increase reference counts on shared objects.
* The p_stats and p_sigacts substructs are set in vm_forkproc. * The p_stats substruct is set in vm_forkproc.
*/ */
p2->p_flag = 0; p2->p_flag = 0;
if (p1->p_flag & P_PROFIL) if (p1->p_flag & P_PROFIL)
@ -497,25 +491,10 @@ again:
pargs_hold(p2->p_args); pargs_hold(p2->p_args);
if (flags & RFSIGSHARE) { if (flags & RFSIGSHARE) {
p2->p_procsig = p1->p_procsig; p2->p_sigacts = sigacts_hold(p1->p_sigacts);
p2->p_procsig->ps_refcnt++;
if (p1->p_sigacts == &p1->p_uarea->u_sigacts) {
/*
* Set p_sigacts to the new shared structure.
* Note that this is updating p1->p_sigacts at the
* same time, since p_sigacts is just a pointer to
* the shared p_procsig->ps_sigacts.
*/
p2->p_sigacts = newsigacts;
newsigacts = NULL;
*p2->p_sigacts = p1->p_uarea->u_sigacts;
}
} else { } else {
p2->p_procsig = newprocsig; sigacts_copy(newsigacts, p1->p_sigacts);
newprocsig = NULL; p2->p_sigacts = newsigacts;
bcopy(p1->p_procsig, p2->p_procsig, sizeof(*p2->p_procsig));
p2->p_procsig->ps_refcnt = 1;
p2->p_sigacts = NULL; /* finished in vm_forkproc() */
} }
if (flags & RFLINUXTHPN) if (flags & RFLINUXTHPN)
p2->p_sigparent = SIGUSR1; p2->p_sigparent = SIGUSR1;
@ -647,9 +626,6 @@ again:
p2->p_acflag = AFORK; p2->p_acflag = AFORK;
PROC_UNLOCK(p2); PROC_UNLOCK(p2);
KASSERT(newprocsig == NULL, ("unused newprocsig"));
if (newsigacts != NULL)
FREE(newsigacts, M_SUBPROC);
/* /*
* Finish creating the child process. It will return via a different * Finish creating the child process. It will return via a different
* execution path later. (ie: directly into user mode) * execution path later. (ie: directly into user mode)

View File

@ -94,7 +94,9 @@ kthread_create(void (*func)(void *), void *arg,
/* this is a non-swapped system process */ /* this is a non-swapped system process */
PROC_LOCK(p2); PROC_LOCK(p2);
p2->p_flag |= P_SYSTEM | P_KTHREAD; p2->p_flag |= P_SYSTEM | P_KTHREAD;
p2->p_procsig->ps_flag |= PS_NOCLDWAIT; mtx_lock(&p2->p_sigacts->ps_mtx);
p2->p_sigacts->ps_flag |= PS_NOCLDWAIT;
mtx_unlock(&p2->p_sigacts->ps_mtx);
_PHOLD(p2); _PHOLD(p2);
PROC_UNLOCK(p2); PROC_UNLOCK(p2);

View File

@ -623,6 +623,7 @@ fill_kinfo_proc(p, kp)
struct tty *tp; struct tty *tp;
struct session *sp; struct session *sp;
struct timeval tv; struct timeval tv;
struct sigacts *ps;
td = FIRST_THREAD_IN_PROC(p); td = FIRST_THREAD_IN_PROC(p);
@ -653,9 +654,12 @@ fill_kinfo_proc(p, kp)
kp->ki_rgid = p->p_ucred->cr_rgid; kp->ki_rgid = p->p_ucred->cr_rgid;
kp->ki_svgid = p->p_ucred->cr_svgid; kp->ki_svgid = p->p_ucred->cr_svgid;
} }
if (p->p_procsig) { if (p->p_sigacts) {
kp->ki_sigignore = p->p_procsig->ps_sigignore; ps = p->p_sigacts;
kp->ki_sigcatch = p->p_procsig->ps_sigcatch; mtx_lock(&ps->ps_mtx);
kp->ki_sigignore = ps->ps_sigignore;
kp->ki_sigcatch = ps->ps_sigcatch;
mtx_unlock(&ps->ps_mtx);
} }
mtx_lock_spin(&sched_lock); mtx_lock_spin(&sched_lock);
if (p->p_state != PRS_NEW && if (p->p_state != PRS_NEW &&

View File

@ -181,6 +181,7 @@ int
cursig(struct thread *td) cursig(struct thread *td)
{ {
PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
mtx_assert(&td->td_proc->p_sigacts->ps_mtx, MA_OWNED);
mtx_assert(&sched_lock, MA_NOTOWNED); mtx_assert(&sched_lock, MA_NOTOWNED);
return (SIGPENDING(td) ? issignal(td) : 0); return (SIGPENDING(td) ? issignal(td) : 0);
} }
@ -267,16 +268,16 @@ kern_sigaction(td, sig, act, oact, flags)
struct sigaction *act, *oact; struct sigaction *act, *oact;
int flags; int flags;
{ {
register struct sigacts *ps; struct sigacts *ps;
struct thread *td0; struct thread *td0;
struct proc *p = td->td_proc; struct proc *p = td->td_proc;
if (!_SIG_VALID(sig)) if (!_SIG_VALID(sig))
return (EINVAL); return (EINVAL);
mtx_lock(&Giant);
PROC_LOCK(p); PROC_LOCK(p);
ps = p->p_sigacts; ps = p->p_sigacts;
mtx_lock(&ps->ps_mtx);
if (oact) { if (oact) {
oact->sa_handler = ps->ps_sigact[_SIG_IDX(sig)]; oact->sa_handler = ps->ps_sigact[_SIG_IDX(sig)];
oact->sa_mask = ps->ps_catchmask[_SIG_IDX(sig)]; oact->sa_mask = ps->ps_catchmask[_SIG_IDX(sig)];
@ -291,16 +292,16 @@ kern_sigaction(td, sig, act, oact, flags)
oact->sa_flags |= SA_NODEFER; oact->sa_flags |= SA_NODEFER;
if (SIGISMEMBER(ps->ps_siginfo, sig)) if (SIGISMEMBER(ps->ps_siginfo, sig))
oact->sa_flags |= SA_SIGINFO; oact->sa_flags |= SA_SIGINFO;
if (sig == SIGCHLD && p->p_procsig->ps_flag & PS_NOCLDSTOP) if (sig == SIGCHLD && ps->ps_flag & PS_NOCLDSTOP)
oact->sa_flags |= SA_NOCLDSTOP; oact->sa_flags |= SA_NOCLDSTOP;
if (sig == SIGCHLD && p->p_procsig->ps_flag & PS_NOCLDWAIT) if (sig == SIGCHLD && ps->ps_flag & PS_NOCLDWAIT)
oact->sa_flags |= SA_NOCLDWAIT; oact->sa_flags |= SA_NOCLDWAIT;
} }
if (act) { if (act) {
if ((sig == SIGKILL || sig == SIGSTOP) && if ((sig == SIGKILL || sig == SIGSTOP) &&
act->sa_handler != SIG_DFL) { act->sa_handler != SIG_DFL) {
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
mtx_unlock(&Giant);
return (EINVAL); return (EINVAL);
} }
@ -342,9 +343,9 @@ kern_sigaction(td, sig, act, oact, flags)
#endif #endif
if (sig == SIGCHLD) { if (sig == SIGCHLD) {
if (act->sa_flags & SA_NOCLDSTOP) if (act->sa_flags & SA_NOCLDSTOP)
p->p_procsig->ps_flag |= PS_NOCLDSTOP; ps->ps_flag |= PS_NOCLDSTOP;
else else
p->p_procsig->ps_flag &= ~PS_NOCLDSTOP; ps->ps_flag &= ~PS_NOCLDSTOP;
if (act->sa_flags & SA_NOCLDWAIT) { if (act->sa_flags & SA_NOCLDWAIT) {
/* /*
* Paranoia: since SA_NOCLDWAIT is implemented * Paranoia: since SA_NOCLDWAIT is implemented
@ -353,20 +354,20 @@ kern_sigaction(td, sig, act, oact, flags)
* is forbidden to set SA_NOCLDWAIT. * is forbidden to set SA_NOCLDWAIT.
*/ */
if (p->p_pid == 1) if (p->p_pid == 1)
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT; ps->ps_flag &= ~PS_NOCLDWAIT;
else else
p->p_procsig->ps_flag |= PS_NOCLDWAIT; ps->ps_flag |= PS_NOCLDWAIT;
} else } else
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT; ps->ps_flag &= ~PS_NOCLDWAIT;
if (ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN) if (ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN)
p->p_procsig->ps_flag |= PS_CLDSIGIGN; ps->ps_flag |= PS_CLDSIGIGN;
else else
p->p_procsig->ps_flag &= ~PS_CLDSIGIGN; ps->ps_flag &= ~PS_CLDSIGIGN;
} }
/* /*
* Set bit in p_sigignore for signals that are set to SIG_IGN, * Set bit in ps_sigignore for signals that are set to SIG_IGN,
* and for signals set to SIG_DFL where the default is to * and for signals set to SIG_DFL where the default is to
* ignore. However, don't put SIGCONT in p_sigignore, as we * ignore. However, don't put SIGCONT in ps_sigignore, as we
* have to restart the process. * have to restart the process.
*/ */
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN || if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
@ -378,14 +379,14 @@ kern_sigaction(td, sig, act, oact, flags)
SIGDELSET(td0->td_siglist, sig); SIGDELSET(td0->td_siglist, sig);
if (sig != SIGCONT) if (sig != SIGCONT)
/* easier in psignal */ /* easier in psignal */
SIGADDSET(p->p_sigignore, sig); SIGADDSET(ps->ps_sigignore, sig);
SIGDELSET(p->p_sigcatch, sig); SIGDELSET(ps->ps_sigcatch, sig);
} else { } else {
SIGDELSET(p->p_sigignore, sig); SIGDELSET(ps->ps_sigignore, sig);
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL) if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)
SIGDELSET(p->p_sigcatch, sig); SIGDELSET(ps->ps_sigcatch, sig);
else else
SIGADDSET(p->p_sigcatch, sig); SIGADDSET(ps->ps_sigcatch, sig);
} }
#ifdef COMPAT_FREEBSD4 #ifdef COMPAT_FREEBSD4
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN || if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
@ -404,8 +405,8 @@ kern_sigaction(td, sig, act, oact, flags)
SIGADDSET(ps->ps_osigset, sig); SIGADDSET(ps->ps_osigset, sig);
#endif #endif
} }
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
mtx_unlock(&Giant);
return (0); return (0);
} }
@ -543,11 +544,15 @@ siginit(p)
struct proc *p; struct proc *p;
{ {
register int i; register int i;
struct sigacts *ps;
PROC_LOCK(p); PROC_LOCK(p);
ps = p->p_sigacts;
mtx_lock(&ps->ps_mtx);
for (i = 1; i <= NSIG; i++) for (i = 1; i <= NSIG; i++)
if (sigprop(i) & SA_IGNORE && i != SIGCONT) if (sigprop(i) & SA_IGNORE && i != SIGCONT)
SIGADDSET(p->p_sigignore, i); SIGADDSET(ps->ps_sigignore, i);
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
} }
@ -568,12 +573,13 @@ execsigs(p)
*/ */
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
ps = p->p_sigacts; ps = p->p_sigacts;
while (SIGNOTEMPTY(p->p_sigcatch)) { mtx_lock(&ps->ps_mtx);
sig = sig_ffs(&p->p_sigcatch); while (SIGNOTEMPTY(ps->ps_sigcatch)) {
SIGDELSET(p->p_sigcatch, sig); sig = sig_ffs(&ps->ps_sigcatch);
SIGDELSET(ps->ps_sigcatch, sig);
if (sigprop(sig) & SA_IGNORE) { if (sigprop(sig) & SA_IGNORE) {
if (sig != SIGCONT) if (sig != SIGCONT)
SIGADDSET(p->p_sigignore, sig); SIGADDSET(ps->ps_sigignore, sig);
SIGDELSET(p->p_siglist, sig); SIGDELSET(p->p_siglist, sig);
/* /*
* There is only one thread at this point. * There is only one thread at this point.
@ -597,9 +603,10 @@ execsigs(p)
/* /*
* Reset no zombies if child dies flag as Solaris does. * Reset no zombies if child dies flag as Solaris does.
*/ */
p->p_procsig->ps_flag &= ~(PS_NOCLDWAIT | PS_CLDSIGIGN); ps->ps_flag &= ~(PS_NOCLDWAIT | PS_CLDSIGIGN);
if (ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN) if (ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN)
ps->ps_sigact[_SIG_IDX(SIGCHLD)] = SIG_DFL; ps->ps_sigact[_SIG_IDX(SIGCHLD)] = SIG_DFL;
mtx_unlock(&ps->ps_mtx);
} }
/* /*
@ -822,14 +829,13 @@ kern_sigtimedwait(struct thread *td, sigset_t set, siginfo_t *info,
sig = 0; sig = 0;
SIG_CANTMASK(set); SIG_CANTMASK(set);
mtx_lock(&Giant);
PROC_LOCK(p); PROC_LOCK(p);
ps = p->p_sigacts; ps = p->p_sigacts;
oldmask = td->td_sigmask; oldmask = td->td_sigmask;
td->td_sigmask = set; td->td_sigmask = set;
signotify(td); signotify(td);
mtx_lock(&ps->ps_mtx);
sig = cursig(td); sig = cursig(td);
if (sig) if (sig)
goto out; goto out;
@ -850,7 +856,9 @@ kern_sigtimedwait(struct thread *td, sigset_t set, siginfo_t *info,
} else } else
hz = 0; hz = 0;
mtx_unlock(&ps->ps_mtx);
error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "pause", hz); error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "pause", hz);
mtx_lock(&ps->ps_mtx);
if (error == EINTR) if (error == EINTR)
error = 0; error = 0;
else if (error) else if (error)
@ -863,6 +871,7 @@ out:
sig_t action; sig_t action;
action = ps->ps_sigact[_SIG_IDX(sig)]; action = ps->ps_sigact[_SIG_IDX(sig)];
mtx_unlock(&ps->ps_mtx);
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_PSIG)) if (KTRPOINT(td, KTR_PSIG))
ktrpsig(sig, action, td->td_flags & TDF_OLDMASK ? ktrpsig(sig, action, td->td_flags & TDF_OLDMASK ?
@ -877,11 +886,9 @@ out:
SIGDELSET(td->td_siglist, sig); SIGDELSET(td->td_siglist, sig);
info->si_signo = sig; info->si_signo = sig;
info->si_code = 0; info->si_code = 0;
} } else
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
mtx_unlock(&Giant);
return (error); return (error);
} }
@ -1330,39 +1337,30 @@ kill(td, uap)
register struct kill_args *uap; register struct kill_args *uap;
{ {
register struct proc *p; register struct proc *p;
int error = 0; int error;
if ((u_int)uap->signum > _SIG_MAXSIG) if ((u_int)uap->signum > _SIG_MAXSIG)
return (EINVAL); return (EINVAL);
mtx_lock(&Giant);
if (uap->pid > 0) { if (uap->pid > 0) {
/* kill single process */ /* kill single process */
if ((p = pfind(uap->pid)) == NULL) { if ((p = pfind(uap->pid)) == NULL)
error = ESRCH; return (ESRCH);
} else if ((error = p_cansignal(td, p, uap->signum)) != 0) { error = p_cansignal(td, p, uap->signum);
PROC_UNLOCK(p); if (error == 0 && uap->signum)
} else { psignal(p, uap->signum);
if (uap->signum) PROC_UNLOCK(p);
psignal(p, uap->signum); return (error);
PROC_UNLOCK(p);
error = 0;
}
} else {
switch (uap->pid) {
case -1: /* broadcast signal */
error = killpg1(td, uap->signum, 0, 1);
break;
case 0: /* signal own process group */
error = killpg1(td, uap->signum, 0, 0);
break;
default: /* negative explicit process group */
error = killpg1(td, uap->signum, -uap->pid, 0);
break;
}
} }
mtx_unlock(&Giant); switch (uap->pid) {
return(error); case -1: /* broadcast signal */
return (killpg1(td, uap->signum, 0, 1));
case 0: /* signal own process group */
return (killpg1(td, uap->signum, 0, 0));
default: /* negative explicit process group */
return (killpg1(td, uap->signum, -uap->pid, 0));
}
/* NOTREACHED */
} }
#if defined(COMPAT_43) || defined(COMPAT_SUNOS) #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
@ -1381,14 +1379,10 @@ okillpg(td, uap)
struct thread *td; struct thread *td;
register struct okillpg_args *uap; register struct okillpg_args *uap;
{ {
int error;
if ((u_int)uap->signum > _SIG_MAXSIG) if ((u_int)uap->signum > _SIG_MAXSIG)
return (EINVAL); return (EINVAL);
mtx_lock(&Giant); return (killpg1(td, uap->signum, uap->pgid, 0));
error = killpg1(td, uap->signum, uap->pgid, 0);
mtx_unlock(&Giant);
return (error);
} }
#endif /* COMPAT_43 || COMPAT_SUNOS */ #endif /* COMPAT_43 || COMPAT_SUNOS */
@ -1451,7 +1445,8 @@ trapsignal(struct thread *td, int sig, u_long code)
PROC_LOCK(p); PROC_LOCK(p);
ps = p->p_sigacts; ps = p->p_sigacts;
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(p->p_sigcatch, sig) && mtx_lock(&ps->ps_mtx);
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) &&
!SIGISMEMBER(td->td_sigmask, sig)) { !SIGISMEMBER(td->td_sigmask, sig)) {
p->p_stats->p_ru.ru_nsignals++; p->p_stats->p_ru.ru_nsignals++;
#ifdef KTRACE #ifdef KTRACE
@ -1468,13 +1463,15 @@ trapsignal(struct thread *td, int sig, u_long code)
/* /*
* See kern_sigaction() for origin of this code. * See kern_sigaction() for origin of this code.
*/ */
SIGDELSET(p->p_sigcatch, sig); SIGDELSET(ps->ps_sigcatch, sig);
if (sig != SIGCONT && if (sig != SIGCONT &&
sigprop(sig) & SA_IGNORE) sigprop(sig) & SA_IGNORE)
SIGADDSET(p->p_sigignore, sig); SIGADDSET(ps->ps_sigignore, sig);
ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
} }
mtx_unlock(&ps->ps_mtx);
} else { } else {
mtx_unlock(&ps->ps_mtx);
p->p_code = code; /* XXX for core dump/debugger */ p->p_code = code; /* XXX for core dump/debugger */
p->p_sig = sig; /* XXX to verify code */ p->p_sig = sig; /* XXX to verify code */
tdsignal(td, sig); tdsignal(td, sig);
@ -1528,6 +1525,8 @@ sigtd(struct proc *p, int sig, int prop)
* regardless of the signal action (eg, blocked or ignored). * regardless of the signal action (eg, blocked or ignored).
* *
* Other ignored signals are discarded immediately. * Other ignored signals are discarded immediately.
*
* MPSAFE
*/ */
void void
psignal(struct proc *p, int sig) psignal(struct proc *p, int sig)
@ -1546,6 +1545,9 @@ psignal(struct proc *p, int sig)
tdsignal(td, sig); tdsignal(td, sig);
} }
/*
* MPSAFE
*/
void void
tdsignal(struct thread *td, int sig) tdsignal(struct thread *td, int sig)
{ {
@ -1554,12 +1556,13 @@ tdsignal(struct thread *td, int sig)
sigset_t *siglist; sigset_t *siglist;
struct thread *td0; struct thread *td0;
register int prop; register int prop;
struct sigacts *ps;
KASSERT(_SIG_VALID(sig), KASSERT(_SIG_VALID(sig),
("tdsignal(): invalid signal %d\n", sig)); ("tdsignal(): invalid signal %d\n", sig));
p = td->td_proc; p = td->td_proc;
ps = p->p_sigacts;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
KNOTE(&p->p_klist, NOTE_SIGNAL | sig); KNOTE(&p->p_klist, NOTE_SIGNAL | sig);
@ -1586,18 +1589,23 @@ tdsignal(struct thread *td, int sig)
/* /*
* If the signal is being ignored, * If the signal is being ignored,
* then we forget about it immediately. * then we forget about it immediately.
* (Note: we don't set SIGCONT in p_sigignore, * (Note: we don't set SIGCONT in ps_sigignore,
* and if it is set to SIG_IGN, * and if it is set to SIG_IGN,
* action will be SIG_DFL here.) * action will be SIG_DFL here.)
*/ */
if (SIGISMEMBER(p->p_sigignore, sig) || (p->p_flag & P_WEXIT)) mtx_lock(&ps->ps_mtx);
if (SIGISMEMBER(ps->ps_sigignore, sig) ||
(p->p_flag & P_WEXIT)) {
mtx_unlock(&ps->ps_mtx);
return; return;
}
if (SIGISMEMBER(td->td_sigmask, sig)) if (SIGISMEMBER(td->td_sigmask, sig))
action = SIG_HOLD; action = SIG_HOLD;
else if (SIGISMEMBER(p->p_sigcatch, sig)) else if (SIGISMEMBER(ps->ps_sigcatch, sig))
action = SIG_CATCH; action = SIG_CATCH;
else else
action = SIG_DFL; action = SIG_DFL;
mtx_unlock(&ps->ps_mtx);
} }
if (prop & SA_CONT) { if (prop & SA_CONT) {
@ -1890,13 +1898,14 @@ issignal(td)
struct thread *td; struct thread *td;
{ {
struct proc *p; struct proc *p;
struct sigacts *ps;
sigset_t sigpending; sigset_t sigpending;
register int sig, prop; register int sig, prop;
p = td->td_proc; p = td->td_proc;
ps = p->p_sigacts;
mtx_assert(&ps->ps_mtx, MA_OWNED);
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, &p->p_mtx.mtx_object,
"Checking for signals");
for (;;) { for (;;) {
int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG);
@ -1916,7 +1925,7 @@ issignal(td)
* We should see pending but ignored signals * We should see pending but ignored signals
* only if P_TRACED was on when they were posted. * only if P_TRACED was on when they were posted.
*/ */
if (SIGISMEMBER(p->p_sigignore, sig) && (traced == 0)) { if (SIGISMEMBER(ps->ps_sigignore, sig) && (traced == 0)) {
SIGDELSET(td->td_siglist, sig); SIGDELSET(td->td_siglist, sig);
continue; continue;
} }
@ -1924,6 +1933,9 @@ issignal(td)
/* /*
* If traced, always stop. * If traced, always stop.
*/ */
mtx_unlock(&ps->ps_mtx);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
&p->p_mtx.mtx_object, "Stopping for traced signal");
p->p_xstat = sig; p->p_xstat = sig;
PROC_LOCK(p->p_pptr); PROC_LOCK(p->p_pptr);
psignal(p->p_pptr, SIGCHLD); psignal(p->p_pptr, SIGCHLD);
@ -1938,11 +1950,12 @@ issignal(td)
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
PICKUP_GIANT(); PICKUP_GIANT();
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&ps->ps_mtx);
/* /*
* If the traced bit got turned off, go back up * If the traced bit got turned off, go back up
* to the top to rescan signals. This ensures * to the top to rescan signals. This ensures
* that p_sig* and ps_sigact are consistent. * that p_sig* and p_sigacts are consistent.
*/ */
if ((p->p_flag & P_TRACED) == 0) if ((p->p_flag & P_TRACED) == 0)
continue; continue;
@ -2001,6 +2014,9 @@ issignal(td)
(p->p_pgrp->pg_jobc == 0 && (p->p_pgrp->pg_jobc == 0 &&
prop & SA_TTYSTOP)) prop & SA_TTYSTOP))
break; /* == ignore */ break; /* == ignore */
mtx_unlock(&ps->ps_mtx);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
&p->p_mtx.mtx_object, "Catching SIGSTOP");
p->p_flag |= P_STOPPED_SIG; p->p_flag |= P_STOPPED_SIG;
p->p_xstat = sig; p->p_xstat = sig;
mtx_lock_spin(&sched_lock); mtx_lock_spin(&sched_lock);
@ -2013,6 +2029,7 @@ issignal(td)
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
PICKUP_GIANT(); PICKUP_GIANT();
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&ps->ps_mtx);
break; break;
} else if (prop & SA_IGNORE) { } else if (prop & SA_IGNORE) {
/* /*
@ -2063,10 +2080,14 @@ stop(struct proc *p)
wakeup(p->p_pptr); wakeup(p->p_pptr);
} }
/*
* MPSAFE
*/
void void
thread_stopped(struct proc *p) thread_stopped(struct proc *p)
{ {
struct proc *p1 = curthread->td_proc; struct proc *p1 = curthread->td_proc;
struct sigacts *ps;
int n; int n;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
@ -2078,10 +2099,13 @@ thread_stopped(struct proc *p)
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
stop(p); stop(p);
PROC_LOCK(p->p_pptr); PROC_LOCK(p->p_pptr);
if ((p->p_pptr->p_procsig->ps_flag & ps = p->p_pptr->p_sigacts;
PS_NOCLDSTOP) == 0) { mtx_lock(&ps->ps_mtx);
if ((ps->ps_flag & PS_NOCLDSTOP) == 0) {
mtx_unlock(&ps->ps_mtx);
psignal(p->p_pptr, SIGCHLD); psignal(p->p_pptr, SIGCHLD);
} } else
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p->p_pptr); PROC_UNLOCK(p->p_pptr);
mtx_lock_spin(&sched_lock); mtx_lock_spin(&sched_lock);
} }
@ -2106,6 +2130,7 @@ postsig(sig)
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
ps = p->p_sigacts; ps = p->p_sigacts;
mtx_assert(&ps->ps_mtx, MA_OWNED);
SIGDELSET(td->td_siglist, sig); SIGDELSET(td->td_siglist, sig);
action = ps->ps_sigact[_SIG_IDX(sig)]; action = ps->ps_sigact[_SIG_IDX(sig)];
#ifdef KTRACE #ifdef KTRACE
@ -2120,6 +2145,7 @@ postsig(sig)
* Default action, where the default is to kill * Default action, where the default is to kill
* the process. (Other cases were ignored above.) * the process. (Other cases were ignored above.)
*/ */
mtx_unlock(&ps->ps_mtx);
sigexit(td, sig); sigexit(td, sig);
/* NOTREACHED */ /* NOTREACHED */
} else { } else {
@ -2153,10 +2179,10 @@ postsig(sig)
/* /*
* See kern_sigaction() for origin of this code. * See kern_sigaction() for origin of this code.
*/ */
SIGDELSET(p->p_sigcatch, sig); SIGDELSET(ps->ps_sigcatch, sig);
if (sig != SIGCONT && if (sig != SIGCONT &&
sigprop(sig) & SA_IGNORE) sigprop(sig) & SA_IGNORE)
SIGADDSET(p->p_sigignore, sig); SIGADDSET(ps->ps_sigignore, sig);
ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
} }
p->p_stats->p_ru.ru_nsignals++; p->p_stats->p_ru.ru_nsignals++;
@ -2199,6 +2225,8 @@ killproc(p, why)
* signal state. Mark the accounting record with the signal termination. * signal state. Mark the accounting record with the signal termination.
* If dumping core, save the signal number for the debugger. Calls exit and * If dumping core, save the signal number for the debugger. Calls exit and
* does not return. * does not return.
*
* MPSAFE
*/ */
void void
sigexit(td, sig) sigexit(td, sig)
@ -2443,11 +2471,9 @@ nosys(td, args)
{ {
struct proc *p = td->td_proc; struct proc *p = td->td_proc;
mtx_lock(&Giant);
PROC_LOCK(p); PROC_LOCK(p);
psignal(p, SIGSYS); psignal(p, SIGSYS);
PROC_UNLOCK(p); PROC_UNLOCK(p);
mtx_unlock(&Giant);
return (ENOSYS); return (ENOSYS);
} }
@ -2532,3 +2558,57 @@ filt_signal(struct knote *kn, long hint)
} }
return (kn->kn_data != 0); return (kn->kn_data != 0);
} }
struct sigacts *
sigacts_alloc(void)
{
struct sigacts *ps;
ps = malloc(sizeof(struct sigacts), M_SUBPROC, M_WAITOK | M_ZERO);
ps->ps_refcnt = 1;
mtx_init(&ps->ps_mtx, "sigacts", NULL, MTX_DEF);
return (ps);
}
void
sigacts_free(struct sigacts *ps)
{
mtx_lock(&ps->ps_mtx);
ps->ps_refcnt--;
if (ps->ps_refcnt == 0) {
mtx_destroy(&ps->ps_mtx);
free(ps, M_SUBPROC);
} else
mtx_unlock(&ps->ps_mtx);
}
struct sigacts *
sigacts_hold(struct sigacts *ps)
{
mtx_lock(&ps->ps_mtx);
ps->ps_refcnt++;
mtx_unlock(&ps->ps_mtx);
return (ps);
}
void
sigacts_copy(struct sigacts *dest, struct sigacts *src)
{
KASSERT(dest->ps_refcnt == 1, ("sigacts_copy to shared dest"));
mtx_lock(&src->ps_mtx);
bcopy(src, dest, offsetof(struct sigacts, ps_refcnt));
mtx_unlock(&src->ps_mtx);
}
int
sigacts_shared(struct sigacts *ps)
{
int shared;
mtx_lock(&ps->ps_mtx);
shared = ps->ps_refcnt > 1;
mtx_unlock(&ps->ps_mtx);
return (shared);
}

View File

@ -230,7 +230,9 @@ msleep(ident, mtx, priority, wmesg, timo)
td->td_flags |= TDF_SINTR; td->td_flags |= TDF_SINTR;
mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sched_lock);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
sig = cursig(td); sig = cursig(td);
mtx_unlock(&p->p_sigacts->ps_mtx);
if (sig == 0 && thread_suspend_check(1)) if (sig == 0 && thread_suspend_check(1))
sig = SIGSTOP; sig = SIGSTOP;
mtx_lock_spin(&sched_lock); mtx_lock_spin(&sched_lock);
@ -291,12 +293,14 @@ msleep(ident, mtx, priority, wmesg, timo)
if (rval == 0 && catch) { if (rval == 0 && catch) {
PROC_LOCK(p); PROC_LOCK(p);
/* XXX: shouldn't we always be calling cursig() */ /* XXX: shouldn't we always be calling cursig() */
mtx_lock(&p->p_sigacts->ps_mtx);
if (sig != 0 || (sig = cursig(td))) { if (sig != 0 || (sig = cursig(td))) {
if (SIGISMEMBER(p->p_sigacts->ps_sigintr, sig)) if (SIGISMEMBER(p->p_sigacts->ps_sigintr, sig))
rval = EINTR; rval = EINTR;
else else
rval = ERESTART; rval = ERESTART;
} }
mtx_unlock(&p->p_sigacts->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
} }
#ifdef KTRACE #ifdef KTRACE

View File

@ -245,10 +245,12 @@ ast(struct trapframe *framep)
sigs = 0; sigs = 0;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx);
while ((sig = cursig(td)) != 0) { while ((sig = cursig(td)) != 0) {
postsig(sig); postsig(sig);
sigs++; sigs++;
} }
mtx_unlock(&p->p_sigacts->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
if (p->p_flag & P_THREADED && sigs) { if (p->p_flag & P_THREADED && sigs) {
struct kse_upcall *ku = td->td_upcall; struct kse_upcall *ku = td->td_upcall;

View File

@ -776,7 +776,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
sx_slock(&proctree_lock); sx_slock(&proctree_lock);
PROC_LOCK(p); PROC_LOCK(p);
while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) && while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
!SIGISMEMBER(p->p_sigignore, SIGTTOU) && !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
!SIGISMEMBER(td->td_sigmask, SIGTTOU)) { !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
pgrp = p->p_pgrp; pgrp = p->p_pgrp;
PROC_UNLOCK(p); PROC_UNLOCK(p);
@ -1934,7 +1934,7 @@ loop:
PROC_LOCK(p); PROC_LOCK(p);
if (isbackground(p, tp) && if (isbackground(p, tp) &&
ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) && ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
!SIGISMEMBER(p->p_sigignore, SIGTTOU) && !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
!SIGISMEMBER(td->td_sigmask, SIGTTOU)) { !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
if (p->p_pgrp->pg_jobc == 0) { if (p->p_pgrp->pg_jobc == 0) {
PROC_UNLOCK(p); PROC_UNLOCK(p);

View File

@ -235,7 +235,7 @@ again:
while (isbackground(p, tp)) { while (isbackground(p, tp)) {
sx_slock(&proctree_lock); sx_slock(&proctree_lock);
PROC_LOCK(p); PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
SIGISMEMBER(td->td_sigmask, SIGTTIN) || SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) { p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) {
PROC_UNLOCK(p); PROC_UNLOCK(p);

View File

@ -88,7 +88,9 @@ ncp_chkintr(struct ncp_conn *conn, struct thread *td)
tmpset = p->p_siglist; tmpset = p->p_siglist;
SIGSETOR(tmpset, td->td_siglist); SIGSETOR(tmpset, td->td_siglist);
SIGSETNAND(tmpset, td->td_sigmask); SIGSETNAND(tmpset, td->td_sigmask);
SIGSETNAND(tmpset, p->p_sigignore); mtx_lock(&p->p_sigacts->ps_mtx);
SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
mtx_unlock(&p->p_sigacts->ps_mtx);
if (SIGNOTEMPTY(td->td_siglist) && NCP_SIGMASK(tmpset)) { if (SIGNOTEMPTY(td->td_siglist) && NCP_SIGMASK(tmpset)) {
PROC_UNLOCK(p); PROC_UNLOCK(p);
return EINTR; return EINTR;

View File

@ -82,7 +82,9 @@ smb_td_intr(struct thread *td)
tmpset = p->p_siglist; tmpset = p->p_siglist;
SIGSETOR(tmpset, td->td_siglist); SIGSETOR(tmpset, td->td_siglist);
SIGSETNAND(tmpset, td->td_sigmask); SIGSETNAND(tmpset, td->td_sigmask);
SIGSETNAND(tmpset, p->p_sigignore); mtx_lock(&p->p_sigacts->ps_mtx);
SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
mtx_unlock(&p->p_sigacts->ps_mtx);
if (SIGNOTEMPTY(td->td_siglist) && SMB_SIGMASK(tmpset)) { if (SIGNOTEMPTY(td->td_siglist) && SMB_SIGMASK(tmpset)) {
PROC_UNLOCK(p); PROC_UNLOCK(p);
return EINTR; return EINTR;

View File

@ -1239,7 +1239,9 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
PROC_LOCK(p); PROC_LOCK(p);
tmpset = p->p_siglist; tmpset = p->p_siglist;
SIGSETNAND(tmpset, td->td_sigmask); SIGSETNAND(tmpset, td->td_sigmask);
SIGSETNAND(tmpset, p->p_sigignore); mtx_lock(&p->p_sigacts->ps_mtx);
SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
mtx_unlock(&p->p_sigacts->ps_mtx);
if (SIGNOTEMPTY(p->p_siglist) && NFSINT_SIGMASK(tmpset)) { if (SIGNOTEMPTY(p->p_siglist) && NFSINT_SIGMASK(tmpset)) {
PROC_UNLOCK(p); PROC_UNLOCK(p);
return (EINTR); return (EINTR);

View File

@ -315,6 +315,7 @@ osendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -328,7 +329,6 @@ osendsig(catcher, sig, mask, code)
#endif #endif
} else } else
fp = (struct osigframe *)regs->tf_esp - 1; fp = (struct osigframe *)regs->tf_esp - 1;
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -337,8 +337,7 @@ osendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_arg2 = (register_t)&fp->sf_siginfo; sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig; sf.sf_siginfo.si_signo = sig;
@ -350,6 +349,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* Save most if not all of trap frame. */ /* Save most if not all of trap frame. */
@ -422,6 +422,7 @@ osendsig(catcher, sig, mask, code)
load_gs(_udatasel); load_gs(_udatasel);
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#endif /* COMPAT_43 */ #endif /* COMPAT_43 */
@ -444,6 +445,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -467,7 +469,6 @@ freebsd4_sendsig(catcher, sig, mask, code)
#endif #endif
} else } else
sfp = (struct sigframe4 *)regs->tf_esp - 1; sfp = (struct sigframe4 *)regs->tf_esp - 1;
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -476,8 +477,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc; sf.sf_ucontext = (register_t)&sfp->sf_uc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_siginfo = (register_t)&sfp->sf_si;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -492,6 +492,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -543,6 +544,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#endif /* COMPAT_FREEBSD4 */ #endif /* COMPAT_FREEBSD4 */
@ -565,6 +567,7 @@ sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx,.MA_OWNED);
#ifdef COMPAT_FREEBSD4 #ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) { if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
freebsd4_sendsig(catcher, sig, mask, code); freebsd4_sendsig(catcher, sig, mask, code);
@ -605,7 +608,6 @@ sendsig(catcher, sig, mask, code)
sp = (char *)regs->tf_esp - sizeof(struct sigframe); sp = (char *)regs->tf_esp - sizeof(struct sigframe);
/* Align to 16 bytes. */ /* Align to 16 bytes. */
sfp = (struct sigframe *)((unsigned int)sp & ~0xF); sfp = (struct sigframe *)((unsigned int)sp & ~0xF);
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -614,8 +616,7 @@ sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc; sf.sf_ucontext = (register_t)&sfp->sf_uc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_siginfo = (register_t)&sfp->sf_si;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -630,6 +631,7 @@ sendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -681,6 +683,7 @@ sendsig(catcher, sig, mask, code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
/* /*

View File

@ -315,6 +315,7 @@ osendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -328,7 +329,6 @@ osendsig(catcher, sig, mask, code)
#endif #endif
} else } else
fp = (struct osigframe *)regs->tf_esp - 1; fp = (struct osigframe *)regs->tf_esp - 1;
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -337,8 +337,7 @@ osendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_arg2 = (register_t)&fp->sf_siginfo; sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig; sf.sf_siginfo.si_signo = sig;
@ -350,6 +349,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* Save most if not all of trap frame. */ /* Save most if not all of trap frame. */
@ -422,6 +422,7 @@ osendsig(catcher, sig, mask, code)
load_gs(_udatasel); load_gs(_udatasel);
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#endif /* COMPAT_43 */ #endif /* COMPAT_43 */
@ -444,6 +445,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
@ -467,7 +469,6 @@ freebsd4_sendsig(catcher, sig, mask, code)
#endif #endif
} else } else
sfp = (struct sigframe4 *)regs->tf_esp - 1; sfp = (struct sigframe4 *)regs->tf_esp - 1;
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -476,8 +477,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc; sf.sf_ucontext = (register_t)&sfp->sf_uc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_siginfo = (register_t)&sfp->sf_si;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -492,6 +492,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -543,6 +544,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#endif /* COMPAT_FREEBSD4 */ #endif /* COMPAT_FREEBSD4 */
@ -565,6 +567,7 @@ sendsig(catcher, sig, mask, code)
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx,.MA_OWNED);
#ifdef COMPAT_FREEBSD4 #ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) { if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
freebsd4_sendsig(catcher, sig, mask, code); freebsd4_sendsig(catcher, sig, mask, code);
@ -605,7 +608,6 @@ sendsig(catcher, sig, mask, code)
sp = (char *)regs->tf_esp - sizeof(struct sigframe); sp = (char *)regs->tf_esp - sizeof(struct sigframe);
/* Align to 16 bytes. */ /* Align to 16 bytes. */
sfp = (struct sigframe *)((unsigned int)sp & ~0xF); sfp = (struct sigframe *)((unsigned int)sp & ~0xF);
PROC_UNLOCK(p);
/* Translate the signal if appropriate. */ /* Translate the signal if appropriate. */
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
@ -614,8 +616,7 @@ sendsig(catcher, sig, mask, code)
/* Build the argument list for the signal handler. */ /* Build the argument list for the signal handler. */
sf.sf_signum = sig; sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc; sf.sf_ucontext = (register_t)&sfp->sf_uc;
PROC_LOCK(p); if (SIGISMEMBER(psp->ps_siginfo, sig)) {
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */ /* Signal handler installed with SA_SIGINFO. */
sf.sf_siginfo = (register_t)&sfp->sf_si; sf.sf_siginfo = (register_t)&sfp->sf_si;
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
@ -630,6 +631,7 @@ sendsig(catcher, sig, mask, code)
sf.sf_addr = regs->tf_err; sf.sf_addr = regs->tf_err;
sf.sf_ahu.sf_handler = catcher; sf.sf_ahu.sf_handler = catcher;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
/* /*
@ -681,6 +683,7 @@ sendsig(catcher, sig, mask, code)
regs->tf_fs = _udatasel; regs->tf_fs = _udatasel;
regs->tf_ss = _udatasel; regs->tf_ss = _udatasel;
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
/* /*

View File

@ -408,7 +408,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
td = curthread; td = curthread;
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame; tf = td->td_frame;
oonstack = sigonstack(tf->fixreg[1]); oonstack = sigonstack(tf->fixreg[1]);
@ -439,7 +441,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
} else { } else {
sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
} }
PROC_UNLOCK(p);
/* /*
* Translate the signal if appropriate (Linux emu ?) * Translate the signal if appropriate (Linux emu ?)
@ -466,9 +467,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
tf->fixreg[1] = (register_t)sfp; tf->fixreg[1] = (register_t)sfp;
tf->fixreg[FIRSTARG] = sig; tf->fixreg[FIRSTARG] = sig;
tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* /*
* Signal handler installed with SA_SIGINFO. * Signal handler installed with SA_SIGINFO.
*/ */
@ -484,6 +483,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Old FreeBSD-style arguments. */ /* Old FreeBSD-style arguments. */
tf->fixreg[FIRSTARG+1] = code; tf->fixreg[FIRSTARG+1] = code;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
@ -504,6 +504,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
tf->srr0, tf->fixreg[1]); tf->srr0, tf->fixreg[1]);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
int int

View File

@ -408,7 +408,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
td = curthread; td = curthread;
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame; tf = td->td_frame;
oonstack = sigonstack(tf->fixreg[1]); oonstack = sigonstack(tf->fixreg[1]);
@ -439,7 +441,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
} else { } else {
sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
} }
PROC_UNLOCK(p);
/* /*
* Translate the signal if appropriate (Linux emu ?) * Translate the signal if appropriate (Linux emu ?)
@ -466,9 +467,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
tf->fixreg[1] = (register_t)sfp; tf->fixreg[1] = (register_t)sfp;
tf->fixreg[FIRSTARG] = sig; tf->fixreg[FIRSTARG] = sig;
tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
/* /*
* Signal handler installed with SA_SIGINFO. * Signal handler installed with SA_SIGINFO.
*/ */
@ -484,6 +483,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Old FreeBSD-style arguments. */ /* Old FreeBSD-style arguments. */
tf->fixreg[FIRSTARG+1] = code; tf->fixreg[FIRSTARG+1] = code;
} }
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
@ -504,6 +504,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
tf->srr0, tf->fixreg[1]); tf->srr0, tf->fixreg[1]);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
int int

View File

@ -403,7 +403,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
oonstack = 0; oonstack = 0;
td = curthread; td = curthread;
p = td->td_proc; p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame; tf = td->td_frame;
sp = tf->tf_sp + SPOFF; sp = tf->tf_sp + SPOFF;
oonstack = sigonstack(sp); oonstack = sigonstack(sp);
@ -437,6 +439,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
p->p_sigstk.ss_size - sizeof(struct sigframe)); p->p_sigstk.ss_size - sizeof(struct sigframe));
} else } else
sfp = (struct sigframe *)sp - 1; sfp = (struct sigframe *)sp - 1;
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p); PROC_UNLOCK(p);
fp = (struct frame *)sfp - 1; fp = (struct frame *)sfp - 1;
@ -476,6 +479,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
tf->tf_sp); tf->tf_sp);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&psp->ps_mtx);
} }
#ifndef _SYS_SYSPROTO_H_ #ifndef _SYS_SYSPROTO_H_

View File

@ -102,18 +102,6 @@ struct pgrp {
struct mtx pg_mtx; /* Mutex to protect members */ struct mtx pg_mtx; /* Mutex to protect members */
}; };
struct procsig {
sigset_t ps_sigignore; /* Signals being ignored. */
sigset_t ps_sigcatch; /* Signals being caught by user. */
int ps_flag;
struct sigacts *ps_sigacts; /* Signal actions, state. */
int ps_refcnt;
};
#define PS_NOCLDWAIT 0x0001 /* No zombies if child dies */
#define PS_NOCLDSTOP 0x0002 /* No SIGCHLD when children stop. */
#define PS_CLDSIGIGN 0x0004 /* The SIGCHLD handler is SIG_IGN. */
/* /*
* pargs, used to hold a copy of the command line, if it had a sane length. * pargs, used to hold a copy of the command line, if it had a sane length.
*/ */
@ -157,6 +145,7 @@ struct pargs {
* o - ktrace lock * o - ktrace lock
* p - select lock (sellock) * p - select lock (sellock)
* r - p_peers lock * r - p_peers lock
* x - created at fork, only changes during single threading in exec
* z - zombie threads/kse/ksegroup lock * z - zombie threads/kse/ksegroup lock
* *
* If the locking key specifies two identifiers (for example, p_pptr) then * If the locking key specifies two identifiers (for example, p_pptr) then
@ -525,7 +514,7 @@ struct proc {
struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */ struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
struct plimit *p_limit; /* (c*) Process limits. */ struct plimit *p_limit; /* (c*) Process limits. */
struct vm_object *p_upages_obj; /* (a) Upages object. */ struct vm_object *p_upages_obj; /* (a) Upages object. */
struct procsig *p_procsig; /* (c) Signal actions, state (CPU). */ struct sigacts *p_sigacts; /* (x) Signal actions, state (CPU). */
/*struct ksegrp p_ksegrp; /*struct ksegrp p_ksegrp;
struct kse p_kse; */ struct kse p_kse; */
@ -614,9 +603,6 @@ struct proc {
}; };
#define p_rlimit p_limit->pl_rlimit #define p_rlimit p_limit->pl_rlimit
#define p_sigacts p_procsig->ps_sigacts
#define p_sigignore p_procsig->ps_sigignore
#define p_sigcatch p_procsig->ps_sigcatch
#define p_session p_pgrp->pg_session #define p_session p_pgrp->pg_session
#define p_pgid p_pgrp->pg_id #define p_pgid p_pgrp->pg_id

View File

@ -37,6 +37,8 @@
#ifndef _SYS_SIGNALVAR_H_ #ifndef _SYS_SIGNALVAR_H_
#define _SYS_SIGNALVAR_H_ #define _SYS_SIGNALVAR_H_
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/signal.h> #include <sys/signal.h>
/* /*
@ -45,8 +47,11 @@
*/ */
/* /*
* Process signal actions and state, needed only within the process * Logical process signal actions and state, needed only within the process
* (not necessarily resident). * The mapping between sigacts and proc structures is 1:1 except for rfork()
* processes masquerading as threads which use one structure for the whole
* group. All members are locked by the included mutex. The reference count
* and mutex must be last for the bcopy in sigacts_copy() to work.
*/ */
struct sigacts { struct sigacts {
sig_t ps_sigact[_SIG_MAXSIG]; /* Disposition of signals. */ sig_t ps_sigact[_SIG_MAXSIG]; /* Disposition of signals. */
@ -56,11 +61,20 @@ struct sigacts {
sigset_t ps_sigreset; /* Signals that reset when caught. */ sigset_t ps_sigreset; /* Signals that reset when caught. */
sigset_t ps_signodefer; /* Signals not masked while handled. */ sigset_t ps_signodefer; /* Signals not masked while handled. */
sigset_t ps_siginfo; /* Signals that want SA_SIGINFO args. */ sigset_t ps_siginfo; /* Signals that want SA_SIGINFO args. */
sigset_t ps_freebsd4; /* Signals using freebsd4 ucontext. */ sigset_t ps_sigignore; /* Signals being ignored. */
sigset_t ps_sigcatch; /* Signals being caught by user. */
sigset_t ps_freebsd4; /* signals using freebsd4 ucontext. */
sigset_t ps_osigset; /* Signals using <= 3.x osigset_t. */ sigset_t ps_osigset; /* Signals using <= 3.x osigset_t. */
sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX. */ sigset_t ps_usertramp; /* SunOS compat; libc sigtramp. XXX */
int ps_flag;
int ps_refcnt;
struct mtx ps_mtx;
}; };
#define PS_NOCLDWAIT 0x0001 /* No zombies if child dies */
#define PS_NOCLDSTOP 0x0002 /* No SIGCHLD when children stop. */
#define PS_CLDSIGIGN 0x0004 /* The SIGCHLD handler is SIG_IGN. */
#if defined(_KERNEL) && defined(COMPAT_43) #if defined(_KERNEL) && defined(COMPAT_43)
/* /*
* Compatibility. * Compatibility.
@ -243,6 +257,11 @@ void pgsigio(struct sigio **, int signum, int checkctty);
void pgsignal(struct pgrp *pgrp, int sig, int checkctty); void pgsignal(struct pgrp *pgrp, int sig, int checkctty);
void postsig(int sig); void postsig(int sig);
void psignal(struct proc *p, int sig); void psignal(struct proc *p, int sig);
struct sigacts *sigacts_alloc(void);
void sigacts_copy(struct sigacts *dest, struct sigacts *src);
void sigacts_free(struct sigacts *ps);
struct sigacts *sigacts_hold(struct sigacts *ps);
int sigacts_shared(struct sigacts *ps);
void sigexit(struct thread *td, int signum) __dead2; void sigexit(struct thread *td, int signum) __dead2;
int sig_ffs(sigset_t *set); int sig_ffs(sigset_t *set);
void siginit(struct proc *p); void siginit(struct proc *p);

View File

@ -174,7 +174,6 @@ void fill_kinfo_proc(struct proc *, struct kinfo_proc *);
* when the process isn't running (esp. when swapped out). * when the process isn't running (esp. when swapped out).
*/ */
struct user { struct user {
struct sigacts u_sigacts; /* *p_sigacts */
struct pstats u_stats; /* *p_stats */ struct pstats u_stats; /* *p_stats */
/* /*
* Remaining field for a.out core dumps - not valid at other times! * Remaining field for a.out core dumps - not valid at other times!

View File

@ -441,23 +441,14 @@ vm_forkproc(td, p2, td2, flags)
/* XXXKSE this is unsatisfactory but should be adequate */ /* XXXKSE this is unsatisfactory but should be adequate */
up = p2->p_uarea; up = p2->p_uarea;
MPASS(p2->p_sigacts != NULL);
/* /*
* p_stats currently points at fields in the user struct * p_stats currently points at fields in the user struct
* but not at &u, instead at p_addr. Copy parts of * but not at &u, instead at p_addr. Copy parts of
* p_stats; zero the rest of p_stats (statistics). * p_stats; zero the rest of p_stats (statistics).
*
* If procsig->ps_refcnt is 1 and p2->p_sigacts is NULL we dont' need
* to share sigacts, so we use the up->u_sigacts.
*/ */
p2->p_stats = &up->u_stats; p2->p_stats = &up->u_stats;
if (p2->p_sigacts == NULL) {
if (p2->p_procsig->ps_refcnt != 1)
printf ("PID:%d NULL sigacts with refcnt not 1!\n",p2->p_pid);
p2->p_sigacts = &up->u_sigacts;
up->u_sigacts = *p1->p_sigacts;
}
bzero(&up->u_stats.pstat_startzero, bzero(&up->u_stats.pstat_startzero,
(unsigned) ((caddr_t) &up->u_stats.pstat_endzero - (unsigned) ((caddr_t) &up->u_stats.pstat_endzero -
(caddr_t) &up->u_stats.pstat_startzero)); (caddr_t) &up->u_stats.pstat_startzero));
@ -465,7 +456,6 @@ vm_forkproc(td, p2, td2, flags)
((caddr_t) &up->u_stats.pstat_endcopy - ((caddr_t) &up->u_stats.pstat_endcopy -
(caddr_t) &up->u_stats.pstat_startcopy)); (caddr_t) &up->u_stats.pstat_startcopy));
/* /*
* cpu_fork will copy and update the pcb, set up the kernel stack, * cpu_fork will copy and update the pcb, set up the kernel stack,
* and make the child ready to run. * and make the child ready to run.