Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/usermode Implement signal forwarding to userland fo...
details: https://anonhg.NetBSD.org/src/rev/219c2e65462d
branches: trunk
changeset: 777769:219c2e65462d
user: reinoud <reinoud%NetBSD.org@localhost>
date: Sat Mar 03 21:15:15 2012 +0000
description:
Implement signal forwarding to userland for usermode kernels. Especially
SIGFPE is important since the urkel shouldn't stop when a userland program
devides by zero!
diffstat:
sys/arch/usermode/dev/cpu.c | 10 ++++----
sys/arch/usermode/dev/ttycons.c | 8 +++---
sys/arch/usermode/include/intr.h | 4 +-
sys/arch/usermode/include/thunk.h | 4 +-
sys/arch/usermode/target/i386/cpu_i386.c | 7 +++--
sys/arch/usermode/usermode/thunk.c | 9 +++++--
sys/arch/usermode/usermode/trap.c | 38 +++++++++++++++++++++++++------
7 files changed, 53 insertions(+), 27 deletions(-)
diffs (289 lines):
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/dev/cpu.c
--- a/sys/arch/usermode/dev/cpu.c Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/dev/cpu.c Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.69 2012/01/21 22:09:56 reinoud Exp $ */
+/* $NetBSD: cpu.c,v 1.70 2012/03/03 21:15:15 reinoud Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
#include "opt_hz.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.69 2012/01/21 22:09:56 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.70 2012/03/03 21:15:15 reinoud Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -242,7 +242,7 @@
/* create atomic switcher */
thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic,
- 2, oldlwp, newlwp, NULL);
+ 2, oldlwp, newlwp, NULL, NULL);
KASSERT(sc);
if (oldpcb) {
@@ -341,7 +341,7 @@
lwp_startup(curcpu()->ci_stash, curlwp);
/* actual jump */
- thunk_makecontext(ucp, (void (*)(void)) func, 1, arg, NULL, NULL);
+ thunk_makecontext(ucp, (void (*)(void)) func, 1, arg, NULL, NULL, NULL);
thunk_setcontext(ucp);
}
@@ -381,7 +381,7 @@
pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
thunk_makecontext(&pcb2->pcb_ucp,
(void (*)(void)) cpu_lwp_trampoline,
- 3, &pcb2->pcb_ucp, func, arg);
+ 3, &pcb2->pcb_ucp, func, arg, NULL);
}
void
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/dev/ttycons.c
--- a/sys/arch/usermode/dev/ttycons.c Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/dev/ttycons.c Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ttycons.c,v 1.18 2012/01/21 22:09:57 reinoud Exp $ */
+/* $NetBSD: ttycons.c,v 1.19 2012/03/03 21:15:15 reinoud Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.18 2012/01/21 22:09:57 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.19 2012/03/03 21:15:15 reinoud Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -389,7 +389,7 @@
* argument 'pc' and 'va' are not used.
*/
static void
-ttycons_ctrlc(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+ttycons_ctrlc(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
{
struct ttycons_softc *sc;
@@ -416,7 +416,7 @@
* argument 'pc' and 'va' are not used.
*/
static void
-ttycons_ctrlz(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+ttycons_ctrlz(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
{
struct ttycons_softc *sc;
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/include/intr.h
--- a/sys/arch/usermode/include/intr.h Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/include/intr.h Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.8 2012/02/02 11:13:41 reinoud Exp $ */
+/* $NetBSD: intr.h,v 1.9 2012/03/03 21:15:16 reinoud Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -41,7 +41,7 @@
#define splx(x) spllower(x)
/* traps */
-typedef void (sigfunc_t)(vaddr_t from_userland, vaddr_t pc, vaddr_t va);
+typedef void (sigfunc_t)(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va);
extern void setup_signal_handlers(void);
extern void signal_intr_establish(int sig, sigfunc_t f);
extern void *sigio_intr_establish(int (*)(void *), void *);
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/include/thunk.h
--- a/sys/arch/usermode/include/thunk.h Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/include/thunk.h Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.h,v 1.60 2012/01/21 19:17:33 reinoud Exp $ */
+/* $NetBSD: thunk.h,v 1.61 2012/03/03 21:15:16 reinoud Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -101,7 +101,7 @@
int thunk_getcontext(ucontext_t *);
int thunk_setcontext(const ucontext_t *);
void thunk_makecontext(ucontext_t *ucp, void (*func)(void),
- int nargs, void *arg1, void *arg2, void *arg3);
+ int nargs, void *arg1, void *arg2, void *arg3, void *arg4);
int thunk_swapcontext(ucontext_t *, ucontext_t *);
int thunk_tcgetattr(int, struct thunk_termios *);
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/target/i386/cpu_i386.c
--- a/sys/arch/usermode/target/i386/cpu_i386.c Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/target/i386/cpu_i386.c Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_i386.c,v 1.3 2012/01/21 22:05:06 reinoud Exp $ */
+/* $NetBSD: cpu_i386.c,v 1.4 2012/03/03 21:15:16 reinoud Exp $ */
/*-
* Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_i386.c,v 1.3 2012/01/21 22:05:06 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_i386.c,v 1.4 2012/03/03 21:15:16 reinoud Exp $");
#include <sys/types.h>
#include <sys/systm.h>
@@ -205,7 +205,8 @@
/* use given stack */
ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */
ucp->uc_stack.ss_size = 0; //pack->ep_ssize;
- thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL);
+ thunk_makecontext(ucp, (void *) pack->ep_entry,
+ 0, NULL, NULL, NULL, NULL);
/* patch up */
reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/usermode/thunk.c
--- a/sys/arch/usermode/usermode/thunk.c Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/usermode/thunk.c Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.c,v 1.80 2012/01/21 19:17:33 reinoud Exp $ */
+/* $NetBSD: thunk.c,v 1.81 2012/03/03 21:15:16 reinoud Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifdef __NetBSD__
-__RCSID("$NetBSD: thunk.c,v 1.80 2012/01/21 19:17:33 reinoud Exp $");
+__RCSID("$NetBSD: thunk.c,v 1.81 2012/03/03 21:15:16 reinoud Exp $");
#endif
#include <sys/types.h>
@@ -373,7 +373,7 @@
void
thunk_makecontext(ucontext_t *ucp, void (*func)(void),
- int nargs, void *arg1, void *arg2, void *arg3)
+ int nargs, void *arg1, void *arg2, void *arg3, void *arg4)
{
switch (nargs) {
case 0:
@@ -388,6 +388,9 @@
case 3:
makecontext(ucp, func, 3, arg1, arg2, arg3);
break;
+ case 4:
+ makecontext(ucp, func, 4, arg1, arg2, arg3, arg4);
+ break;
default:
warnx("%s: nargs (%d) too big\n", __func__, nargs);
abort();
diff -r 0d81e1e35298 -r 219c2e65462d sys/arch/usermode/usermode/trap.c
--- a/sys/arch/usermode/usermode/trap.c Sat Mar 03 15:14:03 2012 +0000
+++ b/sys/arch/usermode/usermode/trap.c Sat Mar 03 21:15:15 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.63 2012/02/15 15:20:53 reinoud Exp $ */
+/* $NetBSD: trap.c,v 1.64 2012/03/03 21:15:16 reinoud Exp $ */
/*-
* Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.63 2012/02/15 15:20:53 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.64 2012/03/03 21:15:16 reinoud Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -59,6 +59,7 @@
static sigfunc_t illegal_instruction;
static sigfunc_t alarm;
static sigfunc_t sigio;
+static sigfunc_t pass_on;
/* raw signal handlers */
static stack_t sigstk;
@@ -125,7 +126,7 @@
/* TRAP */
/* ABRT */
/* SIGEMT */
- /* SIGFPE XXX! */
+ signal_intr_establish(SIGFPE, pass_on);
/* KILL */
signal_intr_establish(SIGBUS, pagefault);
signal_intr_establish(SIGSEGV, pagefault);
@@ -369,7 +370,7 @@
thunk_makecontext(&jump_ucp,
(void (*)(void)) f,
- 3, (void *) from_userland, (void *) pc, (void *) va);
+ 4, info, (void *) from_userland, (void *) pc, (void *) va);
/* switch to the new context on return from signal */
thunk_setcontext(&jump_ucp);
@@ -398,7 +399,7 @@
* pmap reference fault or let uvm handle it.
*/
static void
-pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+pagefault(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
{
struct proc *p;
struct lwp *l;
@@ -514,7 +515,7 @@
* arguments 'pc' and 'va' are ignored here
*/
static void
-illegal_instruction(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+illegal_instruction(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
{
struct lwp *l = curlwp;
struct pcb *pcb = lwp_getpcb(l);
@@ -551,13 +552,34 @@
}
+static void
+pass_on(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+{
+ struct lwp *l = curlwp;
+ struct pcb *pcb = lwp_getpcb(l);
+ ucontext_t *ucp = &pcb->pcb_userret_ucp;
+ ksiginfo_t ksi;
+
+ KASSERT(from_userland);
+ KSI_INIT_TRAP(&ksi);
+ ksi.ksi_signo = info->si_signo;
+ ksi.ksi_trap = 0; /* XXX ? */
+ ksi.ksi_errno = info->si_errno;
+ ksi.ksi_code = info->si_code;
+ ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */
+
+ trapsignal(l, &ksi);
+ userret(l);
+}
+
+
/*
* handle alarm, a clock ticker.
*
* arguments 'pc' and 'va' are ignored here
*/
static void
-alarm(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+alarm(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
{
struct lwp *l = curlwp;
struct pcb *pcb = lwp_getpcb(l); KASSERT(pcb);
@@ -580,7 +602,7 @@
* arguments 'pc' and 'va' are ignored here
*/
static void
-sigio(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
+sigio(siginfo_t *info, vaddr_t from_userland, vaddr_t pc, vaddr_t va)
{
struct lwp *l = curlwp;
struct pcb *pcb = lwp_getpcb(l); KASSERT(pcb);
Home |
Main Index |
Thread Index |
Old Index