aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/machdep.c56
-rw-r--r--sys/alpha/alpha/trap.c8
-rw-r--r--sys/alpha/linux/linux_sysvec.c2
-rw-r--r--sys/alpha/osf1/osf1_signal.c8
-rw-r--r--sys/alpha/osf1/osf1_signal.h2
-rw-r--r--sys/amd64/amd64/machdep.c48
-rw-r--r--sys/amd64/amd64/trap.c48
-rw-r--r--sys/amd64/ia32/ia32_signal.c62
-rw-r--r--sys/amd64/ia32/ia32_syscall.c7
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c36
-rw-r--r--sys/arm/arm/machdep.c23
-rw-r--r--sys/arm/arm/trap.c10
-rw-r--r--sys/arm/arm/undefined.c21
-rw-r--r--sys/compat/ia32/ia32_signal.h4
-rw-r--r--sys/compat/linux/linux_misc.c2
-rw-r--r--sys/compat/svr4/svr4_signal.h4
-rw-r--r--sys/fs/procfs/procfs_ctl.c2
-rw-r--r--sys/i386/i386/machdep.c128
-rw-r--r--sys/i386/i386/trap.c53
-rw-r--r--sys/i386/linux/linux_sysvec.c36
-rw-r--r--sys/i386/svr4/svr4_machdep.c9
-rw-r--r--sys/ia64/ia32/ia32_signal.c4
-rw-r--r--sys/ia64/ia32/ia32_trap.c14
-rw-r--r--sys/ia64/ia64/machdep.c31
-rw-r--r--sys/ia64/ia64/trap.c6
-rw-r--r--sys/kern/init_sysent.c1
-rw-r--r--sys/kern/kern_exec.c2
-rw-r--r--sys/kern/kern_exit.c4
-rw-r--r--sys/kern/kern_kse.c17
-rw-r--r--sys/kern/kern_sig.c675
-rw-r--r--sys/kern/kern_thr.c3
-rw-r--r--sys/kern/kern_thread.c7
-rw-r--r--sys/kern/subr_trap.c6
-rw-r--r--sys/kern/syscalls.master2
-rw-r--r--sys/pc98/pc98/machdep.c64
-rw-r--r--sys/powerpc/aim/machdep.c29
-rw-r--r--sys/powerpc/aim/trap.c8
-rw-r--r--sys/powerpc/powerpc/machdep.c29
-rw-r--r--sys/powerpc/powerpc/trap.c8
-rw-r--r--sys/sparc64/sparc64/machdep.c30
-rw-r--r--sys/sparc64/sparc64/trap.c8
-rw-r--r--sys/sys/proc.h11
-rw-r--r--sys/sys/signalvar.h30
-rw-r--r--sys/sys/sysent.h5
44 files changed, 1038 insertions, 525 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index e09b5f692b93..b12e0398ff49 100644
--- a/sys/alpha/alpha/machdep.c
+++ b/sys/alpha/alpha/machdep.c
@@ -211,11 +211,10 @@ vm_offset_t phys_avail[10];
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
#ifdef COMPAT_43
-void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
+void osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
#endif
#ifdef COMPAT_FREEBSD4
-static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
- u_long code);
+static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
#endif
static void get_fpcontext(struct thread *td, mcontext_t *mcp);
@@ -1107,7 +1106,7 @@ DELAY(int n)
*/
#ifdef COMPAT_43
void
-osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+osendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
{
struct proc *p;
struct thread *td;
@@ -1115,10 +1114,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct trapframe *frame;
struct sigacts *psp;
int oonstack, fsize, rndfsize;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = kp->ksi_signo;
+ code = kp->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -1177,7 +1180,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Fill in POSIX parts */
ksi.si_signo = sig;
ksi.si_code = code;
- ksi.si_value.sigval_ptr = NULL; /* XXX */
+ ksi.si_value = kp->ksi_value;
/*
* copy the frame out to userland.
@@ -1212,7 +1215,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#ifdef COMPAT_FREEBSD4
static void
-freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+freebsd4_sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
{
struct proc *p;
struct thread *td;
@@ -1220,10 +1223,14 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct sigacts *psp;
struct sigframe4 sf, *sfp;
int oonstack, rndfsize;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = kp->ksi_signo;
+ code = kp->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -1308,9 +1315,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
/* Fill in POSIX parts */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0];
+ sf.sf_si = kp->ksi_info;
}
else
frame->tf_regs[FRAME_A1] = code;
@@ -1323,7 +1328,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#endif /* COMPAT_FREEBSD4 */
void
-sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
{
struct proc *p;
struct thread *td;
@@ -1331,21 +1336,25 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct sigacts *psp;
struct sigframe sf, *sfp;
int oonstack, rndfsize;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = kp->ksi_signo;
+ code = kp->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
#ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
- freebsd4_sendsig(catcher, sig, mask, code);
+ freebsd4_sendsig(catcher, kp, mask);
return;
}
#endif
#ifdef COMPAT_43
if (SIGISMEMBER(psp->ps_osigset, sig)) {
- osendsig(catcher, sig, mask, code);
+ osendsig(catcher, kp, mask);
return;
}
#endif
@@ -1432,9 +1441,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
/* Fill in POSIX parts */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0];
+ sf.sf_si = kp->ksi_info;
}
else
frame->tf_regs[FRAME_A1] = code;
@@ -1446,25 +1453,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
}
/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- /* XXXKSE fill other fields */
-}
-
-/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
* stack state from context left by sendsig (above).
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c
index dc800ef2d53c..7a62956f4f46 100644
--- a/sys/alpha/alpha/trap.c
+++ b/sys/alpha/alpha/trap.c
@@ -264,6 +264,7 @@ trap(a0, a1, a2, entry, framep)
#ifdef SMP
register_t s;
#endif
+ ksiginfo_t ksi;
/*
* Find our per-cpu globals.
@@ -585,7 +586,12 @@ trap(a0, a1, a2, entry, framep)
framep->tf_regs[FRAME_TRAPARG_A0] = a0;
framep->tf_regs[FRAME_TRAPARG_A1] = a1;
framep->tf_regs[FRAME_TRAPARG_A2] = a2;
- trapsignal(td, i, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = i;
+ ksi.ksi_code = ucode; /* XXX, Should be POSIX si_code */
+ ksi.ksi_addr = (void *)a0;
+ trapsignal(td, &ksi);
+
out:
if (user) {
framep->tf_regs[FRAME_SP] = alpha_pal_rdusp();
diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c
index 784ec81ef6e3..b6ce778471a0 100644
--- a/sys/alpha/linux/linux_sysvec.c
+++ b/sys/alpha/linux/linux_sysvec.c
@@ -77,7 +77,7 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
-void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
+void osendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask);
static int elf_linux_fixup(register_t **stack_base,
struct image_params *iparams);
diff --git a/sys/alpha/osf1/osf1_signal.c b/sys/alpha/osf1/osf1_signal.c
index 355cb1c20e9b..56e2298e7cda 100644
--- a/sys/alpha/osf1/osf1_signal.c
+++ b/sys/alpha/osf1/osf1_signal.c
@@ -459,7 +459,7 @@ osf1_kill(td, uap)
*/
void
-osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+osf1_sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
{
int fsize, oonstack, rndfsize;
struct thread *td;
@@ -467,10 +467,14 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
osiginfo_t *sip, ksi;
struct trapframe *frame;
struct sigacts *psp;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = kp->ksi_signo;
+ code = kp->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -526,7 +530,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Fill in POSIX parts */
ksi.si_signo = sig;
ksi.si_code = code;
- ksi.si_value.sigval_ptr = NULL; /* XXX */
+ ksi.si_value = kp->ksi_value;
/*
* copy the frame out to userland.
diff --git a/sys/alpha/osf1/osf1_signal.h b/sys/alpha/osf1/osf1_signal.h
index ec1fbeba43ae..1ef5ac4a678b 100644
--- a/sys/alpha/osf1/osf1_signal.h
+++ b/sys/alpha/osf1/osf1_signal.h
@@ -61,7 +61,7 @@ void bsd_to_osf1_sigaltstack(const struct sigaltstack *, struct osf1_sigaltstack
void bsd_to_osf1_sigset(const sigset_t *, osf1_sigset_t *);
void osf1_to_bsd_sigaltstack(const struct osf1_sigaltstack *, struct sigaltstack *);
void osf1_to_bsd_sigset(const osf1_sigset_t *, sigset_t *);
-void osf1_sendsig(sig_t, int , sigset_t *, u_long );
+void osf1_sendsig(sig_t, struct ksiginfo *, sigset_t *);
#endif /* !_OSF1_SIGNAL_H */
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 3dd95771edd7..d6d19a6b765a 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -237,11 +237,7 @@ cpu_startup(dummy)
* specified pc, psl.
*/
void
-sendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct sigframe sf, *sfp;
struct proc *p;
@@ -250,10 +246,12 @@ sendsig(catcher, sig, mask, code)
char *sp;
struct trapframe *regs;
int oonstack;
+ int sig;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame;
@@ -297,13 +295,13 @@ sendsig(catcher, sig, mask, code)
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
/* Fill in POSIX parts */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */
+ sf.sf_si = ksi->ksi_info;
+ sf.sf_si.si_signo = sig; /* maybe a translated signal */
+ regs->tf_rcx = (register_t)ksi->ksi_addr; /* arg 4 in %rcx */
} else {
/* Old FreeBSD-style arguments. */
- regs->tf_rsi = code; /* arg 2 in %rsi */
- regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */
+ regs->tf_rsi = ksi->ksi_code; /* arg 2 in %rsi */
+ regs->tf_rcx = (register_t)ksi->ksi_addr; /* arg 4 in %rcx */
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@@ -329,28 +327,6 @@ sendsig(catcher, sig, mask, code)
}
/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
- struct trapframe *regs;
-
- td = curthread;
- p = td->td_proc;
- regs = td->td_frame;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- si->si_addr = (void *)regs->tf_addr;
- /* XXXKSE fill other fields */
-}
-
-/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
* stack state from context left by sendsig (above).
@@ -374,6 +350,7 @@ sigreturn(td, uap)
const ucontext_t *ucp;
long rflags;
int cs, error, ret;
+ ksiginfo_t ksi;
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0)
@@ -407,7 +384,12 @@ sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_rip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 3f54d6add529..ed7417159cdf 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -161,6 +161,8 @@ trap(frame)
struct proc *p = td->td_proc;
u_int sticks = 0;
int i = 0, ucode = 0, type, code;
+ register_t addr = 0;
+ ksiginfo_t ksi;
PCPU_LAZY_INC(cnt.v_trap);
type = frame.tf_trapno;
@@ -241,13 +243,14 @@ trap(frame)
sticks = td->td_sticks;
td->td_frame = &frame;
+ addr = frame.tf_rip;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
- ucode = type;
i = SIGILL;
+ ucode = ILL_PRVOPC;
break;
case T_BPTFLT: /* bpt instruction fault */
@@ -255,6 +258,7 @@ trap(frame)
enable_intr();
frame.tf_rflags &= ~PSL_T;
i = SIGTRAP;
+ ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
break;
case T_ARITHTRAP: /* arithmetic trap */
@@ -265,16 +269,26 @@ trap(frame)
break;
case T_PROTFLT: /* general protection fault */
+ i = SIGBUS;
+ ucode = BUS_OBJERR;
+ break;
case T_STKFLT: /* stack fault */
case T_SEGNPFLT: /* segment not present fault */
+ i = SIGBUS;
+ ucode = BUS_ADRERR;
+ break;
case T_TSSFLT: /* invalid TSS fault */
+ i = SIGBUS;
+ ucode = BUS_OBJERR;
+ break;
case T_DOUBLEFLT: /* double fault */
default:
- ucode = code + BUS_SEGM_FAULT ;
i = SIGBUS;
+ ucode = BUS_OBJERR;
break;
case T_PAGEFLT: /* page fault */
+ addr = frame.tf_addr;
if (td->td_pflags & TDP_SA)
thread_user_enter(td);
i = trap_pfault(&frame, TRUE);
@@ -283,7 +297,12 @@ trap(frame)
if (i == 0)
goto user;
- ucode = T_PAGEFLT;
+ if (i == SIGSEGV)
+ ucode = SEGV_MAPERR;
+ else {
+ i = SIGSEGV; /* XXX hack */
+ ucode = SEGV_ACCERR;
+ }
break;
case T_DIVIDE: /* integer divide fault */
@@ -326,12 +345,14 @@ trap(frame)
/* transparent fault (due to context switch "late") */
if (fpudna())
goto userout;
- i = SIGFPE;
- ucode = FPE_FPU_NP_TRAP;
+ printf("pid %d killed due to lack of floating point\n",
+ p->p_pid);
+ i = SIGKILL;
+ ucode = 0;
break;
case T_FPOPFLT: /* FPU operand fetch fault */
- ucode = T_FPOPFLT;
+ ucode = ILL_COPROC;
i = SIGILL;
break;
@@ -472,7 +493,12 @@ trap(frame)
if (*p->p_sysent->sv_transtrap)
i = (*p->p_sysent->sv_transtrap)(i, type);
- trapsignal(td, i, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = i;
+ ksi.ksi_code = ucode;
+ ksi.ksi_trapno = type;
+ ksi.ksi_addr = (void *)addr;
+ trapsignal(td, &ksi);
#ifdef DEBUG
if (type <= MAX_TRAP_MSG) {
@@ -696,6 +722,7 @@ syscall(frame)
register_t *argp;
u_int code;
int reg, regcnt;
+ ksiginfo_t ksi;
/*
* note: PCPU_LAZY_INC() can only be used if we can afford
@@ -826,7 +853,12 @@ syscall(frame)
*/
if (orig_tf_rflags & PSL_T) {
frame.tf_rflags &= ~PSL_T;
- trapsignal(td, SIGTRAP, 0);
+
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_code = TRAP_TRACE;
+ ksi.ksi_addr = (void *)frame.tf_rip;
+ trapsignal(td, &ksi);
}
/*
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index b5533b554b19..116361a317e7 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#ifdef COMPAT_FREEBSD4
-static void freebsd4_ia32_sendsig(sig_t, int, sigset_t *, u_long);
+static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
#endif
static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp);
static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp);
@@ -295,18 +295,23 @@ freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
*/
#ifdef COMPAT_FREEBSD4
static void
-freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct ia32_sigframe4 sf, *sfp;
+ struct ia32_siginfo siginfo;
struct proc *p;
struct thread *td;
struct sigacts *psp;
struct trapframe *regs;
int oonstack;
+ int sig;
td = curthread;
p = td->td_proc;
+ siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo);
+
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = siginfo.si_signo;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame;
@@ -362,13 +367,12 @@ freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
/* Fill in POSIX parts */
+ sf.sf_si = siginfo;
sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = regs->tf_addr;
} else {
/* Old FreeBSD-style arguments. */
- sf.sf_siginfo = code;
- sf.sf_addr = regs->tf_addr;
+ sf.sf_siginfo = siginfo.si_code;
+ sf.sf_addr = (u_int32_t)siginfo.si_addr;
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
}
mtx_unlock(&psp->ps_mtx);
@@ -400,23 +404,27 @@ freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
#endif /* COMPAT_FREEBSD4 */
void
-ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct ia32_sigframe sf, *sfp;
+ struct ia32_siginfo siginfo;
struct proc *p;
struct thread *td;
struct sigacts *psp;
char *sp;
struct trapframe *regs;
int oonstack;
+ int sig;
+ siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo);
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = siginfo.si_signo;
psp = p->p_sigacts;
#ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
- freebsd4_ia32_sendsig(catcher, sig, mask, code);
+ freebsd4_ia32_sendsig(catcher, ksi, mask);
return;
}
#endif
@@ -479,13 +487,12 @@ ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
/* Fill in POSIX parts */
+ sf.sf_si = siginfo;
sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = regs->tf_addr;
} else {
/* Old FreeBSD-style arguments. */
- sf.sf_siginfo = code;
- sf.sf_addr = regs->tf_addr;
+ sf.sf_siginfo = siginfo.si_code;
+ sf.sf_addr = (u_int32_t)siginfo.si_addr;
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
}
mtx_unlock(&psp->ps_mtx);
@@ -540,6 +547,7 @@ freebsd4_freebsd32_sigreturn(td, uap)
struct trapframe *regs;
const struct ia32_ucontext4 *ucp;
int cs, eflags, error;
+ ksiginfo_t ksi;
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0)
@@ -573,7 +581,12 @@ freebsd4_freebsd32_sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_rip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
@@ -617,6 +630,7 @@ freebsd32_sigreturn(td, uap)
struct trapframe *regs;
const struct ia32_ucontext *ucp;
int cs, eflags, error, ret;
+ ksiginfo_t ksi;
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0)
@@ -650,7 +664,12 @@ freebsd32_sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_rip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
@@ -722,3 +741,18 @@ ia32_setregs(td, entry, stack, ps_strings)
pcb->pcb_flags |= PCB_FULLCTX;
td->td_retval[1] = 0;
}
+
+void
+siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst)
+{
+ dst->si_signo = src->si_signo;
+ dst->si_errno = src->si_errno;
+ dst->si_code = src->si_code;
+ dst->si_pid = src->si_pid;
+ dst->si_uid = src->si_uid;
+ dst->si_status = src->si_status;
+ dst->si_addr = dst->si_addr;
+ dst->si_value.sigval_int = src->si_value.sigval_int;
+ dst->si_band = src->si_band;
+ dst->__spare__[0] = src->si_trapno;
+}
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index f159cfb645cb..93d4e16a753c 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -101,6 +101,7 @@ ia32_syscall(struct trapframe frame)
u_int32_t args[8];
u_int64_t args64[8];
u_int code;
+ ksiginfo_t ksi;
/*
* note: PCPU_LAZY_INC() can only be used if we can afford
@@ -227,7 +228,11 @@ ia32_syscall(struct trapframe frame)
*/
if (orig_tf_rflags & PSL_T) {
frame.tf_rflags &= ~PSL_T;
- trapsignal(td, SIGTRAP, 0);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_code = TRAP_TRACE;
+ ksi.ksi_addr = (void *)frame.tf_rip;
+ trapsignal(td, &ksi);
}
/*
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index 0e687d1e11bc..b9e7a5d5737d 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -120,8 +120,7 @@ static int elf_linux_fixup(register_t **stack_base,
static register_t *linux_copyout_strings(struct image_params *imgp);
static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
caddr_t *params);
-static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
- u_long code);
+static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
static void exec_linux_setregs(struct thread *td, u_long entry,
u_long stack, u_long ps_strings);
static void linux32_fixlimits(struct image_params *imgp);
@@ -275,7 +274,7 @@ extern int _ucodesel, _ucode32sel, _udatasel;
extern unsigned long linux_sznonrtsigcode;
static void
-linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
@@ -283,7 +282,11 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct trapframe *regs;
struct l_rt_sigframe *fp, frame;
int oonstack;
-
+ int sig;
+ int code;
+
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -323,7 +326,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Fill in POSIX parts */
frame.sf_si.lsi_signo = sig;
frame.sf_si.lsi_code = code;
- frame.sf_si.lsi_addr = PTROUT(regs->tf_err);
+ frame.sf_si.lsi_addr = PTROUT(ksi->ksi_addr);
/*
* Build the signal context to be used by sigreturn.
@@ -411,7 +414,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
* specified pc, psl.
*/
static void
-linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
@@ -420,13 +423,16 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct l_sigframe *fp, frame;
l_sigset_t lmask;
int oonstack, i;
+ int sig, code;
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */
- linux_rt_sendsig(catcher, sig, mask, code);
+ linux_rt_sendsig(catcher, ksi, mask);
return;
}
@@ -534,6 +540,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
struct trapframe *regs;
l_sigset_t lmask;
int eflags, i;
+ ksiginfo_t ksi;
regs = td->td_frame;
@@ -574,7 +581,12 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
*/
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
if (!CS_SECURE(frame.sf_sc.sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_rip;
+ trapsignal(td, &ksi);
return(EINVAL);
}
@@ -627,6 +639,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
stack_t ss;
struct trapframe *regs;
int eflags;
+ ksiginfo_t ksi;
regs = td->td_frame;
@@ -669,7 +682,12 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
*/
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
if (!CS_SECURE(context->sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_rip;
+ trapsignal(td, &ksi);
return(EINVAL);
}
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 7043a7b54666..1e9f5b1c2f2e 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -101,11 +101,10 @@ int _min_memcpy_size = 0;
int _min_bzero_size = 0;
void
-sendsig(catcher, sig, mask, code)
+sendsig(catcher, ksi, mask)
sig_t catcher;
- int sig;
+ ksiginfo_t *ksi;
sigset_t *mask;
- u_long code;
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
@@ -113,9 +112,13 @@ sendsig(catcher, sig, mask, code)
struct sigframe *fp, frame;
struct sigacts *psp = td->td_proc->p_sigacts;
int onstack;
+ int sig;
+ int code;
onstack = sigonstack(td->td_frame->tf_usr_sp);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
if ((td->td_flags & TDP_ALTSTACK) &&
!(onstack) &&
SIGISMEMBER(td->td_proc->p_sigacts->ps_sigonstack, sig)) {
@@ -130,8 +133,7 @@ sendsig(catcher, sig, mask, code)
/* make the stack aligned */
fp = (struct sigframe *)STACKALIGN(fp);
/* Populate the siginfo frame. */
- frame.sf_si.si_signo = sig;
- frame.sf_si.si_code = code;
+ frame.sf_si = ksi->ksi_info;
frame.sf_uc.uc_sigmask = *mask;
frame.sf_uc.uc_link = NULL;
frame.sf_uc.uc_flags = (td->td_pflags & TDP_ALTSTACK )
@@ -436,17 +438,6 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
}
/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
-}
-
-/*
* Get machine context.
*/
int
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index 824878300e52..f858af08acdf 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -184,8 +184,12 @@ static const struct data_abort data_aborts[] = {
static __inline void
call_trapsignal(struct thread *td, int sig, u_long code)
{
+ ksiginfo_t ksi;
- trapsignal(td, sig, code);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = (int)code;
+ trapsignal(td, &ksi);
}
static __inline int
@@ -875,7 +879,7 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
nap = 4;
break;
default:
- trapsignal(td, SIGILL, 0);
+ call_trapsignal(td, SIGILL, 0);
userret(td, frame, td->td_sticks);
return;
}
@@ -993,7 +997,7 @@ swi_handler(trapframe_t *frame)
* don't take an alignment fault trying to read the opcode.
*/
if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
- trapsignal(td, SIGILL, 0);
+ call_trapsignal(td, SIGILL, 0);
userret(td, frame, td->td_sticks);
return;
}
diff --git a/sys/arm/arm/undefined.c b/sys/arm/arm/undefined.c
index 3d7d3cb2423e..94a3ec1493f9 100644
--- a/sys/arm/arm/undefined.c
+++ b/sys/arm/arm/undefined.c
@@ -134,11 +134,17 @@ static int
gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
{
struct thread *td;
+ ksiginfo_t ksi;
+
td = (curthread == NULL) ? &thread0 : curthread;
if (insn == GDB_BREAKPOINT || insn == GDB5_BREAKPOINT) {
if (code == FAULT_USER) {
- trapsignal(td, SIGTRAP, 0);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_code = TRAP_BRKPT;
+ ksi.ksi_addr = (u_int32_t *)addr;
+ trapsignal(td, &ksi);
return 0;
}
#if 0
@@ -179,6 +185,7 @@ undefinedinstruction(trapframe_t *frame)
#ifdef VERBOSE_ARM32
int s;
#endif
+ ksiginfo_t ksi;
/* Enable interrupts if they were enabled before the exception. */
if (!(frame->tf_spsr & I32_bit))
@@ -200,7 +207,11 @@ undefinedinstruction(trapframe_t *frame)
* don't take an alignment fault trying to read the opcode.
*/
if (__predict_false((fault_pc & 3) != 0)) {
- trapsignal(td, SIGILL, 0);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGILL;
+ ksi.ksi_code = ILL_ILLADR;
+ ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
+ trapsignal(td, &ksi);
userret(td, frame, 0);
return;
}
@@ -256,7 +267,11 @@ undefinedinstruction(trapframe_t *frame)
if (uh == NULL && (fault_code & FAULT_USER)) {
/* Fault has not been handled */
- trapsignal(td, SIGILL, 0);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGILL;
+ ksi.ksi_code = ILL_ILLOPC;
+ ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
+ trapsignal(td, &ksi);
}
if ((fault_code & FAULT_USER) == 0) {
diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h
index e79100a3c8f8..267d47293932 100644
--- a/sys/compat/ia32/ia32_signal.h
+++ b/sys/compat/ia32/ia32_signal.h
@@ -199,10 +199,12 @@ struct ia32_sigframe3 {
};
#endif
+struct ksiginfo;
extern char ia32_sigcode[];
extern char freebsd4_ia32_sigcode[];
extern int sz_ia32_sigcode;
extern int sz_freebsd4_ia32_sigcode;
-extern void ia32_sendsig(sig_t, int, sigset_t *, u_long);
+extern void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *);
extern void ia32_setregs(struct thread *td, u_long entry, u_long stack,
u_long ps_strings);
+extern void siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst);
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index eb9115d7f00d..4b85a43776e2 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -862,7 +862,7 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args)
p = td->td_proc;
PROC_LOCK(p);
- SIGDELSET(p->p_siglist, SIGCHLD);
+ sigqueue_delete(&p->p_sigqueue, SIGCHLD);
PROC_UNLOCK(p);
if (args->status) {
diff --git a/sys/compat/svr4/svr4_signal.h b/sys/compat/svr4/svr4_signal.h
index c3230fb1ee38..218236d9880c 100644
--- a/sys/compat/svr4/svr4_signal.h
+++ b/sys/compat/svr4/svr4_signal.h
@@ -133,10 +133,12 @@ struct svr4_sigaltstack {
#define SVR4_MINSIGSTKSZ 8192
+struct ksiginfo;
+
void bsd_to_svr4_sigaltstack(const struct sigaltstack *, struct svr4_sigaltstack *);
void bsd_to_svr4_sigset(const sigset_t *, svr4_sigset_t *);
void svr4_to_bsd_sigaltstack(const struct svr4_sigaltstack *, struct sigaltstack *);
void svr4_to_bsd_sigset(const svr4_sigset_t *, sigset_t *);
-void svr4_sendsig(sig_t, int, sigset_t *, u_long);
+void svr4_sendsig(sig_t, struct ksiginfo *, sigset_t *);
#endif /* !_SVR4_SIGNAL_H_ */
diff --git a/sys/fs/procfs/procfs_ctl.c b/sys/fs/procfs/procfs_ctl.c
index efe18c7931a2..13334fdece6c 100644
--- a/sys/fs/procfs/procfs_ctl.c
+++ b/sys/fs/procfs/procfs_ctl.c
@@ -215,7 +215,7 @@ out:
p->p_flag &= ~P_TRACED;
/* remove pending SIGTRAP, else the process will die */
- SIGDELSET(p->p_siglist, SIGTRAP);
+ sigqueue_delete_proc(p, SIGTRAP);
PROC_UNLOCK(p);
/* give process back to original parent */
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index f413a2090e42..fa29b9c4e28b 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -171,11 +171,10 @@ u_int basemem;
int cold = 1;
#ifdef COMPAT_43
-static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
+static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
#endif
#ifdef COMPAT_FREEBSD4
-static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
- u_long code);
+static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
#endif
long Maxmem = 0;
@@ -261,22 +260,20 @@ cpu_startup(dummy)
*/
#ifdef COMPAT_43
static void
-osendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
+osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct osigframe sf, *fp;
struct proc *p;
struct thread *td;
struct sigacts *psp;
struct trapframe *regs;
+ int sig;
int oonstack;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame;
@@ -304,12 +301,12 @@ osendsig(catcher, sig, mask, code)
/* Signal handler installed with SA_SIGINFO. */
sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig;
- sf.sf_siginfo.si_code = code;
+ sf.sf_siginfo.si_code = ksi->ksi_code;
sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
} else {
/* Old FreeBSD-style arguments. */
- sf.sf_arg2 = code;
- sf.sf_addr = regs->tf_err;
+ sf.sf_arg2 = ksi->ksi_code;
+ sf.sf_addr = (register_t)ksi->ksi_addr;
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@@ -391,22 +388,20 @@ osendsig(catcher, sig, mask, code)
#ifdef COMPAT_FREEBSD4
static void
-freebsd4_sendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
+freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct sigframe4 sf, *sfp;
struct proc *p;
struct thread *td;
struct sigacts *psp;
struct trapframe *regs;
+ int sig;
int oonstack;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame;
@@ -447,12 +442,12 @@ freebsd4_sendsig(catcher, sig, mask, code)
/* Fill in POSIX parts */
sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)regs->tf_err;
+ sf.sf_si.si_code = ksi->ksi_code;
+ sf.sf_si.si_addr = ksi->ksi_addr;
} else {
/* Old FreeBSD-style arguments. */
- sf.sf_siginfo = code;
- sf.sf_addr = regs->tf_err;
+ sf.sf_siginfo = ksi->ksi_code;
+ sf.sf_addr = (register_t)ksi->ksi_addr;
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@@ -512,11 +507,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
#endif /* COMPAT_FREEBSD4 */
void
-sendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct sigframe sf, *sfp;
struct proc *p;
@@ -524,22 +515,24 @@ sendsig(catcher, sig, mask, code)
struct sigacts *psp;
char *sp;
struct trapframe *regs;
+ int sig;
int oonstack;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
#ifdef COMPAT_FREEBSD4
if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
- freebsd4_sendsig(catcher, sig, mask, code);
+ freebsd4_sendsig(catcher, ksi, mask);
return;
}
#endif
#ifdef COMPAT_43
if (SIGISMEMBER(psp->ps_osigset, sig)) {
- osendsig(catcher, sig, mask, code);
+ osendsig(catcher, ksi, mask);
return;
}
#endif
@@ -585,13 +578,12 @@ sendsig(catcher, sig, mask, code)
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
/* Fill in POSIX parts */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)regs->tf_err;
+ sf.sf_si = ksi->ksi_info;
+ sf.sf_si.si_signo = sig; /* maybe a translated signal */
} else {
/* Old FreeBSD-style arguments. */
- sf.sf_siginfo = code;
- sf.sf_addr = regs->tf_err;
+ sf.sf_siginfo = ksi->ksi_code;
+ sf.sf_addr = (register_t)ksi->ksi_addr;
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@@ -650,26 +642,6 @@ sendsig(catcher, sig, mask, code)
}
/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- si->si_addr = (void *)td->td_frame->tf_err;
- /* XXXKSE fill other fields */
-}
-
-/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
* stack state from context left by sendsig (above).
@@ -693,6 +665,7 @@ osigreturn(td, uap)
struct osigcontext *scp;
struct proc *p = td->td_proc;
int eflags, error;
+ ksiginfo_t ksi;
regs = td->td_frame;
error = copyin(uap->sigcntxp, &sc, sizeof(sc));
@@ -715,8 +688,13 @@ osigreturn(td, uap)
return (EINVAL);
/* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
+ }
if (vm86->vm86_has_vme) {
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
@@ -757,7 +735,12 @@ osigreturn(td, uap)
* other selectors, invalid %eip's and invalid %esp's.
*/
if (!CS_SECURE(scp->sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
regs->tf_ds = scp->sc_ds;
@@ -811,6 +794,7 @@ freebsd4_sigreturn(td, uap)
struct trapframe *regs;
const struct ucontext4 *ucp;
int cs, eflags, error;
+ ksiginfo_t ksi;
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0)
@@ -833,9 +817,13 @@ freebsd4_sigreturn(td, uap)
return (EINVAL);
/* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
-
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
+ }
if (vm86->vm86_has_vme) {
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
(eflags & VME_USERCHANGE) | PSL_VM;
@@ -880,7 +868,12 @@ freebsd4_sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
@@ -918,6 +911,7 @@ sigreturn(td, uap)
struct trapframe *regs;
const ucontext_t *ucp;
int cs, eflags, error, ret;
+ ksiginfo_t ksi;
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0)
@@ -940,8 +934,13 @@ sigreturn(td, uap)
return (EINVAL);
/* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
+ }
if (vm86->vm86_has_vme) {
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
@@ -987,7 +986,12 @@ sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 6ab47a51046b..470353709017 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -175,7 +175,9 @@ trap(frame)
struct proc *p = td->td_proc;
u_int sticks = 0;
int i = 0, ucode = 0, type, code;
+ register_t addr = 0;
vm_offset_t eva;
+ ksiginfo_t ksi;
#ifdef POWERFAIL_NMI
static int lastalert = 0;
#endif
@@ -274,13 +276,14 @@ trap(frame)
sticks = td->td_sticks;
td->td_frame = &frame;
+ addr = frame.tf_eip;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
- ucode = type;
i = SIGILL;
+ ucode = ILL_PRVOPC;
break;
case T_BPTFLT: /* bpt instruction fault */
@@ -288,6 +291,7 @@ trap(frame)
enable_intr();
frame.tf_eflags &= ~PSL_T;
i = SIGTRAP;
+ ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
break;
case T_ARITHTRAP: /* arithmetic trap */
@@ -296,7 +300,7 @@ trap(frame)
if (ucode == -1)
goto userout;
#else
- ucode = code;
+ ucode = 0;
#endif
i = SIGFPE;
break;
@@ -314,14 +318,21 @@ trap(frame)
goto user;
break;
}
- /* FALLTHROUGH */
-
+ i = SIGBUS;
+ ucode = (type == T_PROTFLT) ? BUS_OBJERR : BUS_ADRERR;
+ break;
case T_SEGNPFLT: /* segment not present fault */
+ i = SIGBUS;
+ ucode = BUS_ADRERR;
+ break;
case T_TSSFLT: /* invalid TSS fault */
+ i = SIGBUS;
+ ucode = BUS_OBJERR;
+ break;
case T_DOUBLEFLT: /* double fault */
default:
- ucode = code + BUS_SEGM_FAULT ;
i = SIGBUS;
+ ucode = BUS_OBJERR;
break;
case T_PAGEFLT: /* page fault */
@@ -339,7 +350,7 @@ trap(frame)
type = frame.tf_trapno = T_PRIVINFLT;
/* Proceed as in that case. */
- ucode = type;
+ ucode = ILL_PRVOPC;
i = SIGILL;
break;
}
@@ -349,7 +360,13 @@ trap(frame)
if (i == 0)
goto user;
- ucode = T_PAGEFLT;
+ if (i == SIGSEGV)
+ ucode = SEGV_MAPERR;
+ else {
+ i = SIGSEGV; /* XXX hack */
+ ucode = SEGV_ACCERR;
+ }
+ addr = eva;
break;
case T_DIVIDE: /* integer divide fault */
@@ -408,12 +425,14 @@ trap(frame)
if (npxdna())
goto userout;
#endif
- i = SIGFPE;
- ucode = FPE_FPU_NP_TRAP;
+ printf("pid %d killed due to lack of floating point\n",
+ p->p_pid);
+ i = SIGKILL;
+ ucode = 0;
break;
case T_FPOPFLT: /* FPU operand fetch fault */
- ucode = T_FPOPFLT;
+ ucode = ILL_COPROC;
i = SIGILL;
break;
@@ -634,7 +653,12 @@ trap(frame)
if (*p->p_sysent->sv_transtrap)
i = (*p->p_sysent->sv_transtrap)(i, type);
- trapsignal(td, i, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = i;
+ ksi.ksi_code = ucode;
+ ksi.ksi_addr = (void *)addr;
+ ksi.ksi_trapno = type;
+ trapsignal(td, &ksi);
#ifdef DEBUG
if (type <= MAX_TRAP_MSG) {
@@ -879,6 +903,7 @@ syscall(frame)
int narg;
int args[8];
u_int code;
+ ksiginfo_t ksi;
/*
* note: PCPU_LAZY_INC() can only be used if we can afford
@@ -1017,7 +1042,11 @@ syscall(frame)
*/
if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
frame.tf_eflags &= ~PSL_T;
- trapsignal(td, SIGTRAP, 0);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_code = TRAP_TRACE;
+ ksi.ksi_addr = (void *)frame.tf_eip;
+ trapsignal(td, &ksi);
}
/*
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index db1b61703b27..89161833d312 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -107,8 +107,7 @@ static int elf_linux_fixup(register_t **stack_base,
struct image_params *iparams);
static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
caddr_t *params);
-static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
- u_long code);
+static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
static void exec_linux_setregs(struct thread *td, u_long entry,
u_long stack, u_long ps_strings);
@@ -267,15 +266,18 @@ extern int _ucodesel, _udatasel;
extern unsigned long linux_sznonrtsigcode;
static void
-linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
struct sigacts *psp;
struct trapframe *regs;
struct l_rt_sigframe *fp, frame;
+ int sig, code;
int oonstack;
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -315,7 +317,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Fill in POSIX parts */
frame.sf_si.lsi_signo = sig;
frame.sf_si.lsi_code = code;
- frame.sf_si.lsi_addr = (void *)regs->tf_err;
+ frame.sf_si.lsi_addr = ksi->ksi_addr;
/*
* Build the signal context to be used by sigreturn.
@@ -400,7 +402,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
* specified pc, psl.
*/
static void
-linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
@@ -408,17 +410,19 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct trapframe *regs;
struct l_sigframe *fp, frame;
l_sigset_t lmask;
+ int sig, code;
int oonstack, i;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
mtx_assert(&psp->ps_mtx, MA_OWNED);
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
/* Signal handler installed with SA_SIGINFO. */
- linux_rt_sendsig(catcher, sig, mask, code);
+ linux_rt_sendsig(catcher, ksi, mask);
return;
}
-
regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp);
@@ -475,7 +479,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_sc.sc_esp_at_signal = regs->tf_esp;
frame.sf_sc.sc_ss = regs->tf_ss;
frame.sf_sc.sc_err = regs->tf_err;
- frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
+ frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno);
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
frame.sf_extramask[i] = lmask.__bits[i+1];
@@ -522,6 +526,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
struct trapframe *regs;
l_sigset_t lmask;
int eflags, i;
+ ksiginfo_t ksi;
regs = td->td_frame;
@@ -562,7 +567,12 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
*/
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
if (!CS_SECURE(frame.sf_sc.sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return(EINVAL);
}
@@ -618,6 +628,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
stack_t ss;
struct trapframe *regs;
int eflags;
+ ksiginfo_t ksi;
regs = td->td_frame;
@@ -660,7 +671,12 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
*/
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
if (!CS_SECURE(context->sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return(EINVAL);
}
diff --git a/sys/i386/svr4/svr4_machdep.c b/sys/i386/svr4/svr4_machdep.c
index 3b731a23da8e..cc03dee7e842 100644
--- a/sys/i386/svr4/svr4_machdep.c
+++ b/sys/i386/svr4/svr4_machdep.c
@@ -411,11 +411,10 @@ svr4_getsiginfo(si, sig, code, addr)
* will return to the user pc, psl.
*/
void
-svr4_sendsig(catcher, sig, mask, code)
+svr4_sendsig(catcher, ksi, mask)
sig_t catcher;
- int sig;
+ ksiginfo_t ksi;
sigset_t *mask;
- u_long code;
{
register struct thread *td = curthread;
struct proc *p = td->td_proc;
@@ -423,11 +422,15 @@ svr4_sendsig(catcher, sig, mask, code)
struct svr4_sigframe *fp, frame;
struct sigacts *psp;
int oonstack;
+ int sig;
+ int code;
#if defined(DEBUG_SVR4)
printf("svr4_sendsig(%d)\n", sig);
#endif
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_trapno; /* use trap No. */
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
diff --git a/sys/ia64/ia32/ia32_signal.c b/sys/ia64/ia32/ia32_signal.c
index 6725cb33f912..b5b788a590c0 100644
--- a/sys/ia64/ia32/ia32_signal.c
+++ b/sys/ia64/ia32/ia32_signal.c
@@ -98,9 +98,9 @@ int sz_ia32_sigcode = sizeof(ia32_sigcode);
* sendsig() means that at least untrapped signals will work.
*/
void
-ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
- sendsig(catcher, sig, mask, code);
+ sendsig(catcher, ksi, mask);
}
#ifdef COMPAT_FREEBSD4
diff --git a/sys/ia64/ia32/ia32_trap.c b/sys/ia64/ia32/ia32_trap.c
index 58a805f60079..d93722ed522f 100644
--- a/sys/ia64/ia32/ia32_trap.c
+++ b/sys/ia64/ia32/ia32_trap.c
@@ -61,6 +61,7 @@ ia32_syscall(struct trapframe *tf)
register_t eflags;
u_int code;
int error, i, narg;
+ ksiginfo_t ksi;
PCPU_LAZY_INC(cnt.v_syscall);
@@ -168,7 +169,11 @@ ia32_syscall(struct trapframe *tf)
*/
if ((eflags & PSL_T) && !(eflags & PSL_VM)) {
ia64_set_eflag(ia64_get_eflag() & ~PSL_T);
- trapsignal(td, SIGTRAP, 0);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_code = TRAP_TRACE;
+ ksi.ksi_addr = (void *)tf->tf_special.iip;
+ trapsignal(td, &ksi);
}
#ifdef KTRACE
@@ -201,6 +206,7 @@ ia32_trap(int vector, struct trapframe *tf)
uint64_t ucode;
int sig;
u_int sticks;
+ ksiginfo_t ksi;
KASSERT(TRAPF_USERMODE(tf), ("%s: In kernel mode???", __func__));
@@ -284,7 +290,11 @@ ia32_trap(int vector, struct trapframe *tf)
KASSERT(sig != 0, ("%s: signal not set", __func__));
- trapsignal(td, sig, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = (int)ucode; /* XXX */
+ /* ksi.ksi_addr */
+ trapsignal(td, &ksi);
out:
userret(td, tf, sticks);
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 2baf57dd006c..19c4f83a3dcb 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -878,7 +878,7 @@ DELAY(int n)
* Send an interrupt (signal) to a process.
*/
void
-sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct proc *p;
struct thread *td;
@@ -887,10 +887,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct sigframe sf, *sfp;
u_int64_t sbs, sp;
int oonstack;
+ int sig;
+ u_long code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame;
@@ -926,8 +930,12 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Fill in the siginfo structure for POSIX handlers. */
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
+ sf.sf_si = ksi->ksi_info;
sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
+ /*
+ * XXX this shouldn't be here after code in trap.c
+ * is fixed
+ */
sf.sf_si.si_addr = (void*)tf->tf_special.ifa;
code = (u_int64_t)&sfp->sf_si;
}
@@ -979,25 +987,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
}
/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- /* XXXKSE fill other fields */
-}
-
-/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
* stack state from context left by sendsig (above).
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index d68482413912..432ac69799d3 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -361,6 +361,7 @@ trap(int vector, struct trapframe *tf)
uint64_t ucode;
int error, sig, user;
u_int sticks;
+ ksiginfo_t ksi;
user = TRAPF_USERMODE(tf) ? 1 : 0;
@@ -869,7 +870,10 @@ trap(int vector, struct trapframe *tf)
if (print_usertrap)
printtrap(vector, tf, 1, user);
- trapsignal(td, sig, ucode);
+ ksiginfo_init(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = ucode;
+ trapsignal(td, &ksi);
out:
if (user) {
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 4e5f6d926449..efeaa548fce7 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -485,4 +485,5 @@ struct sysent sysent[] = {
{ SYF_MPSAFE | AS(auditctl_args), (sy_call_t *)lkmressys, AUE_NULL }, /* 453 = auditctl */
{ SYF_MPSAFE | AS(_umtx_op_args), (sy_call_t *)_umtx_op, AUE_NULL }, /* 454 = _umtx_op */
{ SYF_MPSAFE | AS(thr_new_args), (sy_call_t *)thr_new, AUE_NULL }, /* 455 = thr_new */
+ { SYF_MPSAFE | AS(sigqueue_args), (sy_call_t *)sigqueue, AUE_NULL }, /* 456 = sigqueue */
};
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index d235b314b0dd..0d0ce88e2848 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -666,7 +666,7 @@ interpret:
* single thread mode.
*/
if (p->p_flag & P_TRACED)
- tdsignal(td, SIGTRAP, SIGTARGET_TD);
+ tdsignal(td, SIGTRAP, NULL, SIGTARGET_TD);
/* clear "fork but no exec" flag, as we _are_ execing */
p->p_acflag &= ~AFORK;
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 9878546df9d0..66f37ca572a4 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -207,8 +207,8 @@ retry:
PROC_LOCK(p);
stopprofclock(p);
p->p_flag &= ~(P_TRACED | P_PPWAIT);
- SIGEMPTYSET(p->p_siglist);
- SIGEMPTYSET(td->td_siglist);
+ sigqueue_flush(&p->p_sigqueue);
+ sigqueue_flush(&td->td_sigqueue);
/*
* Stop the real interval timer. If the handler is currently
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index 69ca17ae7396..f3c9a3e6cb95 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -210,7 +210,7 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap)
if (uap->data > 0) {
td2->td_flags &= ~TDF_INTERRUPT;
mtx_unlock_spin(&sched_lock);
- tdsignal(td2, (int)uap->data, SIGTARGET_TD);
+ tdsignal(td2, (int)uap->data, NULL, SIGTARGET_TD);
} else {
mtx_unlock_spin(&sched_lock);
}
@@ -342,6 +342,7 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
PROC_LOCK(p);
if (error)
psignal(p, SIGSEGV);
+ sigqueue_flush(&td->td_sigqueue);
mtx_lock_spin(&sched_lock);
upcall_remove(td);
if (p->p_numthreads != 1) {
@@ -697,8 +698,8 @@ kse_create(struct thread *td, struct kse_create_args *uap)
* SA threading will make a special thread to handle them.
*/
if (first && sa) {
- SIGSETOR(p->p_siglist, td->td_siglist);
- SIGEMPTYSET(td->td_siglist);
+ sigqueue_move_set(&td->td_sigqueue, &p->p_sigqueue,
+ &td->td_sigqueue.sq_signals);
SIGFILLSET(td->td_sigmask);
SIG_CANTMASK(td->td_sigmask);
}
@@ -1094,10 +1095,9 @@ thread_schedule_upcall(struct thread *td, struct kse_upcall *ku)
* debugged.
*/
void
-thread_signal_add(struct thread *td, int sig)
+thread_signal_add(struct thread *td, ksiginfo_t *ksi)
{
struct proc *p;
- siginfo_t siginfo;
struct sigacts *ps;
int error;
@@ -1106,11 +1106,11 @@ thread_signal_add(struct thread *td, int sig)
ps = p->p_sigacts;
mtx_assert(&ps->ps_mtx, MA_OWNED);
- cpu_thread_siginfo(sig, 0, &siginfo);
mtx_unlock(&ps->ps_mtx);
- SIGADDSET(td->td_sigmask, sig);
+ SIGADDSET(td->td_sigmask, ksi->ksi_signo);
PROC_UNLOCK(p);
- error = copyout(&siginfo, &td->td_mailbox->tm_syncsig, sizeof(siginfo));
+ error = copyout(&ksi->ksi_info, &td->td_mailbox->tm_syncsig,
+ sizeof(siginfo_t));
if (error) {
PROC_LOCK(p);
sigexit(td, SIGSEGV);
@@ -1315,6 +1315,7 @@ thread_userret(struct thread *td, struct trapframe *frame)
wakeup(&kg->kg_completed);
WITNESS_WARN(WARN_PANIC, &p->p_mtx.mtx_object,
"thread exiting in userret");
+ sigqueue_flush(&td->td_sigqueue);
mtx_lock_spin(&sched_lock);
thread_stopped(p);
thread_exit();
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 64fdfde1b793..f1b90c520b18 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -71,6 +71,9 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/unistd.h>
#include <sys/wait.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/uma.h>
#include <machine/cpu.h>
@@ -90,10 +93,15 @@ static int filt_sigattach(struct knote *kn);
static void filt_sigdetach(struct knote *kn);
static int filt_signal(struct knote *kn, long hint);
static struct thread *sigtd(struct proc *p, int sig, int prop);
-static int kern_sigtimedwait(struct thread *td, sigset_t set,
- siginfo_t *info, struct timespec *timeout);
-static void do_tdsignal(struct thread *td, int sig, sigtarget_t target);
-
+static int kern_sigtimedwait(struct thread *, sigset_t,
+ ksiginfo_t *, struct timespec *);
+static int do_tdsignal(struct thread *, int, ksiginfo_t *, sigtarget_t);
+static void sigqueue_start(void);
+static ksiginfo_t * ksiginfo_alloc(void);
+static void ksiginfo_free(ksiginfo_t *);
+static int psignal_common(struct proc *p, int sig, ksiginfo_t *ksi);
+
+static uma_zone_t ksiginfo_zone = NULL;
struct filterops sig_filtops =
{ 0, filt_sigattach, filt_sigdetach, filt_signal };
@@ -102,6 +110,31 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW,
&kern_logsigexit, 0,
"Log processes quitting on abnormal signals to syslog(3)");
+SYSCTL_NODE(_kern, OID_AUTO, sigqueue, CTLFLAG_RW, 0, "POSIX real time signal");
+
+static int max_pending_per_proc = 128;
+SYSCTL_INT(_kern_sigqueue, OID_AUTO, max_pending_per_proc, CTLFLAG_RW,
+ &max_pending_per_proc, 0, "Max pending signals per proc");
+
+static int queue_rt_signal_only = 1;
+SYSCTL_INT(_kern_sigqueue, OID_AUTO, queue_rt_signal_only, CTLFLAG_RW,
+ &queue_rt_signal_only, 0, "Only rt signal is queued");
+
+static int preallocate_siginfo = 1024;
+TUNABLE_INT("kern.sigqueue.preallocate", &preallocate_siginfo);
+SYSCTL_INT(_kern_sigqueue, OID_AUTO, preallocate, CTLFLAG_RD,
+ &preallocate_siginfo, 0, "Preallocated signal memory size");
+
+static int signal_overflow = 0;
+SYSCTL_INT(_kern_sigqueue, OID_AUTO, signal_overflow, CTLFLAG_RD,
+ &signal_overflow, 0, "Number of signals overflew");
+
+static int signal_alloc_fail = 0;
+SYSCTL_INT(_kern_sigqueue, OID_AUTO, signal_alloc_fail, CTLFLAG_RD,
+ &signal_alloc_fail, 0, "signals failed to be allocated");
+
+SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL);
+
/*
* Policy -- Can ucred cr1 send SIGIO to process cr2?
* Should use cr_cansignal() once cr_cansignal() allows SIGIO and SIGURG
@@ -174,11 +207,276 @@ static int sigproptbl[NSIG] = {
SA_KILL|SA_PROC, /* SIGUSR2 */
};
+static void
+sigqueue_start(void)
+{
+ ksiginfo_zone = uma_zcreate("ksiginfo", sizeof(ksiginfo_t),
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+ uma_prealloc(ksiginfo_zone, preallocate_siginfo);
+}
+
+static ksiginfo_t *
+ksiginfo_alloc(void)
+{
+ if (ksiginfo_zone != NULL)
+ return ((ksiginfo_t *)uma_zalloc(ksiginfo_zone, M_NOWAIT));
+ return (NULL);
+}
+
+static void
+ksiginfo_free(ksiginfo_t *ksi)
+{
+ uma_zfree(ksiginfo_zone, ksi);
+}
+
+void
+sigqueue_init(sigqueue_t *list, struct proc *p)
+{
+ SIGEMPTYSET(list->sq_signals);
+ TAILQ_INIT(&list->sq_list);
+ list->sq_proc = p;
+ list->sq_flags = SQ_INIT;
+}
+
+/*
+ * Get a signal's ksiginfo.
+ * Return:
+ * 0 - signal not found
+ * others - signal number
+ */
+int
+sigqueue_get(sigqueue_t *sq, int signo, ksiginfo_t *si)
+{
+ struct proc *p = sq->sq_proc;
+ struct ksiginfo *ksi, *next;
+ int count = 0;
+
+ KASSERT(sq->sq_flags & SQ_INIT, ("sigqueue not inited"));
+
+ ksiginfo_init(si);
+ if (!SIGISMEMBER(sq->sq_signals, signo))
+ return (0);
+
+ for (ksi = TAILQ_FIRST(&sq->sq_list); ksi != NULL; ksi = next) {
+ next = TAILQ_NEXT(ksi, ksi_link);
+ if (ksi->ksi_signo == signo) {
+ if (count == 0) {
+ TAILQ_REMOVE(&sq->sq_list, ksi, ksi_link);
+ ksiginfo_copy(ksi, si);
+ ksiginfo_free(ksi);
+ if (p != NULL)
+ p->p_pendingcnt--;
+ }
+ count++;
+ }
+ }
+
+ if (count <= 1)
+ SIGDELSET(sq->sq_signals, signo);
+ si->ksi_signo = signo;
+ return (signo);
+}
+
+int
+sigqueue_add(sigqueue_t *sq, int signo, ksiginfo_t *si)
+{
+ struct proc *p = sq->sq_proc;
+ struct ksiginfo *ksi;
+ int ret = 0;
+
+ KASSERT(sq->sq_flags & SQ_INIT, ("sigqueue not inited"));
+
+ if (signo == SIGKILL || signo == SIGSTOP || si == NULL)
+ goto out_set_bit;
+
+ if (__predict_false(ksiginfo_zone == NULL))
+ goto out_set_bit;
+
+ if (p != NULL && p->p_pendingcnt > max_pending_per_proc) {
+ signal_overflow++;
+ ret = EAGAIN;
+ } else if ((ksi = ksiginfo_alloc()) == NULL) {
+ signal_alloc_fail++;
+ ret = EAGAIN;
+ } else {
+ if (p != NULL)
+ p->p_pendingcnt++;
+ ksiginfo_copy(si, ksi);
+ ksi->ksi_signo = signo;
+ TAILQ_INSERT_TAIL(&sq->sq_list, ksi, ksi_link);
+ }
+
+ if ((si->ksi_flags & KSI_TRAP) != 0) {
+ ret = 0;
+ goto out_set_bit;
+ }
+
+ if (ret != 0)
+ return (ret);
+
+out_set_bit:
+ SIGADDSET(sq->sq_signals, signo);
+ return (ret);
+}
+
+void
+sigqueue_flush(sigqueue_t *sq)
+{
+ struct proc *p = sq->sq_proc;
+ ksiginfo_t *ksi;
+
+ KASSERT(sq->sq_flags & SQ_INIT, ("sigqueue not inited"));
+
+ while ((ksi = TAILQ_FIRST(&sq->sq_list)) != NULL) {
+ TAILQ_REMOVE(&sq->sq_list, ksi, ksi_link);
+ ksiginfo_free(ksi);
+ if (p != NULL)
+ p->p_pendingcnt--;
+ }
+
+ SIGEMPTYSET(sq->sq_signals);
+}
+
+void
+sigqueue_collect_set(sigqueue_t *sq, sigset_t *set)
+{
+ ksiginfo_t *ksi;
+
+ KASSERT(sq->sq_flags & SQ_INIT, ("sigqueue not inited"));
+
+ TAILQ_FOREACH(ksi, &sq->sq_list, ksi_link)
+ SIGADDSET(*set, ksi->ksi_signo);
+}
+
+void
+sigqueue_move_set(sigqueue_t *src, sigqueue_t *dst, sigset_t *setp)
+{
+ sigset_t tmp, set;
+ struct proc *p1, *p2;
+ ksiginfo_t *ksi, *next;
+
+ KASSERT(src->sq_flags & SQ_INIT, ("src sigqueue not inited"));
+ KASSERT(dst->sq_flags & SQ_INIT, ("dst sigqueue not inited"));
+ /*
+ * make a copy, this allows setp to point to src or dst
+ * sq_signals without trouble.
+ */
+ set = *setp;
+ p1 = src->sq_proc;
+ p2 = dst->sq_proc;
+ /* Move siginfo to target list */
+ for (ksi = TAILQ_FIRST(&src->sq_list); ksi != NULL; ksi = next) {
+ next = TAILQ_NEXT(ksi, ksi_link);
+ if (SIGISMEMBER(set, ksi->ksi_signo)) {
+ TAILQ_REMOVE(&src->sq_list, ksi, ksi_link);
+ if (p1 != NULL)
+ p1->p_pendingcnt--;
+ TAILQ_INSERT_TAIL(&dst->sq_list, ksi, ksi_link);
+ if (p2 != NULL)
+ p2->p_pendingcnt++;
+ }
+ }
+
+ /* Move pending bits to target list */
+ tmp = src->sq_signals;
+ SIGSETAND(tmp, set);
+ SIGSETOR(dst->sq_signals, tmp);
+ SIGSETNAND(src->sq_signals, tmp);
+
+ /* Finally, rescan src queue and set pending bits for it */
+ sigqueue_collect_set(src, &src->sq_signals);
+}
+
+void
+sigqueue_move(sigqueue_t *src, sigqueue_t *dst, int signo)
+{
+ sigset_t set;
+
+ SIGEMPTYSET(set);
+ SIGADDSET(set, signo);
+ sigqueue_move_set(src, dst, &set);
+}
+
+void
+sigqueue_delete_set(sigqueue_t *sq, sigset_t *set)
+{
+ struct proc *p = sq->sq_proc;
+ ksiginfo_t *ksi, *next;
+
+ KASSERT(sq->sq_flags & SQ_INIT, ("src sigqueue not inited"));
+
+ /* Remove siginfo queue */
+ for (ksi = TAILQ_FIRST(&sq->sq_list); ksi != NULL; ksi = next) {
+ next = TAILQ_NEXT(ksi, ksi_link);
+ if (SIGISMEMBER(*set, ksi->ksi_signo)) {
+ TAILQ_REMOVE(&sq->sq_list, ksi, ksi_link);
+ ksiginfo_free(ksi);
+ if (p != NULL)
+ p->p_pendingcnt--;
+ }
+ }
+ SIGSETNAND(sq->sq_signals, *set);
+ /* Finally, rescan queue and set pending bits for it */
+ sigqueue_collect_set(sq, &sq->sq_signals);
+}
+
+void
+sigqueue_delete(sigqueue_t *sq, int signo)
+{
+ sigset_t set;
+
+ SIGEMPTYSET(set);
+ SIGADDSET(set, signo);
+ sigqueue_delete_set(sq, &set);
+}
+
+/* Remove a set of signals for a process */
+void
+sigqueue_delete_set_proc(struct proc *p, sigset_t *set)
+{
+ sigqueue_t worklist;
+ struct thread *td0;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ sigqueue_init(&worklist, NULL);
+ sigqueue_move_set(&p->p_sigqueue, &worklist, set);
+
+ mtx_lock_spin(&sched_lock);
+ FOREACH_THREAD_IN_PROC(p, td0)
+ sigqueue_move_set(&td0->td_sigqueue, &worklist, set);
+ mtx_unlock_spin(&sched_lock);
+
+ sigqueue_flush(&worklist);
+}
+
+void
+sigqueue_delete_proc(struct proc *p, int signo)
+{
+ sigset_t set;
+
+ SIGEMPTYSET(set);
+ SIGADDSET(set, signo);
+ sigqueue_delete_set_proc(p, &set);
+}
+
+void
+sigqueue_delete_stopmask_proc(struct proc *p)
+{
+ sigset_t set;
+
+ SIGEMPTYSET(set);
+ SIGADDSET(set, SIGSTOP);
+ SIGADDSET(set, SIGTSTP);
+ SIGADDSET(set, SIGTTIN);
+ SIGADDSET(set, SIGTTOU);
+ sigqueue_delete_set_proc(p, &set);
+}
+
/*
* Determine signal that should be delivered to process p, the current
* process, 0 if none. If there is a pending stop signal with default
* action, the process stops in issignal().
- * XXXKSE the check for a pending stop is not done under KSE
*
* MP SAFE.
*/
@@ -193,7 +491,7 @@ cursig(struct thread *td)
/*
* Arrange for ast() to handle unmasked pending signals on return to user
- * mode. This must be called whenever a signal is added to td_siglist or
+ * mode. This must be called whenever a signal is added to td_sigqueue or
* unmasked in td_sigmask.
*/
void
@@ -208,22 +506,21 @@ signotify(struct thread *td)
/*
* If our mask changed we may have to move signal that were
- * previously masked by all threads to our siglist.
+ * previously masked by all threads to our sigqueue.
*/
- set = p->p_siglist;
+ set = p->p_sigqueue.sq_signals;
if (p->p_flag & P_SA)
- saved = p->p_siglist;
+ saved = p->p_sigqueue.sq_signals;
SIGSETNAND(set, td->td_sigmask);
- SIGSETNAND(p->p_siglist, set);
- SIGSETOR(td->td_siglist, set);
-
+ if (! SIGISEMPTY(set))
+ sigqueue_move_set(&p->p_sigqueue, &td->td_sigqueue, &set);
if (SIGPENDING(td)) {
mtx_lock_spin(&sched_lock);
td->td_flags |= TDF_NEEDSIGCHK | TDF_ASTPENDING;
mtx_unlock_spin(&sched_lock);
}
if ((p->p_flag & P_SA) && !(p->p_flag & P_SIGEVENT)) {
- if (!SIGSETEQ(saved, p->p_siglist)) {
+ if (!SIGSETEQ(saved, p->p_sigqueue.sq_signals)) {
/* pending set changed */
p->p_flag |= P_SIGEVENT;
wakeup(&p->p_siglist);
@@ -283,7 +580,6 @@ kern_sigaction(td, sig, act, oact, flags)
int flags;
{
struct sigacts *ps;
- struct thread *td0;
struct proc *p = td->td_proc;
if (!_SIG_VALID(sig))
@@ -382,16 +678,12 @@ kern_sigaction(td, sig, act, oact, flags)
(sigprop(sig) & SA_IGNORE &&
ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)) {
if ((p->p_flag & P_SA) &&
- SIGISMEMBER(p->p_siglist, sig)) {
+ SIGISMEMBER(p->p_sigqueue.sq_signals, sig)) {
p->p_flag |= P_SIGEVENT;
wakeup(&p->p_siglist);
}
/* never to be seen again */
- SIGDELSET(p->p_siglist, sig);
- mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td0)
- SIGDELSET(td0->td_siglist, sig);
- mtx_unlock_spin(&sched_lock);
+ sigqueue_delete_proc(p, sig);
if (sig != SIGCONT)
/* easier in psignal */
SIGADDSET(ps->ps_sigignore, sig);
@@ -596,11 +888,7 @@ execsigs(struct proc *p)
if (sigprop(sig) & SA_IGNORE) {
if (sig != SIGCONT)
SIGADDSET(ps->ps_sigignore, sig);
- SIGDELSET(p->p_siglist, sig);
- /*
- * There is only one thread at this point.
- */
- SIGDELSET(td->td_siglist, sig);
+ sigqueue_delete_proc(p, sig);
}
ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
}
@@ -726,18 +1014,13 @@ osigprocmask(td, uap)
}
#endif /* COMPAT_43 */
-#ifndef _SYS_SYSPROTO_H_
-struct sigpending_args {
- sigset_t *set;
-};
-#endif
/*
* MPSAFE
*/
int
sigwait(struct thread *td, struct sigwait_args *uap)
{
- siginfo_t info;
+ ksiginfo_t ksi;
sigset_t set;
int error;
@@ -747,7 +1030,7 @@ sigwait(struct thread *td, struct sigwait_args *uap)
return (0);
}
- error = kern_sigtimedwait(td, set, &info, NULL);
+ error = kern_sigtimedwait(td, set, &ksi, NULL);
if (error) {
if (error == ERESTART)
return (error);
@@ -755,13 +1038,7 @@ sigwait(struct thread *td, struct sigwait_args *uap)
return (0);
}
- error = copyout(&info.si_signo, uap->sig, sizeof(info.si_signo));
- /* Repost if we got an error. */
- if (error && info.si_signo) {
- PROC_LOCK(td->td_proc);
- tdsignal(td, info.si_signo, SIGTARGET_TD);
- PROC_UNLOCK(td->td_proc);
- }
+ error = copyout(&ksi.ksi_signo, uap->sig, sizeof(ksi.ksi_signo));
td->td_retval[0] = error;
return (0);
}
@@ -774,7 +1051,7 @@ sigtimedwait(struct thread *td, struct sigtimedwait_args *uap)
struct timespec ts;
struct timespec *timeout;
sigset_t set;
- siginfo_t info;
+ ksiginfo_t ksi;
int error;
if (uap->timeout) {
@@ -790,20 +1067,15 @@ sigtimedwait(struct thread *td, struct sigtimedwait_args *uap)
if (error)
return (error);
- error = kern_sigtimedwait(td, set, &info, timeout);
+ error = kern_sigtimedwait(td, set, &ksi, timeout);
if (error)
return (error);
if (uap->info)
- error = copyout(&info, uap->info, sizeof(info));
- /* Repost if we got an error. */
- if (error && info.si_signo) {
- PROC_LOCK(td->td_proc);
- tdsignal(td, info.si_signo, SIGTARGET_TD);
- PROC_UNLOCK(td->td_proc);
- } else {
- td->td_retval[0] = info.si_signo;
- }
+ error = copyout(&ksi.ksi_info, uap->info, sizeof(siginfo_t));
+
+ if (error == 0)
+ td->td_retval[0] = ksi.ksi_signo;
return (error);
}
@@ -813,7 +1085,7 @@ sigtimedwait(struct thread *td, struct sigtimedwait_args *uap)
int
sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap)
{
- siginfo_t info;
+ ksiginfo_t ksi;
sigset_t set;
int error;
@@ -821,26 +1093,21 @@ sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap)
if (error)
return (error);
- error = kern_sigtimedwait(td, set, &info, NULL);
+ error = kern_sigtimedwait(td, set, &ksi, NULL);
if (error)
return (error);
if (uap->info)
- error = copyout(&info, uap->info, sizeof(info));
- /* Repost if we got an error. */
- if (error && info.si_signo) {
- PROC_LOCK(td->td_proc);
- tdsignal(td, info.si_signo, SIGTARGET_TD);
- PROC_UNLOCK(td->td_proc);
- } else {
- td->td_retval[0] = info.si_signo;
- }
+ error = copyout(&ksi.ksi_info, uap->info, sizeof(siginfo_t));
+
+ if (error == 0)
+ td->td_retval[0] = ksi.ksi_signo;
return (error);
}
static int
-kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
- struct timespec *timeout)
+kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi,
+ struct timespec *timeout)
{
struct sigacts *ps;
sigset_t savedmask;
@@ -870,7 +1137,7 @@ again:
for (i = 1; i <= _SIG_MAXSIG; ++i) {
if (!SIGISMEMBER(waitset, i))
continue;
- if (SIGISMEMBER(td->td_siglist, i)) {
+ if (SIGISMEMBER(td->td_sigqueue.sq_signals, i)) {
SIGFILLSET(td->td_sigmask);
SIG_CANTMASK(td->td_sigmask);
SIGDELSET(td->td_sigmask, i);
@@ -878,13 +1145,12 @@ again:
sig = cursig(td);
i = 0;
mtx_unlock(&ps->ps_mtx);
- } else if (SIGISMEMBER(p->p_siglist, i)) {
+ } else if (SIGISMEMBER(p->p_sigqueue.sq_signals, i)) {
if (p->p_flag & P_SA) {
p->p_flag |= P_SIGEVENT;
wakeup(&p->p_siglist);
}
- SIGDELSET(p->p_siglist, i);
- SIGADDSET(td->td_siglist, i);
+ sigqueue_move(&p->p_sigqueue, &td->td_sigqueue, i);
SIGFILLSET(td->td_sigmask);
SIG_CANTMASK(td->td_sigmask);
SIGDELSET(td->td_sigmask, i);
@@ -936,11 +1202,11 @@ again:
goto again;
out:
- td->td_sigmask = savedmask;
- signotify(td);
if (sig) {
sig_t action;
+ sigqueue_get(&td->td_sigqueue, sig, ksi);
+ ksi->ksi_signo = sig;
error = 0;
mtx_lock(&ps->ps_mtx);
action = ps->ps_sigact[_SIG_IDX(sig)];
@@ -951,15 +1217,18 @@ out:
#endif
_STOPEVENT(p, S_SIG, sig);
- SIGDELSET(td->td_siglist, sig);
- bzero(info, sizeof(*info));
- info->si_signo = sig;
- info->si_code = 0;
}
+ td->td_sigmask = savedmask;
+ signotify(td);
PROC_UNLOCK(p);
return (error);
}
+#ifndef _SYS_SYSPROTO_H_
+struct sigpending_args {
+ sigset_t *set;
+};
+#endif
/*
* MPSAFE
*/
@@ -969,13 +1238,13 @@ sigpending(td, uap)
struct sigpending_args *uap;
{
struct proc *p = td->td_proc;
- sigset_t siglist;
+ sigset_t pending;
PROC_LOCK(p);
- siglist = p->p_siglist;
- SIGSETOR(siglist, td->td_siglist);
+ pending = p->p_sigqueue.sq_signals;
+ SIGSETOR(pending, td->td_sigqueue.sq_signals);
PROC_UNLOCK(p);
- return (copyout(&siglist, uap->set, sizeof(sigset_t)));
+ return (copyout(&pending, uap->set, sizeof(sigset_t)));
}
#ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */
@@ -993,13 +1262,13 @@ osigpending(td, uap)
struct osigpending_args *uap;
{
struct proc *p = td->td_proc;
- sigset_t siglist;
+ sigset_t pending;
PROC_LOCK(p);
- siglist = p->p_siglist;
- SIGSETOR(siglist, td->td_siglist);
+ pending = p->p_sigqueue.sq_signals;
+ SIGSETOR(pending, td->td_sigqueue.sq_signals);
PROC_UNLOCK(p);
- SIG2OSIG(siglist, td->td_retval[0]);
+ SIG2OSIG(pending, td->td_retval[0]);
return (0);
}
#endif /* COMPAT_43 */
@@ -1107,11 +1376,8 @@ osigsetmask(td, uap)
#endif /* COMPAT_43 */
/*
- * Suspend process until signal, providing mask to be set
+ * Suspend calling thread until signal, providing mask to be set
* in the meantime.
- ***** XXXKSE this doesn't make sense under KSE.
- ***** Do we suspend the thread or all threads in the process?
- ***** How do we suspend threads running NOW on another processor?
*/
#ifndef _SYS_SYSPROTO_H_
struct sigsuspend_args {
@@ -1289,9 +1555,9 @@ kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss)
if ((ss->ss_flags & ~SS_DISABLE) != 0)
return (EINVAL);
if (!(ss->ss_flags & SS_DISABLE)) {
- if (ss->ss_size < p->p_sysent->sv_minsigstksz) {
+ if (ss->ss_size < p->p_sysent->sv_minsigstksz)
return (ENOMEM);
- }
+
td->td_sigstk = *ss;
td->td_pflags |= TDP_ALTSTACK;
} else {
@@ -1431,10 +1697,54 @@ okillpg(td, uap)
if ((u_int)uap->signum > _SIG_MAXSIG)
return (EINVAL);
+
return (killpg1(td, uap->signum, uap->pgid, 0));
}
#endif /* COMPAT_43 */
+#ifndef _SYS_SYSPROTO_H_
+struct sigqueue_args {
+ pid_t pid;
+ int signum;
+ /* union sigval */ void *value;
+};
+#endif
+
+int
+sigqueue(struct thread *td, struct sigqueue_args *uap)
+{
+ ksiginfo_t ksi;
+ struct proc *p;
+ int error;
+
+ if ((u_int)uap->signum > _SIG_MAXSIG)
+ return (EINVAL);
+
+ /*
+ * Specification says sigqueue can only send signal to
+ * single process.
+ */
+ if (uap->pid <= 0)
+ return (EINVAL);
+
+ if ((p = pfind(uap->pid)) == NULL) {
+ if ((p = zpfind(uap->pid)) == NULL)
+ return (ESRCH);
+ }
+ error = p_cansignal(td, p, uap->signum);
+ if (error == 0 && uap->signum != 0) {
+ ksiginfo_init(&ksi);
+ ksi.ksi_signo = uap->signum;
+ ksi.ksi_code = SI_QUEUE;
+ ksi.ksi_pid = td->td_proc->p_pid;
+ ksi.ksi_uid = td->td_ucred->cr_ruid;
+ ksi.ksi_value.sigval_ptr = uap->value;
+ error = psignal_info(p, &ksi);
+ }
+ PROC_UNLOCK(p);
+ return (error);
+}
+
/*
* Send a signal to a process group.
*/
@@ -1485,14 +1795,19 @@ pgsignal(pgrp, sig, checkctty)
* MPSAFE
*/
void
-trapsignal(struct thread *td, int sig, u_long code)
+trapsignal(struct thread *td, ksiginfo_t *ksi)
{
struct sigacts *ps;
struct proc *p;
- siginfo_t siginfo;
int error;
+ int sig;
+ int code;
p = td->td_proc;
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
+ KASSERT(_SIG_VALID(sig), ("invalid signal"));
+
if (td->td_pflags & TDP_SA) {
if (td->td_mailbox == NULL)
thread_user_enter(td);
@@ -1521,9 +1836,8 @@ trapsignal(struct thread *td, int sig, u_long code)
&td->td_sigmask, code);
#endif
if (!(td->td_pflags & TDP_SA))
- (*p->p_sysent->sv_sendsig)(
- ps->ps_sigact[_SIG_IDX(sig)], sig,
- &td->td_sigmask, code);
+ (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
+ ksi, &td->td_sigmask);
else if (td->td_mailbox == NULL) {
mtx_unlock(&ps->ps_mtx);
/* UTS caused a sync signal */
@@ -1531,12 +1845,11 @@ trapsignal(struct thread *td, int sig, u_long code)
p->p_sig = sig; /* XXX to verify code */
sigexit(td, sig);
} else {
- cpu_thread_siginfo(sig, code, &siginfo);
mtx_unlock(&ps->ps_mtx);
SIGADDSET(td->td_sigmask, sig);
PROC_UNLOCK(p);
- error = copyout(&siginfo, &td->td_mailbox->tm_syncsig,
- sizeof(siginfo));
+ error = copyout(&ksi->ksi_info, &td->td_mailbox->tm_syncsig,
+ sizeof(siginfo_t));
PROC_LOCK(p);
/* UTS memory corrupted */
if (error)
@@ -1561,7 +1874,7 @@ trapsignal(struct thread *td, int sig, u_long code)
mtx_unlock(&ps->ps_mtx);
p->p_code = code; /* XXX for core dump/debugger */
p->p_sig = sig; /* XXX to verify code */
- tdsignal(td, sig, SIGTARGET_TD);
+ tdsignal(td, sig, ksi, SIGTARGET_TD);
}
PROC_UNLOCK(p);
}
@@ -1611,6 +1924,18 @@ sigtd(struct proc *p, int sig, int prop)
void
psignal(struct proc *p, int sig)
{
+ (void) psignal_common(p, sig, NULL);
+}
+
+int
+psignal_info(struct proc *p, ksiginfo_t *ksi)
+{
+ return (psignal_common(p, ksi->ksi_signo, ksi));
+}
+
+static int
+psignal_common(struct proc *p, int sig, ksiginfo_t *ksi)
+{
struct thread *td;
int prop;
@@ -1622,7 +1947,7 @@ psignal(struct proc *p, int sig)
* IEEE Std 1003.1-2001: return success when killing a zombie.
*/
if (p->p_state == PRS_ZOMBIE)
- return;
+ return (0);
prop = sigprop(sig);
/*
@@ -1630,39 +1955,42 @@ psignal(struct proc *p, int sig)
*/
td = sigtd(p, sig, prop);
- tdsignal(td, sig, SIGTARGET_P);
+ return (tdsignal(td, sig, ksi, SIGTARGET_P));
}
/*
* MPSAFE
*/
-void
-tdsignal(struct thread *td, int sig, sigtarget_t target)
+int
+tdsignal(struct thread *td, int sig, ksiginfo_t *ksi, sigtarget_t target)
{
sigset_t saved;
struct proc *p = td->td_proc;
+ int ret;
if (p->p_flag & P_SA)
- saved = p->p_siglist;
- do_tdsignal(td, sig, target);
+ saved = p->p_sigqueue.sq_signals;
+ ret = do_tdsignal(td, sig, ksi, target);
if ((p->p_flag & P_SA) && !(p->p_flag & P_SIGEVENT)) {
- if (!SIGSETEQ(saved, p->p_siglist)) {
+ if (!SIGSETEQ(saved, p->p_sigqueue.sq_signals)) {
/* pending set changed */
p->p_flag |= P_SIGEVENT;
wakeup(&p->p_siglist);
}
}
+ return (ret);
}
-static void
-do_tdsignal(struct thread *td, int sig, sigtarget_t target)
+static int
+do_tdsignal(struct thread *td, int sig, ksiginfo_t *ksi, sigtarget_t target)
{
struct proc *p;
- register sig_t action;
- sigset_t *siglist;
+ sig_t action;
+ sigqueue_t *sigqueue;
struct thread *td0;
- register int prop;
+ int prop;
struct sigacts *ps;
+ int ret = 0;
if (!_SIG_VALID(sig))
panic("do_tdsignal(): invalid signal");
@@ -1681,16 +2009,17 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
* thread that unblocks it. Otherwise, assign it to this thread now.
*/
if (target == SIGTARGET_TD) {
- siglist = &td->td_siglist;
+ sigqueue = &td->td_sigqueue;
} else {
if (!SIGISMEMBER(td->td_sigmask, sig))
- siglist = &td->td_siglist;
+ sigqueue = &td->td_sigqueue;
else
- siglist = &p->p_siglist;
+ sigqueue = &p->p_sigqueue;
}
/*
* If the signal is being ignored,
+ * or process is exiting or thread is exiting,
* then we forget about it immediately.
* (Note: we don't set SIGCONT in ps_sigignore,
* and if it is set to SIG_IGN,
@@ -1700,7 +2029,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
if (SIGISMEMBER(ps->ps_sigignore, sig) ||
(p->p_flag & P_WEXIT)) {
mtx_unlock(&ps->ps_mtx);
- return;
+ return (ret);
}
if (SIGISMEMBER(td->td_sigmask, sig))
action = SIG_HOLD;
@@ -1710,19 +2039,9 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
action = SIG_DFL;
mtx_unlock(&ps->ps_mtx);
- if (prop & SA_CONT) {
- SIG_STOPSIGMASK(p->p_siglist);
- /*
- * XXX Should investigate leaving STOP and CONT sigs only in
- * the proc's siglist.
- */
- mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td0)
- SIG_STOPSIGMASK(td0->td_siglist);
- mtx_unlock_spin(&sched_lock);
- }
-
- if (prop & SA_STOP) {
+ if (prop & SA_CONT)
+ sigqueue_delete_stopmask_proc(p);
+ else if (prop & SA_STOP) {
/*
* If sending a tty stop signal to a member of an orphaned
* process group, discard the signal here if the action
@@ -1732,16 +2051,14 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
if ((prop & SA_TTYSTOP) &&
(p->p_pgrp->pg_jobc == 0) &&
(action == SIG_DFL))
- return;
- SIG_CONTSIGMASK(p->p_siglist);
- mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td0)
- SIG_CONTSIGMASK(td0->td_siglist);
- mtx_unlock_spin(&sched_lock);
+ return (ret);
+ sigqueue_delete_proc(p, SIGCONT);
p->p_flag &= ~P_CONTINUED;
}
- SIGADDSET(*siglist, sig);
+ ret = sigqueue_add(sigqueue, sig, ksi);
+ if (ret != 0)
+ return (ret);
signotify(td); /* uses schedlock */
/*
* Defer further processing for signals which are held,
@@ -1749,7 +2066,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
*/
if (action == SIG_HOLD &&
!((prop & SA_CONT) && (p->p_flag & P_STOPPED_SIG)))
- return;
+ return (ret);
/*
* SIGKILL: Remove procfs STOPEVENTs.
*/
@@ -1795,10 +2112,10 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
if (prop & SA_CONT) {
/*
* If SIGCONT is default (or ignored), we continue the
- * process but don't leave the signal in siglist as
+ * process but don't leave the signal in sigqueue as
* it has no further action. If SIGCONT is held, we
* continue the process and leave the signal in
- * siglist. If the process catches SIGCONT, let it
+ * sigqueue. If the process catches SIGCONT, let it
* handle the signal itself. If it isn't waiting on
* an event, it goes back to run state.
* Otherwise, process goes back to sleep state.
@@ -1806,7 +2123,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
p->p_flag &= ~P_STOPPED_SIG;
p->p_flag |= P_CONTINUED;
if (action == SIG_DFL) {
- SIGDELSET(*siglist, sig);
+ sigqueue_delete(sigqueue, sig);
} else if (action == SIG_CATCH) {
/*
* The process wants to catch it so it needs
@@ -1836,7 +2153,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
* Just make sure the signal STOP bit set.
*/
p->p_flag |= P_STOPPED_SIG;
- SIGDELSET(*siglist, sig);
+ sigqueue_delete(sigqueue, sig);
goto out;
}
@@ -1885,11 +2202,10 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
}
thread_stopped(p);
if (p->p_numthreads == p->p_suspcount) {
- SIGDELSET(p->p_siglist, p->p_xstat);
- FOREACH_THREAD_IN_PROC(p, td0)
- SIGDELSET(td0->td_siglist, p->p_xstat);
- }
- mtx_unlock_spin(&sched_lock);
+ mtx_unlock_spin(&sched_lock);
+ sigqueue_delete_proc(p, p->p_xstat);
+ } else
+ mtx_unlock_spin(&sched_lock);
goto out;
}
else
@@ -1897,7 +2213,7 @@ do_tdsignal(struct thread *td, int sig, sigtarget_t target)
/* NOTREACHED */
} else {
/* Not in "NORMAL" state. discard the signal. */
- SIGDELSET(*siglist, sig);
+ sigqueue_delete(sigqueue, sig);
goto out;
}
@@ -1914,6 +2230,7 @@ runfast:
out:
/* If we jump here, sched_lock should not be owned. */
mtx_assert(&sched_lock, MA_NOTOWNED);
+ return (ret);
}
/*
@@ -1957,12 +2274,14 @@ tdsigwakeup(struct thread *td, int sig, sig_t action)
* be awakened.
*/
if ((prop & SA_CONT) && action == SIG_DFL) {
- SIGDELSET(p->p_siglist, sig);
+ mtx_unlock_spin(&sched_lock);
+ sigqueue_delete(&p->p_sigqueue, sig);
/*
* It may be on either list in this state.
* Remove from both for now.
*/
- SIGDELSET(td->td_siglist, sig);
+ sigqueue_delete(&td->td_sigqueue, sig);
+ mtx_lock_spin(&sched_lock);
return;
}
@@ -2074,7 +2393,7 @@ issignal(td)
for (;;) {
int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG);
- sigpending = td->td_siglist;
+ sigpending = td->td_sigqueue.sq_signals;
SIGSETNAND(sigpending, td->td_sigmask);
if (p->p_flag & P_PPWAIT)
@@ -2094,7 +2413,7 @@ issignal(td)
* only if P_TRACED was on when they were posted.
*/
if (SIGISMEMBER(ps->ps_sigignore, sig) && (traced == 0)) {
- SIGDELSET(td->td_siglist, sig);
+ sigqueue_delete(&td->td_sigqueue, sig);
if (td->td_pflags & TDP_SA)
SIGADDSET(td->td_sigmask, sig);
continue;
@@ -2107,17 +2426,38 @@ issignal(td)
newsig = ptracestop(td, sig);
mtx_lock(&ps->ps_mtx);
- /*
- * If parent wants us to take the signal,
- * then it will leave it in p->p_xstat;
- * otherwise we just look for signals again.
- */
- SIGDELSET(td->td_siglist, sig); /* clear old signal */
if (td->td_pflags & TDP_SA)
SIGADDSET(td->td_sigmask, sig);
- if (newsig == 0)
- continue;
- sig = newsig;
+
+ if (sig != newsig) {
+ /*
+ * clear old signal.
+ * XXX shrug off debugger, it causes siginfo to
+ * be thrown away.
+ */
+ sigqueue_delete(&td->td_sigqueue, sig);
+
+ /*
+ * If parent wants us to take the signal,
+ * then it will leave it in p->p_xstat;
+ * otherwise we just look for signals again.
+ */
+ if (newsig == 0)
+ continue;
+ sig = newsig;
+
+ /*
+ * Put the new signal into td_sigqueue. If the
+ * signal is being masked, look for other signals.
+ */
+ SIGADDSET(td->td_sigqueue.sq_signals, sig);
+ if (td->td_pflags & TDP_SA)
+ SIGDELSET(td->td_sigmask, sig);
+ if (SIGISMEMBER(td->td_sigmask, sig))
+ continue;
+ signotify(td);
+ }
+
/*
* If the traced bit got turned off, go back up
* to the top to rescan signals. This ensures
@@ -2125,17 +2465,6 @@ issignal(td)
*/
if ((p->p_flag & P_TRACED) == 0)
continue;
-
- /*
- * Put the new signal into td_siglist. If the
- * signal is being masked, look for other signals.
- */
- SIGADDSET(td->td_siglist, sig);
- if (td->td_pflags & TDP_SA)
- SIGDELSET(td->td_sigmask, sig);
- if (SIGISMEMBER(td->td_sigmask, sig))
- continue;
- signotify(td);
}
prop = sigprop(sig);
@@ -2228,7 +2557,7 @@ issignal(td)
*/
return (sig);
}
- SIGDELSET(td->td_siglist, sig); /* take the signal! */
+ sigqueue_delete(&td->td_sigqueue, sig); /* take the signal! */
}
/* NOTREACHED */
}
@@ -2284,6 +2613,7 @@ postsig(sig)
register struct proc *p = td->td_proc;
struct sigacts *ps;
sig_t action;
+ ksiginfo_t ksi;
sigset_t returnmask;
int code;
@@ -2292,7 +2622,9 @@ postsig(sig)
PROC_LOCK_ASSERT(p, MA_OWNED);
ps = p->p_sigacts;
mtx_assert(&ps->ps_mtx, MA_OWNED);
- SIGDELSET(td->td_siglist, sig);
+ sigqueue_get(&td->td_sigqueue, sig, &ksi);
+ ksi.ksi_signo = sig;
+
action = ps->ps_sigact[_SIG_IDX(sig)];
#ifdef KTRACE
if (KTRPOINT(td, KTR_PSIG))
@@ -2364,10 +2696,9 @@ postsig(sig)
p->p_sig = 0;
}
if (td->td_pflags & TDP_SA)
- thread_signal_add(curthread, sig);
+ thread_signal_add(curthread, &ksi);
else
- (*p->p_sysent->sv_sendsig)(action, sig,
- &returnmask, code);
+ (*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
}
}
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 0e8b3e81f69f..e6661e29eeed 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -279,6 +279,7 @@ thr_exit(struct thread *td, struct thr_exit_args *uap)
suword((void *)uap->state, 1);
PROC_LOCK(p);
+ sigqueue_flush(&td->td_sigqueue);
mtx_lock_spin(&sched_lock);
/*
@@ -319,7 +320,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
error = EINVAL;
goto out;
}
- tdsignal(ttd, uap->sig, SIGTARGET_TD);
+ tdsignal(ttd, uap->sig, NULL, SIGTARGET_TD);
out:
PROC_UNLOCK(p);
return (error);
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index ed788dae8c20..e315baf2e26d 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -277,6 +277,7 @@ proc_linkup(struct proc *p, struct ksegrp *kg, struct thread *td)
TAILQ_INIT(&p->p_ksegrps); /* all ksegrps in proc */
TAILQ_INIT(&p->p_threads); /* all threads in proc */
TAILQ_INIT(&p->p_suspended); /* Threads suspended */
+ sigqueue_init(&p->p_sigqueue, p);
p->p_numksegrps = 0;
p->p_numthreads = 0;
@@ -454,6 +455,7 @@ thread_exit(void)
KASSERT(kg != NULL, ("thread exiting without a kse group"));
CTR3(KTR_PROC, "thread_exit: thread %p (pid %ld, %s)", td,
(long)p->p_pid, p->p_comm);
+ KASSERT(TAILQ_EMPTY(&td->td_sigqueue.sq_list), ("signal pending"));
if (td->td_standin != NULL) {
/*
@@ -625,6 +627,7 @@ thread_link(struct thread *td, struct ksegrp *kg)
td->td_kflags = 0;
LIST_INIT(&td->td_contested);
+ sigqueue_init(&td->td_sigqueue, p);
callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
TAILQ_INSERT_HEAD(&p->p_threads, td, td_plist);
TAILQ_INSERT_HEAD(&kg->kg_threads, td, td_kglist);
@@ -875,6 +878,10 @@ thread_suspend_check(int return_instead)
(p->p_flag & P_SINGLE_BOUNDARY) && return_instead)
return (1);
+ /* If thread will exit, flush its pending signals */
+ if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td))
+ sigqueue_flush(&td->td_sigqueue);
+
mtx_lock_spin(&sched_lock);
thread_stopped(p);
/*
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 4574aad5e098..c305dc0227aa 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -155,6 +155,7 @@ ast(struct trapframe *framep)
int sig;
#if defined(DEV_NPX) && !defined(SMP)
int ucode;
+ ksiginfo_t ksi;
#endif
td = curthread;
@@ -217,7 +218,10 @@ ast(struct trapframe *framep)
PCB_NPXTRAP);
ucode = npxtrap();
if (ucode != -1) {
- trapsignal(td, SIGFPE, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGFPE;
+ ksi.ksi_code = ucode;
+ trapsignal(td, &ksi);
}
}
#endif
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index f0f3cf8ba96d..2b827a0b74be 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -793,6 +793,6 @@
long id, void *uaddr, void *uaddr2); }
455 AUE_NULL MSTD { int thr_new(struct thr_param *param, \
int param_size); }
-
+456 AUE_NULL MSTD { int sigqueue(pid_t pid, int signum, void *value); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index a5fe2fa2bfcd..531781eb6484 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -177,11 +177,10 @@ SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
int cold = 1;
#ifdef COMPAT_43
-static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
+static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
#endif
#ifdef COMPAT_FREEBSD4
-static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
- u_long code);
+static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask)
#endif
long Maxmem = 0;
@@ -267,11 +266,7 @@ cpu_startup(dummy)
*/
#ifdef COMPAT_43
static void
-osendsig(catcher, sig, mask, code)
- sig_t catcher;
- int sig;
- sigset_t *mask;
- u_long code;
+osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct osigframe sf, *fp;
struct proc *p;
@@ -279,10 +274,14 @@ osendsig(catcher, sig, mask, code)
struct sigacts *psp;
struct trapframe *regs;
int oonstack;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
regs = td->td_frame;
@@ -311,6 +310,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_arg2 = (register_t)&fp->sf_siginfo;
sf.sf_siginfo.si_signo = sig;
sf.sf_siginfo.si_code = code;
+ sf.sf_siginfo.sf_value = ksi->ksi_value;
sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
} else {
/* Old FreeBSD-style arguments. */
@@ -721,8 +721,13 @@ osigreturn(td, uap)
return (EINVAL);
/* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
+ }
if (vm86->vm86_has_vme) {
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
@@ -763,7 +768,12 @@ osigreturn(td, uap)
* other selectors, invalid %eip's and invalid %esp's.
*/
if (!CS_SECURE(scp->sc_cs)) {
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
regs->tf_ds = scp->sc_ds;
@@ -839,8 +849,13 @@ freebsd4_sigreturn(td, uap)
return (EINVAL);
/* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
+ }
if (vm86->vm86_has_vme) {
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
@@ -886,7 +901,12 @@ freebsd4_sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
@@ -946,8 +966,13 @@ sigreturn(td, uap)
return (EINVAL);
/* Go back to user mode if both flags are set. */
- if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
- trapsignal(td, SIGBUS, 0);
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
+ }
if (vm86->vm86_has_vme) {
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
@@ -993,7 +1018,12 @@ sigreturn(td, uap)
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("sigreturn: cs = 0x%x\n", cs);
- trapsignal(td, SIGBUS, T_PROTFLT);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_eip;
+ trapsignal(td, &ksi);
return (EINVAL);
}
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index a74cc27286e4..d27d48fd8f8e 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -432,7 +432,7 @@ bzero(void *buf, size_t len)
}
void
-sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct trapframe *tf;
struct sigframe *sfp;
@@ -441,10 +441,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct thread *td;
struct proc *p;
int oonstack, rndfsize;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame;
@@ -512,9 +516,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Fill siginfo structure.
*/
+ sf.sf_si = ksi->ksi_info;
sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)tf->srr0;
+ sf.sf_si.si_addr = (void *)tf->srr0; /* XXX */
} else {
/* Old FreeBSD-style arguments. */
tf->fixreg[FIRSTARG+1] = code;
@@ -543,25 +547,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
mtx_lock(&psp->ps_mtx);
}
-/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- /* XXXKSE fill other fields */
-}
-
int
sigreturn(struct thread *td, struct sigreturn_args *uap)
{
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index 85bdab95ccd1..72da80516fc9 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -144,6 +144,7 @@ trap(struct trapframe *frame)
struct proc *p;
int sig, type, user;
u_int sticks, ucode;
+ ksiginfo_t ksi;
PCPU_LAZY_INC(cnt.v_trap);
@@ -254,7 +255,12 @@ trap(struct trapframe *frame)
if (sig != 0) {
if (p->p_sysent->sv_transtrap != NULL)
sig = (p->p_sysent->sv_transtrap)(sig, type);
- trapsignal(td, sig, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = (int) ucode; /* XXX, not POSIX */
+ /* ksi.ksi_addr = ? */
+ ksi.ksi_trapno = type;
+ trapsignal(td, &ksi);
}
userret(td, frame, sticks);
diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c
index a74cc27286e4..d27d48fd8f8e 100644
--- a/sys/powerpc/powerpc/machdep.c
+++ b/sys/powerpc/powerpc/machdep.c
@@ -432,7 +432,7 @@ bzero(void *buf, size_t len)
}
void
-sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct trapframe *tf;
struct sigframe *sfp;
@@ -441,10 +441,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct thread *td;
struct proc *p;
int oonstack, rndfsize;
+ int sig;
+ int code;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame;
@@ -512,9 +516,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Fill siginfo structure.
*/
+ sf.sf_si = ksi->ksi_info;
sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)tf->srr0;
+ sf.sf_si.si_addr = (void *)tf->srr0; /* XXX */
} else {
/* Old FreeBSD-style arguments. */
tf->fixreg[FIRSTARG+1] = code;
@@ -543,25 +547,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
mtx_lock(&psp->ps_mtx);
}
-/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- /* XXXKSE fill other fields */
-}
-
int
sigreturn(struct thread *td, struct sigreturn_args *uap)
{
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 85bdab95ccd1..72da80516fc9 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -144,6 +144,7 @@ trap(struct trapframe *frame)
struct proc *p;
int sig, type, user;
u_int sticks, ucode;
+ ksiginfo_t ksi;
PCPU_LAZY_INC(cnt.v_trap);
@@ -254,7 +255,12 @@ trap(struct trapframe *frame)
if (sig != 0) {
if (p->p_sysent->sv_transtrap != NULL)
sig = (p->p_sysent->sv_transtrap)(sig, type);
- trapsignal(td, sig, ucode);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = (int) ucode; /* XXX, not POSIX */
+ /* ksi.ksi_addr = ? */
+ ksi.ksi_trapno = type;
+ trapsignal(td, &ksi);
}
userret(td, frame, sticks);
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 89e12d080fda..9d7e6cfe71ac 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -447,7 +447,7 @@ set_openfirm_callback(ofw_vec_t *vec)
}
void
-sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
struct trapframe *tf;
struct sigframe *sfp;
@@ -458,11 +458,15 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct proc *p;
int oonstack;
u_long sp;
+ int sig;
+ int code;
oonstack = 0;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ code = ksi->ksi_code;
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame;
@@ -513,9 +517,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
tf->tf_out[2] = (register_t)&sfp->sf_uc;
tf->tf_out[4] = (register_t)catcher;
/* Fill siginfo structure. */
- sf.sf_si.si_signo = sig;
- sf.sf_si.si_code = code;
- sf.sf_si.si_addr = (void *)tf->tf_sfar;
+ sf.sf_si = ksi->ksi_info;
+ sf.sf_si.si_addr = (void *)tf->tf_sfar; /* XXX */
/* Copy the sigframe out to the user's stack. */
if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 ||
@@ -541,25 +544,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
mtx_lock(&psp->ps_mtx);
}
-/*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
- struct proc *p;
- struct thread *td;
-
- td = curthread;
- p = td->td_proc;
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- bzero(si, sizeof(*si));
- si->si_signo = sig;
- si->si_code = code;
- /* XXXKSE fill other fields */
-}
-
#ifndef _SYS_SYSPROTO_H_
struct sigreturn_args {
ucontext_t *ucp;
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index 4629dea27627..1a440a659e5e 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -233,6 +233,7 @@ trap(struct trapframe *tf)
u_int sticks;
int error;
int sig;
+ ksiginfo_t ksi;
td = PCPU_GET(curthread);
@@ -284,7 +285,12 @@ trap(struct trapframe *tf)
if (debugger_on_signal &&
(sig == 4 || sig == 10 || sig == 11))
kdb_enter("trapsig");
- trapsignal(td, sig, tf->tf_type);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
+ /* ksi.ksi_addr = ? */
+ ksi.ksi_trap = (int)tf->tf_type;
+ trapsignal(td, &ksi);
}
userret(td, tf, sticks);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 1006b9b8735e..a697c24348ec 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -51,6 +51,7 @@
#include <sys/runq.h>
#include <sys/sigio.h>
#include <sys/signal.h>
+#include <sys/signalvar.h>
#ifndef _KERNEL
#include <sys/time.h> /* For structs itimerval, timeval. */
#else
@@ -253,6 +254,8 @@ struct thread {
struct turnstile *td_turnstile; /* (k) Associated turnstile. */
struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */
lwpid_t td_tid; /* (b) Thread ID. */
+ sigqueue_t td_sigqueue; /* (c) Sigs arrived, not delivered. */
+#define td_siglist td_sigqueue.sq_signals
/* Cleared during fork1() or thread_schedule_upcall(). */
#define td_startzero td_flags
@@ -283,7 +286,6 @@ struct thread {
int td_intrval; /* (j) Return value of TDF_INTERRUPT. */
sigset_t td_oldsigmask; /* (k) Saved mask from pre sigpause. */
sigset_t td_sigmask; /* (c) Current signal mask. */
- sigset_t td_siglist; /* (c) Sigs arrived, not delivered. */
volatile u_int td_generation; /* (k) For detection of preemption */
stack_t td_sigstk; /* (k) Stack ptr and on-stack flag. */
int td_kflags; /* (c) Flags for KSE threading. */
@@ -544,6 +546,8 @@ struct proc {
LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */
LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */
struct mtx p_mtx; /* (n) Lock for this struct. */
+ sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */
+#define p_siglist p_sigqueue.sq_signals
/* The following fields are all zeroed upon creation in fork. */
#define p_startzero p_oppid
@@ -559,7 +563,6 @@ struct proc {
struct vnode *p_tracevp; /* (c + o) Trace to vnode. */
struct ucred *p_tracecred; /* (o) Credentials to trace with. */
struct vnode *p_textvp; /* (b) Vnode of executable. */
- sigset_t p_siglist; /* (c) Sigs not delivered to a td. */
char p_lock; /* (c) Proclock (prevent swap) count. */
struct sigiolst p_sigiolst; /* (c) List of sigio sources. */
int p_sigparent; /* (c) Signal to parent on exit. */
@@ -576,6 +579,7 @@ struct proc {
struct thread *p_xthread; /* (c) Trap thread */
int p_boundary_count;/* (c) Num threads at user boundary */
struct ksegrp *p_procscopegrp;
+ int p_pendingcnt; /* how many signals are pending */
/* End area that is zeroed on creation. */
#define p_endzero p_magic
@@ -908,7 +912,6 @@ int cpu_set_user_tls(struct thread *, void *tls_base);
void cpu_thread_clean(struct thread *);
void cpu_thread_exit(struct thread *);
void cpu_thread_setup(struct thread *td);
-void cpu_thread_siginfo(int sig, u_long code, siginfo_t *si);
void cpu_thread_swapin(struct thread *);
void cpu_thread_swapout(struct thread *);
void ksegrp_link(struct ksegrp *kg, struct proc *p);
@@ -921,7 +924,7 @@ void thread_free(struct thread *td);
void thread_link(struct thread *td, struct ksegrp *kg);
void thread_reap(void);
struct thread *thread_schedule_upcall(struct thread *td, struct kse_upcall *ku);
-void thread_signal_add(struct thread *td, int sig);
+void thread_signal_add(struct thread *td, ksiginfo_t *);
int thread_single(int how);
void thread_single_end(void);
int thread_sleep_check(struct thread *td);
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index e7a327358339..395930167941 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -219,6 +219,16 @@ typedef struct ksiginfo {
/* bits for ksi_flags */
#define KSI_TRAP 0x01 /* Generated by trap. */
+typedef struct sigqueue {
+ sigset_t sq_signals;
+ TAILQ_HEAD(, ksiginfo) sq_list;
+ struct proc *sq_proc;
+ int sq_flags;
+} sigqueue_t;
+
+/* Flags for ksi_flags */
+#define SQ_INIT 0x01
+
#ifdef _KERNEL
/*
@@ -299,6 +309,7 @@ void pgsigio(struct sigio **, int signum, int checkctty);
void pgsignal(struct pgrp *pgrp, int sig, int checkctty);
void postsig(int sig);
void psignal(struct proc *p, int sig);
+int psignal_info(struct proc *p, ksiginfo_t *ksi);
struct sigacts *sigacts_alloc(void);
void sigacts_copy(struct sigacts *dest, struct sigacts *src);
void sigacts_free(struct sigacts *ps);
@@ -308,14 +319,27 @@ void sigexit(struct thread *td, int signum) __dead2;
int sig_ffs(sigset_t *set);
void siginit(struct proc *p);
void signotify(struct thread *td);
-void tdsignal(struct thread *td, int sig, sigtarget_t target);
-void trapsignal(struct thread *td, int sig, u_long code);
+int tdsignal(struct thread *td, int sig, ksiginfo_t *ksi,
+ sigtarget_t target);
+void trapsignal(struct thread *td, ksiginfo_t *);
int ptracestop(struct thread *td, int sig);
+void sigqueue_init(struct sigqueue *queue, struct proc *p);
+void sigqueue_flush(struct sigqueue *queue);
+void sigqueue_delete_proc(struct proc *p, int sig);
+void sigqueue_delete_set(struct sigqueue *queue, sigset_t *set);
+void sigqueue_delete(struct sigqueue *queue, int sig);
+void sigqueue_move_set(struct sigqueue *src, sigqueue_t *dst, sigset_t *);
+int sigqueue_get(struct sigqueue *queue, int sig, ksiginfo_t *info);
+int sigqueue_add(struct sigqueue *queue, int sig, ksiginfo_t *info);
+void sigqueue_collect_set(struct sigqueue *queue, sigset_t *set);
+void sigqueue_move(struct sigqueue *, struct sigqueue *, int sig);
+void sigqueue_delete_set_proc(struct proc *, sigset_t *);
+void sigqueue_delete_stopmask_proc(struct proc *);
/*
* Machine-dependent functions:
*/
-void sendsig(sig_t action, int sig, sigset_t *retmask, u_long code);
+void sendsig(sig_t, ksiginfo_t *, sigset_t *retmask);
#endif /* _KERNEL */
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index 2ac793ce8ee8..2796660f294c 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -35,6 +35,7 @@
#include <bsm/audit.h>
struct thread;
+struct ksiginfo;
typedef int sy_call_t(struct thread *, void *);
@@ -64,8 +65,8 @@ struct sysentvec {
/* translate trap-to-signal mapping */
int (*sv_fixup)(register_t **, struct image_params *);
/* stack fixup function */
- void (*sv_sendsig)(void (*)(int), int, struct __sigset *,
- u_long); /* send signal */
+ void (*sv_sendsig)(void (*)(int), struct ksiginfo *, struct __sigset *);
+ /* send signal */
char *sv_sigcode; /* start of sigtramp code */
int *sv_szsigcode; /* size of sigtramp code */
void (*sv_prepsyscall)(struct trapframe *, int *, u_int *,