diff options
author | davidxu <davidxu@FreeBSD.org> | 2005-10-14 12:43:47 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2005-10-14 12:43:47 +0000 |
commit | 3fbdb3c21524d9d95278ada1d61b4d1e6bee654b (patch) | |
tree | 95d82b1a11b0c187223f8ac12f020b19901fa750 /sys/arm | |
parent | 6b2407fb7677ef2b8cef5c0925b3fe88a6ec7ca4 (diff) | |
download | FreeBSD-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/arm')
-rw-r--r-- | sys/arm/arm/machdep.c | 23 | ||||
-rw-r--r-- | sys/arm/arm/trap.c | 10 | ||||
-rw-r--r-- | sys/arm/arm/undefined.c | 21 |
3 files changed, 32 insertions, 22 deletions
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 7043a7b..1e9f5b1 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 8248783..f858af0 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 3d7d3cb..94a3ec1 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) { |