summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2005-10-14 12:43:47 +0000
committerdavidxu <davidxu@FreeBSD.org>2005-10-14 12:43:47 +0000
commit3fbdb3c21524d9d95278ada1d61b4d1e6bee654b (patch)
tree95d82b1a11b0c187223f8ac12f020b19901fa750 /sys/alpha
parent6b2407fb7677ef2b8cef5c0925b3fe88a6ec7ca4 (diff)
downloadFreeBSD-src-3fbdb3c21524d9d95278ada1d61b4d1e6bee654b.zip
FreeBSD-src-3fbdb3c21524d9d95278ada1d61b4d1e6bee654b.tar.gz
1. Change prototype of trapsignal and sendsig to use ksiginfo_t *, most
changes in MD code are trivial, before this change, trapsignal and sendsig use discrete parameters, now they uses member fields of ksiginfo_t structure. For sendsig, this change allows us to pass POSIX realtime signal value to user code. 2. Remove cpu_thread_siginfo, it is no longer needed because we now always generate ksiginfo_t data and feed it to libpthread. 3. Add p_sigqueue to proc structure to hold shared signals which were blocked by all threads in the proc. 4. Add td_sigqueue to thread structure to hold all signals delivered to thread. 5. i386 and amd64 now return POSIX standard si_code, other arches will be fixed. 6. In this sigqueue implementation, pending signal set is kept as before, an extra siginfo list holds additional siginfo_t data for signals. kernel code uses psignal() still behavior as before, it won't be failed even under memory pressure, only exception is when deleting a signal, we should call sigqueue_delete to remove signal from sigqueue but not SIGDELSET. Current there is no kernel code will deliver a signal with additional data, so kernel should be as stable as before, a ksiginfo can carry more information, for example, allow signal to be delivered but throw away siginfo data if memory is not enough. SIGKILL and SIGSTOP have fast path in sigqueue_add, because they can not be caught or masked. The sigqueue() syscall allows user code to queue a signal to target process, if resource is unavailable, EAGAIN will be returned as specification said. Just before thread exits, signal queue memory will be freed by sigqueue_flush. Current, all signals are allowed to be queued, not only realtime signals. Earlier patch reviewed by: jhb, deischen Tested on: i386, amd64
Diffstat (limited to 'sys/alpha')
-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
5 files changed, 37 insertions, 39 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index e09b5f6..b12e039 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 dc800ef..7a62956f 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 784ec81..b6ce778 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 355cb1c..56e2298 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 ec1fbeb..1ef5ac4 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 */
OpenPOWER on IntegriCloud