diff options
author | David Xu <davidxu@FreeBSD.org> | 2005-10-14 12:43:47 +0000 |
---|---|---|
committer | David Xu <davidxu@FreeBSD.org> | 2005-10-14 12:43:47 +0000 |
commit | 9104847f216771dfda5d78a6dd4974882f1a55cd (patch) | |
tree | 95d82b1a11b0c187223f8ac12f020b19901fa750 /sys/ia64 | |
parent | de90a634cba8adb2ba64538ba6d99c72b5794507 (diff) | |
download | src-9104847f216771dfda5d78a6dd4974882f1a55cd.tar.gz src-9104847f216771dfda5d78a6dd4974882f1a55cd.zip |
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
Notes
Notes:
svn path=/head/; revision=151316
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia32/ia32_signal.c | 4 | ||||
-rw-r--r-- | sys/ia64/ia32/ia32_trap.c | 14 | ||||
-rw-r--r-- | sys/ia64/ia64/machdep.c | 31 | ||||
-rw-r--r-- | sys/ia64/ia64/trap.c | 6 |
4 files changed, 29 insertions, 26 deletions
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) { |