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);

Reply via email to