Module Name: src Committed By: reinoud Date: Sat Mar 3 21:15:16 UTC 2012
Modified Files: src/sys/arch/usermode/dev: cpu.c ttycons.c src/sys/arch/usermode/include: intr.h thunk.h src/sys/arch/usermode/target/i386: cpu_i386.c src/sys/arch/usermode/usermode: thunk.c trap.c Log Message: 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! To generate a diff of this commit: cvs rdiff -u -r1.69 -r1.70 src/sys/arch/usermode/dev/cpu.c cvs rdiff -u -r1.18 -r1.19 src/sys/arch/usermode/dev/ttycons.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/usermode/include/intr.h cvs rdiff -u -r1.60 -r1.61 src/sys/arch/usermode/include/thunk.h cvs rdiff -u -r1.3 -r1.4 src/sys/arch/usermode/target/i386/cpu_i386.c cvs rdiff -u -r1.80 -r1.81 src/sys/arch/usermode/usermode/thunk.c cvs rdiff -u -r1.63 -r1.64 src/sys/arch/usermode/usermode/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/usermode/dev/cpu.c diff -u src/sys/arch/usermode/dev/cpu.c:1.69 src/sys/arch/usermode/dev/cpu.c:1.70 --- src/sys/arch/usermode/dev/cpu.c:1.69 Sat Jan 21 22:09:56 2012 +++ src/sys/arch/usermode/dev/cpu.c Sat Mar 3 21:15:15 2012 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw /* 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 @@ cpu_lwp_trampoline(ucontext_t *ucp, void 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 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 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 Index: src/sys/arch/usermode/dev/ttycons.c diff -u src/sys/arch/usermode/dev/ttycons.c:1.18 src/sys/arch/usermode/dev/ttycons.c:1.19 --- src/sys/arch/usermode/dev/ttycons.c:1.18 Sat Jan 21 22:09:57 2012 +++ src/sys/arch/usermode/dev/ttycons.c Sat Mar 3 21:15:15 2012 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ ttycons_softintr(void *priv) * 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 @@ ttycons_softctrlc(void *priv) * 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; Index: src/sys/arch/usermode/include/intr.h diff -u src/sys/arch/usermode/include/intr.h:1.8 src/sys/arch/usermode/include/intr.h:1.9 --- src/sys/arch/usermode/include/intr.h:1.8 Thu Feb 2 11:13:41 2012 +++ src/sys/arch/usermode/include/intr.h Sat Mar 3 21:15:16 2012 @@ -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 <jmcne...@invisible.ca> @@ -41,7 +41,7 @@ void spllower(int); #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 *); Index: src/sys/arch/usermode/include/thunk.h diff -u src/sys/arch/usermode/include/thunk.h:1.60 src/sys/arch/usermode/include/thunk.h:1.61 --- src/sys/arch/usermode/include/thunk.h:1.60 Sat Jan 21 19:17:33 2012 +++ src/sys/arch/usermode/include/thunk.h Sat Mar 3 21:15:16 2012 @@ -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 <jmcne...@invisible.ca> @@ -101,7 +101,7 @@ void thunk_seterrno(int err); 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 *); Index: src/sys/arch/usermode/target/i386/cpu_i386.c diff -u src/sys/arch/usermode/target/i386/cpu_i386.c:1.3 src/sys/arch/usermode/target/i386/cpu_i386.c:1.4 --- src/sys/arch/usermode/target/i386/cpu_i386.c:1.3 Sat Jan 21 22:05:06 2012 +++ src/sys/arch/usermode/target/i386/cpu_i386.c Sat Mar 3 21:15:16 2012 @@ -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 <rein...@netbsd.org> @@ -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 @@ setregs(struct lwp *l, struct exec_packa /* 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 */ Index: src/sys/arch/usermode/usermode/thunk.c diff -u src/sys/arch/usermode/usermode/thunk.c:1.80 src/sys/arch/usermode/usermode/thunk.c:1.81 --- src/sys/arch/usermode/usermode/thunk.c:1.80 Sat Jan 21 19:17:33 2012 +++ src/sys/arch/usermode/usermode/thunk.c Sat Mar 3 21:15:16 2012 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ thunk_setcontext(const ucontext_t *ucp) 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 @@ thunk_makecontext(ucontext_t *ucp, void 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(); Index: src/sys/arch/usermode/usermode/trap.c diff -u src/sys/arch/usermode/usermode/trap.c:1.63 src/sys/arch/usermode/usermode/trap.c:1.64 --- src/sys/arch/usermode/usermode/trap.c:1.63 Wed Feb 15 15:20:53 2012 +++ src/sys/arch/usermode/usermode/trap.c Sat Mar 3 21:15:16 2012 @@ -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 <rein...@netbsd.org> @@ -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 pagefault; 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 @@ setup_signal_handlers(void) /* 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 @@ handle_signal(int sig, siginfo_t *info, 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 @@ signal_intr_establish(int sig, sigfunc_t * 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 @@ out_quick: * 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 @@ illegal_instruction(vaddr_t from_userlan } +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 @@ alarm(vaddr_t from_userland, vaddr_t pc, * 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);