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