Sat Jan 21 22:09:57 2012 UTC ()
Complete rewrite of the signal and spl framework for NetBSD/usermode

Signals are now moved from the sigaltstack ASAP and stacked on a replacement
stack for each processes.

Preemption now works though could be enhanced a bit more


(reinoud)
diff -r1.25 -r1.26 src/sys/arch/usermode/dev/clock.c
diff -r1.68 -r1.69 src/sys/arch/usermode/dev/cpu.c
diff -r1.4 -r1.5 src/sys/arch/usermode/dev/if_veth.c
diff -r1.29 -r1.30 src/sys/arch/usermode/dev/ld_thunkbus.c
diff -r1.17 -r1.18 src/sys/arch/usermode/dev/ttycons.c
diff -r1.6 -r1.7 src/sys/arch/usermode/include/intr.h
diff -r1.14 -r1.15 src/sys/arch/usermode/usermode/intr.c
diff -r1.60 -r1.61 src/sys/arch/usermode/usermode/trap.c

cvs diff -r1.25 -r1.26 src/sys/arch/usermode/dev/clock.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/clock.c 2012/01/14 21:42:51 1.25
+++ src/sys/arch/usermode/dev/clock.c 2012/01/21 22:09:56 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: clock.c,v 1.25 2012/01/14 21:42:51 reinoud Exp $ */ 1/* $NetBSD: clock.c,v 1.26 2012/01/21 22:09:56 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -19,130 +19,120 @@ @@ -19,130 +19,120 @@
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_hz.h" 29#include "opt_hz.h"
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.25 2012/01/14 21:42:51 reinoud Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.26 2012/01/21 22:09:56 reinoud Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/proc.h> 35#include <sys/proc.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/device.h> 37#include <sys/device.h>
38#include <sys/lwp.h> 38#include <sys/lwp.h>
39#include <sys/cpu.h> 39#include <sys/cpu.h>
40#include <sys/malloc.h> 40#include <sys/malloc.h>
41#include <sys/timetc.h> 41#include <sys/timetc.h>
42#include <sys/time.h> 42#include <sys/time.h>
43 43
44#include <machine/pcb.h> 44#include <machine/pcb.h>
45#include <machine/mainbus.h> 45#include <machine/mainbus.h>
46#include <machine/thunk.h> 46#include <machine/thunk.h>
47 47
48#include <dev/clock_subr.h> 48#include <dev/clock_subr.h>
49 49
50static int clock_match(device_t, cfdata_t, void *); 50static int clock_match(device_t, cfdata_t, void *);
51static void clock_attach(device_t, device_t, void *); 51static void clock_attach(device_t, device_t, void *);
52 52
53static void clock_signal(int sig, siginfo_t *info, void *ctx); 
54static unsigned int clock_getcounter(struct timecounter *); 53static unsigned int clock_getcounter(struct timecounter *);
55 54
56static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *); 55static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *);
57 56
 57extern void setup_clock_intr(void);
 58void clock_intr(void *priv);
 59
 60
58struct clock_softc { 61struct clock_softc {
59 device_t sc_dev; 62 device_t sc_dev;
60 struct todr_chip_handle sc_todr; 63 struct todr_chip_handle sc_todr;
61}; 64};
62 65
63static struct timecounter clock_timecounter = { 66static struct timecounter clock_timecounter = {
64 clock_getcounter, /* get_timecount */ 67 clock_getcounter, /* get_timecount */
65 0, /* no poll_pps */ 68 0, /* no poll_pps */
66 ~0u, /* counter_mask */ 69 ~0u, /* counter_mask */
67 1000000000ULL, /* frequency */ 70 1000000000ULL, /* frequency */
68 "CLOCK_MONOTONIC", /* name */ 71 "CLOCK_MONOTONIC", /* name */
69 -100, /* quality */ 72 -100, /* quality */
70 NULL, /* prev */ 73 NULL, /* prev */
71 NULL, /* next */ 74 NULL, /* next */
72}; 75};
73 76
74timer_t clock_timerid; 77timer_t clock_timerid;
 78int clock_running = 0;
75 79
76CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc), 80CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc),
77 clock_match, clock_attach, NULL, NULL); 81 clock_match, clock_attach, NULL, NULL);
78 82
79static int 83static int
80clock_match(device_t parent, cfdata_t match, void *opaque) 84clock_match(device_t parent, cfdata_t match, void *opaque)
81{ 85{
82 struct thunkbus_attach_args *taa = opaque; 86 struct thunkbus_attach_args *taa = opaque;
83 87
84 if (taa->taa_type != THUNKBUS_TYPE_CLOCK) 88 if (taa->taa_type != THUNKBUS_TYPE_CLOCK)
85 return 0; 89 return 0;
86 90
87 return 1; 91 return 1;
88} 92}
89 93
90static void 94static void
91clock_attach(device_t parent, device_t self, void *opaque) 95clock_attach(device_t parent, device_t self, void *opaque)
92{ 96{
93 static struct sigaction sa; 
94 struct clock_softc *sc = device_private(self); 97 struct clock_softc *sc = device_private(self);
95 98
96 aprint_naive("\n"); 99 aprint_naive("\n");
97 aprint_normal("\n"); 100 aprint_normal("\n");
98 101
99 sc->sc_dev = self; 102 sc->sc_dev = self;
100 103
101 sc->sc_todr.todr_gettime = clock_todr_gettime; 104 sc->sc_todr.todr_gettime = clock_todr_gettime;
102 todr_attach(&sc->sc_todr); 105 todr_attach(&sc->sc_todr);
103 106
104 memset(&sa, 0, sizeof(sa)); 
105 thunk_sigemptyset(&sa.sa_mask); 
106 sa.sa_sigaction = clock_signal; 
107 sa.sa_flags = SA_RESTART | SA_ONSTACK; 
108 if (thunk_sigaction(SIGALRM, &sa, NULL) == -1) 
109 panic("couldn't register SIGALRM handler : %d", 
110 thunk_geterrno()); 
111 
112 clock_timerid = thunk_timer_attach(); 107 clock_timerid = thunk_timer_attach();
113 
114 clock_timecounter.tc_quality = 1000; 108 clock_timecounter.tc_quality = 1000;
115 tc_init(&clock_timecounter); 109 tc_init(&clock_timecounter);
 110
 111 setup_clock_intr();
 112 clock_running = 1;
116} 113}
117 114
118static void 115void
119clock_intr(void *priv) 116clock_intr(void *priv)
120{ 117{
121 struct clockframe cf; 118 struct clockframe cf;
122 int nticks = thunk_timer_getoverrun(clock_timerid) + 1; 119 int nticks = thunk_timer_getoverrun(clock_timerid) + 1;
123 120
124 while (nticks-- > 0) { 121 while (nticks-- > 0) {
125 hardclock(&cf); 122 hardclock(&cf);
126 } 123 }
127} 124}
128 125
129static void 
130clock_signal(int sig, siginfo_t *info, void *ctx) 
131{ 
132 curcpu()->ci_idepth++; 
133 spl_intr(IPL_SOFTCLOCK, clock_intr, NULL); 
134 curcpu()->ci_idepth--; 
135} 
136 126
137static unsigned int 127static unsigned int
138clock_getcounter(struct timecounter *tc) 128clock_getcounter(struct timecounter *tc)
139{ 129{
140 return thunk_getcounter(); 130 return thunk_getcounter();
141} 131}
142 132
143static int 133static int
144clock_todr_gettime(struct todr_chip_handle *tch, struct timeval *tv) 134clock_todr_gettime(struct todr_chip_handle *tch, struct timeval *tv)
145{ 135{
146 struct thunk_timeval ttv; 136 struct thunk_timeval ttv;
147 int error; 137 int error;
148 138

cvs diff -r1.68 -r1.69 src/sys/arch/usermode/dev/cpu.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/cpu.c 2012/01/18 19:17:02 1.68
+++ src/sys/arch/usermode/dev/cpu.c 2012/01/21 22:09:56 1.69
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.c,v 1.68 2012/01/18 19:17:02 reinoud Exp $ */ 1/* $NetBSD: cpu.c,v 1.69 2012/01/21 22:09:56 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_cpu.h" 29#include "opt_cpu.h"
30#include "opt_hz.h" 30#include "opt_hz.h"
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.68 2012/01/18 19:17:02 reinoud Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.69 2012/01/21 22:09:56 reinoud Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/conf.h> 36#include <sys/conf.h>
37#include <sys/proc.h> 37#include <sys/proc.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/reboot.h> 40#include <sys/reboot.h>
41#include <sys/lwp.h> 41#include <sys/lwp.h>
42#include <sys/cpu.h> 42#include <sys/cpu.h>
43#include <sys/mbuf.h> 43#include <sys/mbuf.h>
44#include <sys/msgbuf.h> 44#include <sys/msgbuf.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
@@ -234,32 +234,33 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw @@ -234,32 +234,33 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw
234 if (newpcb) { 234 if (newpcb) {
235 thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, " 235 thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, "
236 "uc_stack.ss_size=%d\n", 236 "uc_stack.ss_size=%d\n",
237 newpcb->pcb_ucp.uc_link, 237 newpcb->pcb_ucp.uc_link,
238 newpcb->pcb_ucp.uc_stack.ss_sp, 238 newpcb->pcb_ucp.uc_stack.ss_sp,
239 (int)newpcb->pcb_ucp.uc_stack.ss_size); 239 (int)newpcb->pcb_ucp.uc_stack.ss_size);
240 } 240 }
241#endif /* !CPU_DEBUG */ 241#endif /* !CPU_DEBUG */
242 242
243 /* create atomic switcher */ 243 /* create atomic switcher */
244 thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic, 244 thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic,
245 2, oldlwp, newlwp, NULL); 245 2, oldlwp, newlwp, NULL);
246 246
247 if (!oldpcb) { 247 KASSERT(sc);
248 thunk_setcontext(&sc->sc_ucp); 248 if (oldpcb) {
249 /* never returns */ 
250 } else { 
251 thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp); 249 thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp);
252 /* returns here */ 250 /* returns here */
 251 } else {
 252 thunk_setcontext(&sc->sc_ucp);
 253 /* never returns */
253 } 254 }
254 255
255#ifdef CPU_DEBUG 256#ifdef CPU_DEBUG
256 thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp); 257 thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp);
257#endif 258#endif
258 return ci->ci_stash; 259 return ci->ci_stash;
259} 260}
260 261
261void 262void
262cpu_dumpconf(void) 263cpu_dumpconf(void)
263{ 264{
264#ifdef CPU_DEBUG 265#ifdef CPU_DEBUG
265 thunk_printf_debug("cpu_dumpconf\n"); 266 thunk_printf_debug("cpu_dumpconf\n");
@@ -364,28 +365,30 @@ cpu_lwp_fork(struct lwp *l1, struct lwp  @@ -364,28 +365,30 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
364 /* copy the PCB and its switchframes from parent */ 365 /* copy the PCB and its switchframes from parent */
365 memcpy(pcb2, pcb1, sizeof(struct pcb)); 366 memcpy(pcb2, pcb1, sizeof(struct pcb));
366 367
367 /* refresh context */ 368 /* refresh context */
368 if (thunk_getcontext(&pcb2->pcb_ucp)) 369 if (thunk_getcontext(&pcb2->pcb_ucp))
369 panic("getcontext failed"); 370 panic("getcontext failed");
370 371
371 /* recalculate the system stack top */ 372 /* recalculate the system stack top */
372 pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE; 373 pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE;
373 374
374 /* get l2 its own stack */ 375 /* get l2 its own stack */
375 pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack; 376 pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack;
376 pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack; 377 pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack;
377 pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; 
378 pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp; 378 pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp;
 379
 380 thunk_sigemptyset(&pcb2->pcb_ucp.uc_sigmask);
 381 pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
379 thunk_makecontext(&pcb2->pcb_ucp, 382 thunk_makecontext(&pcb2->pcb_ucp,
380 (void (*)(void)) cpu_lwp_trampoline, 383 (void (*)(void)) cpu_lwp_trampoline,
381 3, &pcb2->pcb_ucp, func, arg); 384 3, &pcb2->pcb_ucp, func, arg);
382} 385}
383 386
384void 387void
385cpu_initclocks(void) 388cpu_initclocks(void)
386{ 389{
387 extern timer_t clock_timerid; 390 extern timer_t clock_timerid;
388 391
389 thunk_timer_start(clock_timerid, HZ); 392 thunk_timer_start(clock_timerid, HZ);
390} 393}
391 394
@@ -402,27 +405,29 @@ cpu_startup(void) @@ -402,27 +405,29 @@ cpu_startup(void)
402 initmsgbuf(um_msgbuf, msgbufsize); 405 initmsgbuf(um_msgbuf, msgbufsize);
403 406
404 /* allocate a submap for physio, 1Mb enough? */ 407 /* allocate a submap for physio, 1Mb enough? */
405 minaddr = 0; 408 minaddr = 0;
406 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 409 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
407 1024 * 1024, 0, false, NULL); 410 1024 * 1024, 0, false, NULL);
408 411
409 /* say hi! */ 412 /* say hi! */
410 banner(); 413 banner();
411 414
412 /* init lwp0 */ 415 /* init lwp0 */
413 memset(&lwp0pcb, 0, sizeof(lwp0pcb)); 416 memset(&lwp0pcb, 0, sizeof(lwp0pcb));
414 thunk_getcontext(&lwp0pcb.pcb_ucp); 417 thunk_getcontext(&lwp0pcb.pcb_ucp);
 418 thunk_sigemptyset(&lwp0pcb.pcb_ucp.uc_sigmask);
415 lwp0pcb.pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; 419 lwp0pcb.pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
 420
416 uvm_lwp_setuarea(&lwp0, (vaddr_t) &lwp0pcb); 421 uvm_lwp_setuarea(&lwp0, (vaddr_t) &lwp0pcb);
417 memcpy(&lwp0pcb.pcb_userret_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t)); 422 memcpy(&lwp0pcb.pcb_userret_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
418 423
419 /* set stack top */ 424 /* set stack top */
420 lwp0pcb.sys_stack_top = lwp0pcb.sys_stack + TRAPSTACKSIZE; 425 lwp0pcb.sys_stack_top = lwp0pcb.sys_stack + TRAPSTACKSIZE;
421} 426}
422 427
423void 428void
424cpu_rootconf(void) 429cpu_rootconf(void)
425{ 430{
426 extern char *usermode_root_device; 431 extern char *usermode_root_device;
427 device_t rdev; 432 device_t rdev;
428 433

cvs diff -r1.4 -r1.5 src/sys/arch/usermode/dev/if_veth.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/if_veth.c 2012/01/15 10:51:12 1.4
+++ src/sys/arch/usermode/dev/if_veth.c 2012/01/21 22:09:56 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_veth.c,v 1.4 2012/01/15 10:51:12 jmcneill Exp $ */ 1/* $NetBSD: if_veth.c,v 1.5 2012/01/21 22:09:56 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: if_veth.c,v 1.4 2012/01/15 10:51:12 jmcneill Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: if_veth.c,v 1.5 2012/01/21 22:09:56 reinoud Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/proc.h> 33#include <sys/proc.h>
34#include <sys/systm.h> 34#include <sys/systm.h>
35#include <sys/kernel.h> 35#include <sys/kernel.h>
36#include <sys/mbuf.h> 36#include <sys/mbuf.h>
37#include <sys/socket.h> 37#include <sys/socket.h>
38#include <sys/device.h> 38#include <sys/device.h>
39 39
40#include <net/if.h> 40#include <net/if.h>
41#include <net/if_ether.h> 41#include <net/if_ether.h>
42#include <net/if_media.h> 42#include <net/if_media.h>
43 43
@@ -179,30 +179,27 @@ veth_init(struct ifnet *ifp) @@ -179,30 +179,27 @@ veth_init(struct ifnet *ifp)
179 veth_stop(ifp, 0); 179 veth_stop(ifp, 0);
180 180
181 ifp->if_flags |= IFF_RUNNING; 181 ifp->if_flags |= IFF_RUNNING;
182 ifp->if_flags &= ~IFF_OACTIVE; 182 ifp->if_flags &= ~IFF_OACTIVE;
183 183
184 return 0; 184 return 0;
185} 185}
186 186
187static int 187static int
188veth_rx(void *priv) 188veth_rx(void *priv)
189{ 189{
190 struct veth_softc *sc = priv; 190 struct veth_softc *sc = priv;
191 191
192 curcpu()->ci_idepth++; 192 softint_schedule(sc->sc_rx_intr);
193 spl_intr(IPL_NET, softint_schedule, sc->sc_rx_intr); 
194 curcpu()->ci_idepth--; 
195 
196 return 0; 193 return 0;
197} 194}
198 195
199static void 196static void
200veth_softrx(void *priv) 197veth_softrx(void *priv)
201{ 198{
202 struct veth_softc *sc = priv; 199 struct veth_softc *sc = priv;
203 struct ifnet *ifp = &sc->sc_ec.ec_if; 200 struct ifnet *ifp = &sc->sc_ec.ec_if;
204 struct mbuf *m; 201 struct mbuf *m;
205 ssize_t len; 202 ssize_t len;
206 int s, avail; 203 int s, avail;
207 204
208 for (;;) { 205 for (;;) {

cvs diff -r1.29 -r1.30 src/sys/arch/usermode/dev/ld_thunkbus.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/ld_thunkbus.c 2012/01/09 21:01:31 1.29
+++ src/sys/arch/usermode/dev/ld_thunkbus.c 2012/01/21 22:09:57 1.30
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ld_thunkbus.c,v 1.29 2012/01/09 21:01:31 reinoud Exp $ */ 1/* $NetBSD: ld_thunkbus.c,v 1.30 2012/01/21 22:09:57 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: ld_thunkbus.c,v 1.29 2012/01/09 21:01:31 reinoud Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: ld_thunkbus.c,v 1.30 2012/01/21 22:09:57 reinoud Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/proc.h> 33#include <sys/proc.h>
34#include <sys/systm.h> 34#include <sys/systm.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/buf.h> 36#include <sys/buf.h>
37#include <sys/disk.h> 37#include <sys/disk.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39 39
40#include <dev/ldvar.h> 40#include <dev/ldvar.h>
41 41
42#include <machine/mainbus.h> 42#include <machine/mainbus.h>
43#include <machine/thunk.h> 43#include <machine/thunk.h>
@@ -135,29 +135,27 @@ ld_thunkbus_attach(device_t parent, devi @@ -135,29 +135,27 @@ ld_thunkbus_attach(device_t parent, devi
135 135
136 sc->busy = false; 136 sc->busy = false;
137 137
138 ldattach(ld); 138 ldattach(ld);
139} 139}
140 140
141#ifdef LD_USE_AIO 141#ifdef LD_USE_AIO
142static int 142static int
143ld_aio_sig(void *arg) 143ld_aio_sig(void *arg)
144{ 144{
145 struct ld_softc *ld = arg; 145 struct ld_softc *ld = arg;
146 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 146 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
147 147
148 curcpu()->ci_idepth++; 148 softint_schedule(sc->sc_ih);
149 spl_intr(IPL_BIO, softint_schedule, sc->sc_ih); 
150 curcpu()->ci_idepth--; 
151 149
152 return 0; 150 return 0;
153} 151}
154 152
155static int 153static int
156ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) 154ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp)
157{ 155{
158 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 156 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
159 struct ld_thunkbus_transfer *tt = &sc->sc_tt; 157 struct ld_thunkbus_transfer *tt = &sc->sc_tt;
160 off_t offset = bp->b_rawblkno * ld->sc_secsize; 158 off_t offset = bp->b_rawblkno * ld->sc_secsize;
161 off_t disksize = ld->sc_secsize * ld->sc_secperunit; 159 off_t disksize = ld->sc_secsize * ld->sc_secperunit;
162 int error; 160 int error;
163 161
@@ -240,27 +238,27 @@ ld_thunkbus_complete(void *arg) @@ -240,27 +238,27 @@ ld_thunkbus_complete(void *arg)
240 238
241 239
242static int 240static int
243ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) 241ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp)
244{ 242{
245 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 243 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
246 struct ld_thunkbus_transfer *tt = &sc->sc_tt; 244 struct ld_thunkbus_transfer *tt = &sc->sc_tt;
247 245
248 tt->tt_sc = sc; 246 tt->tt_sc = sc;
249 tt->tt_bp = bp; 247 tt->tt_bp = bp;
250 248
251 /* let the softint do the work */ 249 /* let the softint do the work */
252 sc->busy = true; 250 sc->busy = true;
253 spl_intr(IPL_BIO, softint_schedule, sc->sc_ih); 251 softint_schedule(sc->sc_ih);
254 252
255 return 0; 253 return 0;
256} 254}
257 255
258static void 256static void
259ld_thunkbus_complete(void *arg) 257ld_thunkbus_complete(void *arg)
260{ 258{
261 struct ld_softc *ld = arg; 259 struct ld_softc *ld = arg;
262 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 260 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
263 struct ld_thunkbus_transfer *tt = &sc->sc_tt; 261 struct ld_thunkbus_transfer *tt = &sc->sc_tt;
264 struct buf *bp = tt->tt_bp; 262 struct buf *bp = tt->tt_bp;
265 off_t offset = bp->b_rawblkno * ld->sc_secsize; 263 off_t offset = bp->b_rawblkno * ld->sc_secsize;
266 int64_t ret; 264 int64_t ret;

cvs diff -r1.17 -r1.18 src/sys/arch/usermode/dev/ttycons.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/ttycons.c 2011/12/27 20:59:45 1.17
+++ src/sys/arch/usermode/dev/ttycons.c 2012/01/21 22:09:57 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ttycons.c,v 1.17 2011/12/27 20:59:45 jmcneill Exp $ */ 1/* $NetBSD: ttycons.c,v 1.18 2012/01/21 22:09:57 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.17 2011/12/27 20:59:45 jmcneill Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.18 2012/01/21 22:09:57 reinoud Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/conf.h> 33#include <sys/conf.h>
34#include <sys/proc.h> 34#include <sys/proc.h>
35#include <sys/systm.h> 35#include <sys/systm.h>
36#include <sys/device.h> 36#include <sys/device.h>
37#include <sys/kauth.h> 37#include <sys/kauth.h>
38#include <sys/termios.h> 38#include <sys/termios.h>
39#include <sys/tty.h> 39#include <sys/tty.h>
40 40
41#include <dev/cons.h> 41#include <dev/cons.h>
42 42
43#include <machine/mainbus.h> 43#include <machine/mainbus.h>
@@ -93,29 +93,29 @@ const struct cdevsw ttycons_cdevsw = { @@ -93,29 +93,29 @@ const struct cdevsw ttycons_cdevsw = {
93 .d_stop = ttycons_stop, 93 .d_stop = ttycons_stop,
94 .d_tty = ttycons_tty, 94 .d_tty = ttycons_tty,
95 .d_poll = ttycons_poll, 95 .d_poll = ttycons_poll,
96 .d_kqfilter = ttykqfilter, 96 .d_kqfilter = ttykqfilter,
97 .d_flag = D_TTY, 97 .d_flag = D_TTY,
98}; 98};
99 99
100static void ttycons_start(struct tty *); 100static void ttycons_start(struct tty *);
101static int ttycons_param(struct tty *, struct termios *); 101static int ttycons_param(struct tty *, struct termios *);
102 102
103static int ttycons_intr(void *); 103static int ttycons_intr(void *);
104static void ttycons_softintr(void *); 104static void ttycons_softintr(void *);
105 105
106static void ttycons_ctrlc(int); 106static sigfunc_t ttycons_ctrlc;
107static void ttycons_softctrlc(void *); 107static void ttycons_softctrlc(void *);
108static void ttycons_ctrlz(int); 108static sigfunc_t ttycons_ctrlz;
109static void ttycons_softctrlz(void *); 109static void ttycons_softctrlz(void *);
110 110
111static int 111static int
112ttycons_match(device_t parent, cfdata_t match, void *opaque) 112ttycons_match(device_t parent, cfdata_t match, void *opaque)
113{ 113{
114 struct thunkbus_attach_args *taa = opaque; 114 struct thunkbus_attach_args *taa = opaque;
115 115
116 if (taa->taa_type != THUNKBUS_TYPE_TTYCONS) 116 if (taa->taa_type != THUNKBUS_TYPE_TTYCONS)
117 return 0; 117 return 0;
118 118
119 return 1; 119 return 1;
120} 120}
121 121
@@ -144,28 +144,29 @@ ttycons_attach(device_t parent, device_t @@ -144,28 +144,29 @@ ttycons_attach(device_t parent, device_t
144 if (sc->sc_rd_sih == NULL) 144 if (sc->sc_rd_sih == NULL)
145 panic("couldn't establish ttycons intr handler\n"); 145 panic("couldn't establish ttycons intr handler\n");
146 146
147 sc->sc_ctrlc_sih = softint_establish(SOFTINT_SERIAL, 147 sc->sc_ctrlc_sih = softint_establish(SOFTINT_SERIAL,
148 ttycons_softctrlc, sc); 148 ttycons_softctrlc, sc);
149 if (sc->sc_ctrlc_sih == NULL) 149 if (sc->sc_ctrlc_sih == NULL)
150 panic("couldn't establish ttycons ctrlc handler\n"); 150 panic("couldn't establish ttycons ctrlc handler\n");
151 sc->sc_ctrlz_sih = softint_establish(SOFTINT_SERIAL, 151 sc->sc_ctrlz_sih = softint_establish(SOFTINT_SERIAL,
152 ttycons_softctrlz, sc); 152 ttycons_softctrlz, sc);
153 if (sc->sc_ctrlz_sih == NULL) 153 if (sc->sc_ctrlz_sih == NULL)
154 panic("couldn't establish ttycons ctrlz handler\n"); 154 panic("couldn't establish ttycons ctrlz handler\n");
155 155
156 sigio_intr_establish(ttycons_intr, sc); 156 sigio_intr_establish(ttycons_intr, sc);
157 thunk_signal(SIGINT, ttycons_ctrlc); 157 signal_intr_establish(SIGINT, ttycons_ctrlc);
158 thunk_signal(SIGTSTP, ttycons_ctrlz); 158 signal_intr_establish(SIGTSTP, ttycons_ctrlz);
 159
159 if (thunk_set_stdin_sigio(true) != 0) 160 if (thunk_set_stdin_sigio(true) != 0)
160 panic("couldn't enable stdin async mode"); 161 panic("couldn't enable stdin async mode");
161} 162}
162 163
163void 164void
164ttycons_consinit(void) 165ttycons_consinit(void)
165{ 166{
166 struct thunk_termios t; 167 struct thunk_termios t;
167 168
168 thunk_tcgetattr(0, &t); 169 thunk_tcgetattr(0, &t);
169 t.c_lflag &= ~(ECHO|ICANON); 170 t.c_lflag &= ~(ECHO|ICANON);
170 t.c_cc[VTIME] = 0; 171 t.c_cc[VTIME] = 0;
171 t.c_cc[VMIN] = 1; 172 t.c_cc[VMIN] = 1;
@@ -351,84 +352,86 @@ static int @@ -351,84 +352,86 @@ static int
351ttycons_param(struct tty *t, struct termios *c) 352ttycons_param(struct tty *t, struct termios *c)
352{ 353{
353 t->t_ispeed = c->c_ispeed; 354 t->t_ispeed = c->c_ispeed;
354 t->t_ospeed = c->c_ospeed; 355 t->t_ospeed = c->c_ospeed;
355 t->t_cflag = c->c_cflag; 356 t->t_cflag = c->c_cflag;
356 return 0; 357 return 0;
357} 358}
358 359
359static int 360static int
360ttycons_intr(void *priv) 361ttycons_intr(void *priv)
361{ 362{
362 struct ttycons_softc *sc = priv; 363 struct ttycons_softc *sc = priv;
363 364
364 curcpu()->ci_idepth++; 365 softint_schedule(sc->sc_rd_sih);
365 spl_intr(IPL_SERIAL, softint_schedule, sc->sc_rd_sih); 
366 curcpu()->ci_idepth--; 
367 366
368 return 0; 367 return 0;
369} 368}
370 369
371static void 370static void
372ttycons_softintr(void *priv) 371ttycons_softintr(void *priv)
373{ 372{
374 struct ttycons_softc *sc = priv; 373 struct ttycons_softc *sc = priv;
375 struct tty *t = sc->sc_tty; 374 struct tty *t = sc->sc_tty;
376 unsigned char ch; 375 unsigned char ch;
377 int c; 376 int c;
378 377
379 while ((c = thunk_pollchar()) >= 0) { 378 while ((c = thunk_pollchar()) >= 0) {
380 ch = (unsigned char)c; 379 ch = (unsigned char)c;
381 cn_check_magic(t->t_dev, ch, ttycons_cnm_state); 380 cn_check_magic(t->t_dev, ch, ttycons_cnm_state);
382 t->t_linesw->l_rint(ch, t); 381 t->t_linesw->l_rint(ch, t);
383 } 382 }
384} 383}
385 384
 385
 386/*
 387 * handle SIGINT signal from trap.c
 388 *
 389 * argument 'pc' and 'va' are not used.
 390 */
386static void 391static void
387ttycons_ctrlc(int sig) 392ttycons_ctrlc(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
388{ 393{
389 struct ttycons_softc *sc; 394 struct ttycons_softc *sc;
390 395
391 curcpu()->ci_idepth++; 
392 sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev)); 396 sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev));
393 if (sc) { 397 if (sc)
394 spl_intr(IPL_SERIAL, softint_schedule, sc->sc_ctrlc_sih); 398 softint_schedule(sc->sc_ctrlc_sih);
395 } 
396 curcpu()->ci_idepth--; 
397 399
398} 400}
399 401
400static void 402static void
401ttycons_softctrlc(void *priv) 403ttycons_softctrlc(void *priv)
402{ 404{
403 struct ttycons_softc *sc = priv; 405 struct ttycons_softc *sc = priv;
404 struct tty *t = sc->sc_tty; 406 struct tty *t = sc->sc_tty;
405 unsigned char ch = 3; /* ETX */ 407 unsigned char ch = 3; /* ETX */
406 408
407 cn_check_magic(t->t_dev, ch, ttycons_cnm_state); 409 cn_check_magic(t->t_dev, ch, ttycons_cnm_state);
408 t->t_linesw->l_rint(ch, t); 410 t->t_linesw->l_rint(ch, t);
409} 411}
410 412
 413/*
 414 * handle SIGTSTP signal from trap.c
 415 *
 416 * argument 'pc' and 'va' are not used.
 417 */
411static void 418static void
412ttycons_ctrlz(int sig) 419ttycons_ctrlz(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
413{ 420{
414 struct ttycons_softc *sc; 421 struct ttycons_softc *sc;
415 422
416 curcpu()->ci_idepth++; 
417 sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev)); 423 sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev));
418 if (sc) { 424 if (sc)
419 spl_intr(IPL_SERIAL, softint_schedule, sc->sc_ctrlz_sih); 425 softint_schedule(sc->sc_ctrlz_sih);
420 } 
421 curcpu()->ci_idepth--; 
422 
423} 426}
424 427
425static void 428static void
426ttycons_softctrlz(void *priv) 429ttycons_softctrlz(void *priv)
427{ 430{
428 struct ttycons_softc *sc = priv; 431 struct ttycons_softc *sc = priv;
429 struct tty *t = sc->sc_tty; 432 struct tty *t = sc->sc_tty;
430 unsigned char ch = 26; /* SUB */ 433 unsigned char ch = 26; /* SUB */
431 434
432 cn_check_magic(t->t_dev, ch, ttycons_cnm_state); 435 cn_check_magic(t->t_dev, ch, ttycons_cnm_state);
433 t->t_linesw->l_rint(ch, t); 436 t->t_linesw->l_rint(ch, t);
434} 437}

cvs diff -r1.6 -r1.7 src/sys/arch/usermode/include/intr.h (expand / switch to unified diff)

--- src/sys/arch/usermode/include/intr.h 2011/12/26 22:04:35 1.6
+++ src/sys/arch/usermode/include/intr.h 2012/01/21 22:09:57 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: intr.h,v 1.6 2011/12/26 22:04:35 jmcneill Exp $ */ 1/* $NetBSD: intr.h,v 1.7 2012/01/21 22:09:57 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -22,44 +22,51 @@ @@ -22,44 +22,51 @@
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#ifndef _ARCH_USERMODE_INCLUDE_INTR_H 29#ifndef _ARCH_USERMODE_INCLUDE_INTR_H
30#define _ARCH_USERMODE_INCLUDE_INTR_H 30#define _ARCH_USERMODE_INCLUDE_INTR_H
31 31
32#include <machine/intrdefs.h> 32#include <machine/intrdefs.h>
33#include <sys/siginfo.h> 33#include <sys/siginfo.h>
34 34
35void sigio_signal_handler(int, siginfo_t *, void *); 35/* spl */
36void * sigio_intr_establish(int (*)(void *), void *); 
37 
38void splinit(void); 36void splinit(void);
39int splraise(int); 37int splraise(int);
40void spllower(int); 38void spllower(int);
41void spl_intr(int x, void (*func)(void *), void *arg); 39void spl_intr(int x, void (*func)(void *), void *arg);
42 40
43#define spl0() spllower(IPL_NONE) 41#define spl0() spllower(IPL_NONE)
44#define splx(x) spllower(x) 42#define splx(x) spllower(x)
45 43
 44/* traps */
 45typedef void (sigfunc_t)(vaddr_t from_userland, vaddr_t pc, vaddr_t va);
 46extern void setup_signal_handlers(void);
 47extern void signal_intr_establish(int sig, sigfunc_t f);
 48extern void *sigio_intr_establish(int (*)(void *), void *);
 49
 50/* spl implementation */
46typedef uint8_t ipl_t; 51typedef uint8_t ipl_t;
47typedef struct { 52typedef struct {
48 ipl_t _ipl; 53 ipl_t _ipl;
49} ipl_cookie_t; 54} ipl_cookie_t;
50 55
51static inline ipl_cookie_t 56static inline ipl_cookie_t
52makeiplcookie(ipl_t ipl) 57makeiplcookie(ipl_t ipl)
53{ 58{
54 return (ipl_cookie_t){._ipl = ipl}; 59 return (ipl_cookie_t){._ipl = ipl};
55} 60}
56 61
57static inline int 62static inline int
58splraiseipl(ipl_cookie_t icookie) 63splraiseipl(ipl_cookie_t icookie)
59{ 64{
60 return splraise(icookie._ipl); 65 return splraise(icookie._ipl);
61} 66}
62 67
63#include <sys/spl.h> 68#include <sys/spl.h>
64 69
 70/* for trap.c */
 71
65#endif /* !_ARCH_USERMODE_INCLUDE_INTR_H */ 72#endif /* !_ARCH_USERMODE_INCLUDE_INTR_H */

cvs diff -r1.14 -r1.15 src/sys/arch/usermode/usermode/intr.c (expand / switch to unified diff)

--- src/sys/arch/usermode/usermode/intr.c 2012/01/09 22:20:53 1.14
+++ src/sys/arch/usermode/usermode/intr.c 2012/01/21 22:09:57 1.15
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: intr.c,v 1.14 2012/01/09 22:20:53 reinoud Exp $ */ 1/* $NetBSD: intr.c,v 1.15 2012/01/21 22:09:57 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,162 +17,46 @@ @@ -17,162 +17,46 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.14 2012/01/09 22:20:53 reinoud Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.15 2012/01/21 22:09:57 reinoud Exp $");
31 31
32#include <sys/types.h> 32#include <sys/types.h>
33 33
34#include <machine/intr.h> 34#include <machine/intr.h>
35#include <machine/thunk.h> 35#include <machine/thunk.h>
36 36
37struct intr_handler { 37int usermode_x = IPL_NONE;
38 int (*func)(void *); 
39 void *arg; 
40}; 
41 
42#define SIGIO_MAX_HANDLERS 8 
43 
44static struct intr_handler sigio_intr_handler[SIGIO_MAX_HANDLERS]; 
45 
46//#define INTR_USE_SIGPROCMASK 
47 
48#define MAX_QUEUED_EVENTS 128 
49 
50static int usermode_x = IPL_NONE; 
51 
52#ifdef INTR_USE_SIGPROCMASK 
53static bool block_sigalrm = false; 
54#endif 
55 
56 
57struct spl_intr_event { 
58 void (*func)(void *); 
59 void *arg; 
60}; 
61 
62struct spl_intr_event spl_intrs[IPL_HIGH+1][MAX_QUEUED_EVENTS]; 
63int spl_intr_wr[IPL_HIGH+1]; 
64int spl_intr_rd[IPL_HIGH+1]; 
65 38
66void 39void
67splinit(void) 40splinit(void)
68{ 41{
69 int i; 42 /* nothing */
70 for (i = 0; i <= IPL_HIGH; i++) { 
71 spl_intr_rd[i] = 1; 
72 spl_intr_wr[i] = 1; 
73 } 
74} 
75 
76void 
77spl_intr(int x, void (*func)(void *), void *arg) 
78{ 
79 struct spl_intr_event *spli; 
80 
81 if (x >= usermode_x) { 
82 func(arg); 
83 return; 
84 } 
85 
86// dprintf_debug("spl_intr: queue %d when %d\n", x, usermode_x); 
87 spli = &spl_intrs[x][spl_intr_wr[x]]; 
88 spli->func = func; 
89 spli->arg = arg; 
90 
91 spl_intr_wr[x] = (spl_intr_wr[x] + 1) % MAX_QUEUED_EVENTS; 
92 if (spl_intr_wr[x] == spl_intr_rd[x]) { 
93 thunk_printf("%s: spl list %d full!\n", __func__, x); 
94 panic("%s: spl list %d full!\n", __func__, x); 
95 } 
96} 43}
97 44
98int 45int
99splraise(int x) 46splraise(int x)
100{ 47{
101 int oldx = usermode_x; 48 int oldx = usermode_x;
102 49
103 if (x > usermode_x) { 50 if (x > usermode_x)
104 usermode_x = x; 51 usermode_x = x;
105 } 
106 
107#ifdef INTR_USE_SIGPROCMASK 
108 if (x >= IPL_SCHED && !block_sigalrm) { 
109 thunk_sigblock(SIGALRM); 
110 block_sigalrm = true; 
111 } 
112#endif 
113 52
114 return oldx; 53 return oldx;
115} 54}
116 55
117void 56void
118spllower(int x) 57spllower(int x)
119{ 58{
120 struct spl_intr_event *spli; 59 if (usermode_x > x)
121 int y; 
122 
123 /* `eat' interrupts that came by until we got back to x */ 
124 if (usermode_x > x) { 
125//restart: 
126 for (y = usermode_x; y >= x; y--) { 
127 while (spl_intr_rd[y] != spl_intr_wr[y]) { 
128// dprintf_debug("spl y %d firing\n", y); 
129 spli = &spl_intrs[y][spl_intr_rd[y]]; 
130 if (!spli->func) 
131 panic("%s: spli->func is NULL for ipl %d, rd %d, wr %d\n", 
132 __func__, y, spl_intr_rd[y], spl_intr_wr[y]); 
133 spli->func(spli->arg); 
134 spl_intr_rd[y] = (spl_intr_rd[y] + 1) % MAX_QUEUED_EVENTS; 
135// goto restart; 
136 } 
137 } 
138 usermode_x = x; 60 usermode_x = x;
139 } 
140 
141#ifdef INTR_USE_SIGPROCMASK 
142 if (x < IPL_SCHED && block_sigalrm) { 
143 thunk_sigunblock(SIGALRM); 
144 block_sigalrm = false; 
145 } 
146#endif 
147} 61}
148 62
149void 
150sigio_signal_handler(int sig, siginfo_t *info, void *ctx) 
151{ 
152 struct intr_handler *sih; 
153 unsigned int n; 
154 
155 for (n = 0; n < SIGIO_MAX_HANDLERS; n++) { 
156 sih = &sigio_intr_handler[n]; 
157 if (sih->func) 
158 sih->func(sih->arg); 
159 } 
160} 
161 
162void * 
163sigio_intr_establish(int (*func)(void *), void *arg) 
164{ 
165 struct intr_handler *sih; 
166 unsigned int n; 
167 
168 for (n = 0; n < SIGIO_MAX_HANDLERS; n++) { 
169 sih = &sigio_intr_handler[n]; 
170 if (sih->func == NULL) { 
171 sih->func = func; 
172 sih->arg = arg; 
173 return sih; 
174 } 
175 } 
176 
177 panic("increase SIGIO_MAX_HANDLERS"); 
178} 

cvs diff -r1.60 -r1.61 src/sys/arch/usermode/usermode/trap.c (expand / switch to unified diff)

--- src/sys/arch/usermode/usermode/trap.c 2012/01/18 12:39:45 1.60
+++ src/sys/arch/usermode/usermode/trap.c 2012/01/21 22:09:57 1.61
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: trap.c,v 1.60 2012/01/18 12:39:45 reinoud Exp $ */ 1/* $NetBSD: trap.c,v 1.61 2012/01/21 22:09:57 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Reinoud Zandijk <reinoud@netbsd.org> 4 * Copyright (c) 2011 Reinoud Zandijk <reinoud@netbsd.org>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,142 +17,211 @@ @@ -17,142 +17,211 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.60 2012/01/18 12:39:45 reinoud Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.61 2012/01/21 22:09:57 reinoud Exp $");
31 31
32#include <sys/types.h> 32#include <sys/types.h>
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/systm.h> 34#include <sys/systm.h>
35#include <sys/proc.h> 35#include <sys/proc.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/userret.h> 37#include <sys/userret.h>
38#include <sys/kauth.h> 38#include <sys/kauth.h>
39#include <sys/errno.h> 39#include <sys/errno.h>
40 40
41#include <uvm/uvm_extern.h> 41#include <uvm/uvm_extern.h>
42#include <machine/cpu.h> 42#include <machine/cpu.h>
43#include <machine/pcb.h> 43#include <machine/pcb.h>
44#include <machine/pmap.h> 44#include <machine/pmap.h>
45#include <machine/machdep.h> 45#include <machine/machdep.h>
46#include <machine/intr.h> 46#include <machine/intr.h>
47#include <machine/thunk.h> 47#include <machine/thunk.h>
48 48
 49/* define maximum signal number */
 50#ifndef NSIG
 51#define NSIG 64
 52#endif
49 53
50/* forwards and externals */ 54/* forwards and externals */
51void setup_signal_handlers(void); 55void setup_signal_handlers(void);
52void stop_all_signal_handlers(void); 56void stop_all_signal_handlers(void);
53 57
54static void mem_access_handler(int sig, siginfo_t *info, void *ctx); 58static sigfunc_t pagefault;
55static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx); 59static sigfunc_t illegal_instruction;
56extern int errno; 60static sigfunc_t alarm;
 61static sigfunc_t sigio;
 62
 63/* raw signal handlers */
 64static stack_t sigstk;
 65ucontext_t jump_ucp;
57 66
58static void pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va); 67sigfunc_t *sig_funcs[NSIG];
59static void illegal_instruction(vaddr_t from_userland); 
60 68
61bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype); 69/* segv, bus */
 70extern bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype);
62 71
63static stack_t sigstk; 72/* alarm */
 73void setup_clock_intr(void);
 74extern void clock_intr(void *priv);
64 75
 76extern int clock_running;
 77void *alrm_ih;
 78
 79/* sigio handlers */
 80struct intr_handler {
 81 int (*func)(void *);
 82 void *arg;
 83};
 84#define SIGIO_MAX_HANDLERS 8
 85static struct intr_handler sigio_intr_handler[SIGIO_MAX_HANDLERS];
 86
 87/* misc */
65int astpending = 0; 88int astpending = 0;
66 89
 90
 91/* XXX why is it here ? */
67void 92void
68startlwp(void *arg) 93startlwp(void *arg)
69{ 94{
70 /* nothing here */ 95 /* nothing here */
71} 96}
72 97
73 98
74void 99void
75setup_signal_handlers(void) 100setup_signal_handlers(void)
76{ 101{
77 static struct sigaction sa; 102 int i;
78 103
 104 /*
 105 * Set up the alternative signal stack. This prevents signals to be
 106 * pushed on the NetBSD/usermode userland's stack with all desastrous
 107 * effects. Especially ld.so and friends have such tiny stacks that
 108 * its not feasable.
 109 */
79 if ((sigstk.ss_sp = thunk_malloc(SIGSTKSZ)) == NULL) 110 if ((sigstk.ss_sp = thunk_malloc(SIGSTKSZ)) == NULL)
80 panic("can't allocate signal stack space\n"); 111 panic("can't allocate signal stack space\n");
81 sigstk.ss_size = SIGSTKSZ; 112 sigstk.ss_size = SIGSTKSZ;
82 sigstk.ss_flags = 0; 113 sigstk.ss_flags = 0;
83 if (thunk_sigaltstack(&sigstk, 0) < 0) 114 if (thunk_sigaltstack(&sigstk, 0) < 0)
84 panic("can't set alternate stacksize: %d", 115 panic("can't set alternate stacksize: %d",
85 thunk_geterrno()); 116 thunk_geterrno());
86 117
87 /* SIGBUS and SIGSEGV need to be reentrant hence the SA_NODEFER */ 118 for (i = 0; i < NSIG; i++)
88 sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK | SA_NODEFER; 119 sig_funcs[i] = NULL;
89 sa.sa_sigaction = mem_access_handler; 
90 thunk_sigemptyset(&sa.sa_mask); 
91 if (thunk_sigaction(SIGSEGV, &sa, NULL) == -1) 
92 panic("couldn't register SIGSEGV handler: %d", 
93 thunk_geterrno()); 
94 if (thunk_sigaction(SIGBUS, &sa, NULL) == -1) 
95 panic("couldn't register SIGBUS handler: %d", thunk_geterrno()); 
96 
97 sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 
98 sa.sa_sigaction = illegal_instruction_handler; 
99 thunk_sigemptyset(&sa.sa_mask); 
100 if (thunk_sigaction(SIGILL, &sa, NULL) == -1) 
101 panic("couldn't register SIGILL handler: %d", thunk_geterrno()); 
102 120
103 sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 121 /* HUP */
104 sa.sa_sigaction = sigio_signal_handler; 122 /* INT */ /* ttycons ^C */
105 thunk_sigemptyset(&sa.sa_mask); 123 /* QUIT */
106 if (thunk_sigaction(SIGIO, &sa, NULL) == -1) 124 signal_intr_establish(SIGILL, illegal_instruction);
107 panic("couldn't register SIGIO handler: %d", thunk_geterrno()); 125 /* TRAP */
 126 /* ABRT */
 127 /* SIGEMT */
 128 /* SIGFPE XXX! */
 129 /* KILL */
 130 signal_intr_establish(SIGBUS, pagefault);
 131 signal_intr_establish(SIGSEGV, pagefault);
 132 /* SYS */
 133 /* PIPE */
 134 signal_intr_establish(SIGALRM, alarm);
 135 /* TERM */
 136 /* URG */
 137 /* STOP */
 138 /* TSTP */ /* ttycons ^Z */
 139 /* CONT */
 140 /* CHLD */
 141 /* GTTIN */
 142 /* TTOU */
 143 signal_intr_establish(SIGIO, sigio);
 144 /* XCPU */
 145 /* XFSZ */
 146 /* VTALRM */
 147 /* PROF */
 148 /* WINCH */
 149 /* INFO */
 150 /* USR1 */
 151 /* USR2 */
 152 /* PWR */
108} 153}
109 154
110 155
 156/* XXX yes this is blunt */
111void 157void
112stop_all_signal_handlers(void) 158stop_all_signal_handlers(void)
113{ 159{
114 thunk_sigblock(SIGALRM); 160 int i;
115 thunk_sigblock(SIGIO); 161 for (i = 0; i < NSIG; i++)
116 thunk_sigblock(SIGILL); 162 if (sig_funcs[i])
117 thunk_sigblock(SIGSEGV); 163 thunk_sigblock(i);
118 thunk_sigblock(SIGBUS); 
119} 164}
120 165
121 166
122/* ast and userret */ 
123void 167void
124userret(struct lwp *l) 168setup_clock_intr(void)
125{ 169{
126 /* invoke MI userret code */ 170 /* setup soft interrupt handler */
127 mi_userret(l); 171 alrm_ih = softint_establish(SOFTINT_CLOCK,
 172 clock_intr, NULL);
 173}
 174
 175
 176/* ast and userret */
 177static void
 178ast(struct lwp *l)
 179{
 180 struct pcb *pcb;
128 181
129 while (astpending) { 182 if (!astpending)
130 astpending = 0; 183 return;
 184
 185 astpending = 0;
 186 curcpu()->ci_data.cpu_ntrap++;
131 187
132 curcpu()->ci_data.cpu_ntrap++; 
133#if 0 188#if 0
134 /* profiling */ 189 /* profiling */
135 if (l->l_pflag & LP_OWEUPC) { 190 if (l->l_pflag & LP_OWEUPC) {
136 l->l_pflag &= ~LP_OWEUPC; 191 l->l_pflag &= ~LP_OWEUPC;
137 ADDUPROF(l); 192 ADDUPROF(l);
138 } 193 }
139#endif 194#endif
140 /* allow a forced task switch */ 
141 if (l->l_cpu->ci_want_resched) 
142 preempt(); 
143 195
144 mi_userret(l); 196 /* allow a forced task switch */
 197 if (curcpu()->ci_want_resched) {
 198 curcpu()->ci_want_resched = 0;
 199 preempt();
 200 /* returns here! */
145 } 201 }
 202 KASSERT(l == curlwp); KASSERT(l);
 203 pcb = lwp_getpcb(l); KASSERT(pcb);
 204 mi_userret(l);
 205}
 206
 207
 208void
 209userret(struct lwp *l)
 210{
 211 /* invoke MI userret code */
 212 mi_userret(l);
 213
 214 ast(l);
146} 215}
147 216
148 217
149#ifdef DEBUG 218#ifdef DEBUG
150/* 219/*
151 * Uncomment the following if you want to receive information about what 220 * Uncomment the following if you want to receive information about what
152 * triggered the fault. Mainly for debugging and porting purposes 221 * triggered the fault. Mainly for debugging and porting purposes
153 */ 222 */
154static void 223static void
155print_mem_access_siginfo(int sig, siginfo_t *info, void *ctx, 224print_mem_access_siginfo(int sig, siginfo_t *info, void *ctx,
156 vaddr_t pc, vaddr_t va, vaddr_t sp) 225 vaddr_t pc, vaddr_t va, vaddr_t sp)
157{ 226{
158#if 0 227#if 0
@@ -165,31 +234,28 @@ print_mem_access_siginfo(int sig, siginf @@ -165,31 +234,28 @@ print_mem_access_siginfo(int sig, siginf
165 if (info->si_code == SEGV_ACCERR) 234 if (info->si_code == SEGV_ACCERR)
166 thunk_printf_debug("\t\tSEGV_ACCERR\n"); 235 thunk_printf_debug("\t\tSEGV_ACCERR\n");
167 if (info->si_code == BUS_ADRALN) 236 if (info->si_code == BUS_ADRALN)
168 thunk_printf_debug("\t\tBUS_ADRALN\n"); 237 thunk_printf_debug("\t\tBUS_ADRALN\n");
169 if (info->si_code == BUS_ADRERR) 238 if (info->si_code == BUS_ADRERR)
170 thunk_printf_debug("\t\tBUS_ADRERR\n"); 239 thunk_printf_debug("\t\tBUS_ADRERR\n");
171 if (info->si_code == BUS_OBJERR) 240 if (info->si_code == BUS_OBJERR)
172 thunk_printf_debug("\t\tBUS_OBJERR\n"); 241 thunk_printf_debug("\t\tBUS_OBJERR\n");
173 thunk_printf_debug("\tsi_addr = %p\n", info->si_addr); 242 thunk_printf_debug("\tsi_addr = %p\n", info->si_addr);
174 thunk_printf_debug("\tsi_trap = %d\n", info->si_trap); 243 thunk_printf_debug("\tsi_trap = %d\n", info->si_trap);
175#endif 244#endif
176 245
177#if 0 246#if 0
178 printf("memaccess error, pc %p, va %p, " 247 thunk_printf("memaccess error, pc %p, va %p, sp %p\n",
179 "sys_stack %p, sp %p, stack top %p\n", 248 (void *) pc, (void *) va, (void *) sp);
180 (void *) pc, (void *) va, 
181 (void *) pcb->sys_stack, (void *) sp, 
182 (void *) pcb->sys_stack_top); 
183#endif 249#endif
184} 250}
185 251
186/* 252/*
187 * Uncomment the following if you want to receive information about what 253 * Uncomment the following if you want to receive information about what
188 * triggered the fault. Mainly for debugging and porting purposes 254 * triggered the fault. Mainly for debugging and porting purposes
189 */ 255 */
190static void 256static void
191print_illegal_instruction_siginfo(int sig, siginfo_t *info, void *ctx, 257print_illegal_instruction_siginfo(int sig, siginfo_t *info, void *ctx,
192 vaddr_t pc, vaddr_t va, vaddr_t sp) 258 vaddr_t pc, vaddr_t va, vaddr_t sp)
193{ 259{
194#if 0 260#if 0
195 thunk_printf("SIGILL!\n"); 261 thunk_printf("SIGILL!\n");
@@ -210,155 +276,125 @@ print_illegal_instruction_siginfo(int si @@ -210,155 +276,125 @@ print_illegal_instruction_siginfo(int si
210 thunk_printf("\t\tPrivileged register"); 276 thunk_printf("\t\tPrivileged register");
211 if (info->si_code == ILL_COPROC) 277 if (info->si_code == ILL_COPROC)
212 thunk_printf("\t\tCoprocessor error"); 278 thunk_printf("\t\tCoprocessor error");
213 if (info->si_code == ILL_BADSTK) 279 if (info->si_code == ILL_BADSTK)
214 thunk_printf("\t\tInternal stack error"); 280 thunk_printf("\t\tInternal stack error");
215 thunk_printf("\tsi_addr = %p\n", info->si_addr); 281 thunk_printf("\tsi_addr = %p\n", info->si_addr);
216 thunk_printf("\tsi_trap = %d\n", info->si_trap); 282 thunk_printf("\tsi_trap = %d\n", info->si_trap);
217 283
218 thunk_printf("%p : ", info->si_addr); 284 thunk_printf("%p : ", info->si_addr);
219 for (int i = 0; i < 10; i++) 285 for (int i = 0; i < 10; i++)
220 thunk_printf("%02x ", *((uint8_t *) info->si_addr + i)); 286 thunk_printf("%02x ", *((uint8_t *) info->si_addr + i));
221 thunk_printf("\n"); 287 thunk_printf("\n");
222#endif 288#endif
 289
 290#if 0
 291 thunk_printf("sigill\n");
 292#endif
223} 293}
224#else /* DEBUG */ 294#else /* DEBUG */
225#define print_mem_access_siginfo(s, i, c, p, v, sp) 295#define print_mem_access_siginfo(s, i, c, p, v, sp)
226#define print_illegal_instruction_siginfo(s, i, c, p, v, sp) 296#define print_illegal_instruction_siginfo(s, i, c, p, v, sp)
227#endif /* DEBUG */ 297#endif /* DEBUG */
228 298
229 299
230/* signal handler switching to a pagefault context */ 
231static void 300static void
232mem_access_handler(int sig, siginfo_t *info, void *ctx) 301handle_signal(int sig, siginfo_t *info, void *ctx)
233{ 302{
 303 sigfunc_t *f;
234 ucontext_t *ucp = ctx; 304 ucontext_t *ucp = ctx;
235 struct lwp *l; 305 struct lwp *l;
236 struct pcb *pcb; 306 struct pcb *pcb;
237 vaddr_t va, sp, pc, fp; 307 vaddr_t va, sp, pc, fp;
238 int from_userland; 308 int from_userland;
239 309
240 assert((info->si_signo == SIGSEGV) || (info->si_signo == SIGBUS)); 310 if (sig == SIGBUS || sig == SIGSEGV || sig == SIGILL) {
 311 if (info->si_code == SI_NOINFO)
 312 panic("received signal %d with no info",
 313 info->si_signo);
 314 }
241 315
242 if (info->si_code == SI_NOINFO) 316 f = sig_funcs[sig];
243 panic("received signal %d with no info", 317 KASSERT(f);
244 info->si_signo); 
245 318
246 l = curlwp; 319 l = curlwp; KASSERT(l);
247 pcb = lwp_getpcb(l); 320 pcb = lwp_getpcb(l); KASSERT(pcb);
248 321
249 /* get address of faulted memory access and make it page aligned */ 322 /* get address of possible faulted memory access and page aligne it */
250 va = (vaddr_t) info->si_addr; 323 va = (vaddr_t) info->si_addr;
251 va = trunc_page(va); 324 va = trunc_page(va);
252 325
253 /* get PC address of faulted memory instruction */ 326 /* get PC address of possibly faulted instruction */
254 pc = md_get_pc(ctx); 327 pc = md_get_pc(ctx);
255 328
256 /* setup for pagefault context */ 329 /* nest it on the stack */
257 sp = md_get_sp(ctx); 330 sp = md_get_sp(ctx);
258 331
259 print_mem_access_siginfo(sig, info, ctx, pc, va, sp); 332 if (sig == SIGBUS || sig == SIGSEGV)
 333 print_mem_access_siginfo(sig, info, ctx, pc, va, sp);
 334 if (sig == SIGILL)
 335 print_illegal_instruction_siginfo(sig, info, ctx, pc, va, sp);
260 336
261 /* if we're running on a stack of our own, use the system stack */ 337 /* if we're running on a stack of our own, use the system stack */
262 from_userland = 0; 338 from_userland = 0;
263 if ((sp < (vaddr_t) pcb->sys_stack) || (sp > (vaddr_t) pcb->sys_stack_top)) { 339 if ((sp < (vaddr_t) pcb->sys_stack) ||
 340 (sp > (vaddr_t) pcb->sys_stack_top)) {
264 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); 341 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t);
265 fp = (vaddr_t) &pcb->pcb_userret_ucp; 342 fp = (vaddr_t) &pcb->pcb_userret_ucp;
266 if (pc < kmem_user_end) 343 if (pc < kmem_user_end)
267 from_userland = 1; 344 from_userland = 1;
268 } else { 345 } else {
269 /* stack grows down */ 346 /* stack grows down */
270 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ 347 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */
271 sp = fp - sizeof(register_t); /* slack */ 348 sp = fp - sizeof(register_t); /* slack */
272 349
273 /* sanity check before copying */ 350 /* sanity check before copying */
274 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) 351 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack)
275 panic("%s: out of system stack", __func__); 352 panic("%s: out of system stack", __func__);
276 } 353 }
277 354
278 memcpy((void *) fp, ucp, sizeof(ucontext_t)); 355 memcpy((void *) fp, ucp, sizeof(ucontext_t));
 356 memcpy(&jump_ucp, ucp, sizeof(ucontext_t));
279 357
280 /* create context for pagefault */ 358 /* create context */
281 pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; 359 jump_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack;
282 pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; 360 jump_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack;
283 pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */ 361 jump_ucp.uc_link = (void *) fp; /* link to old frame on stack */
284 362
285 pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; 363 thunk_sigemptyset(&jump_ucp.uc_sigmask);
286 thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) pagefault, 364 jump_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
 365 thunk_makecontext(&jump_ucp,
 366 (void (*)(void)) f,
287 3, (void *) from_userland, (void *) pc, (void *) va); 367 3, (void *) from_userland, (void *) pc, (void *) va);
288 368
289 /* switch to the new pagefault entry on return from signal */ 369 /* switch to the new context on return from signal */
290 memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); 370 thunk_setcontext(&jump_ucp);
 371// memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t));
291} 372}
292 373
293 374
294/* signal handler switching to a illegal instruction context */ 375void
295static void 376signal_intr_establish(int sig, sigfunc_t f)
296illegal_instruction_handler(int sig, siginfo_t *info, void *ctx) 
297{ 377{
298 ucontext_t *ucp = ctx; 378 static struct sigaction sa;
299 struct lwp *l; 
300 struct pcb *pcb; 
301 vaddr_t sp, pc, fp; 
302 int from_userland; 
303 
304 assert(info->si_signo == SIGILL); 
305 
306 l = curlwp; 
307 pcb = lwp_getpcb(l); 
308 
309 /* get PC address of faulted instruction */ 
310 pc = md_get_pc(ctx); 
311 
312 /* setup for illegal_instruction context */ 
313 sp = md_get_sp(ctx); 
314 
315 print_illegal_instruction_siginfo(sig, info, ctx, pc, 0, sp); 
316 
317 /* if we're running on a stack of our own, use the system stack */ 
318 from_userland = 0; 
319 if ((sp < (vaddr_t) pcb->sys_stack) || 
320 (sp > (vaddr_t) pcb->sys_stack_top)) { 
321 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); 
322 fp = (vaddr_t) &pcb->pcb_userret_ucp; 
323 
324 KASSERT(pc < kmem_user_end); 
325 from_userland = 1; 
326 } else { 
327 panic("illegal instruction inside kernel?"); 
328#if 0 
329 /* stack grows down */ 
330 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ 
331 sp = fp - sizeof(register_t); /* slack */ 
332 
333 /* sanity check before copying */ 
334 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) 
335 panic("%s: out of system stack", __func__); 
336#endif 
337 } 
338 
339 memcpy((void *) fp, ucp, sizeof(ucontext_t)); 
340 379
341 /* create context for illegal instruction */ 380 sig_funcs[sig] = f;
342 pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; 
343 pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; 
344 pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */ 
345 
346 pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; 
347 thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) illegal_instruction, 
348 1, (void *) from_userland, NULL, NULL); 
349 381
350 /* switch to the new illegal instruction entry on return from signal */ 382 sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
351 memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); 383 sa.sa_sigaction = (void *) handle_signal;
 384 thunk_sigfillset(&sa.sa_mask);
 385 if (thunk_sigaction(sig, &sa, NULL) == -1)
 386 panic("couldn't register SIG%d handler: %d", sig,
 387 thunk_geterrno());
352} 388}
353 389
354 390
355/* 391/*
356 * Context for handing page faults from the sigsegv handler; check if its a 392 * Context for handing page faults from the sigsegv handler; check if its a
357 * pmap reference fault or let uvm handle it. 393 * pmap reference fault or let uvm handle it.
358 */ 394 */
359static void 395static void
360pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va) 396pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
361{ 397{
362 struct proc *p; 398 struct proc *p;
363 struct lwp *l; 399 struct lwp *l;
364 struct pcb *pcb; 400 struct pcb *pcb;
@@ -367,38 +403,37 @@ pagefault(vaddr_t from_userland, vaddr_t @@ -367,38 +403,37 @@ pagefault(vaddr_t from_userland, vaddr_t
367 vm_prot_t atype; 403 vm_prot_t atype;
368 void *onfault; 404 void *onfault;
369 int from_kernel, lwp_errno, error; 405 int from_kernel, lwp_errno, error;
370 ksiginfo_t ksi; 406 ksiginfo_t ksi;
371 407
372 l = curlwp; KASSERT(l); 408 l = curlwp; KASSERT(l);
373 pcb = lwp_getpcb(l); 409 pcb = lwp_getpcb(l);
374 p = l->l_proc; 410 p = l->l_proc;
375 vm = p->p_vmspace; 411 vm = p->p_vmspace;
376 412
377 lwp_errno = thunk_geterrno(); 413 lwp_errno = thunk_geterrno();
378 414
379 vm_map = &vm->vm_map; 415 vm_map = &vm->vm_map;
380 from_kernel = (pc >= kmem_k_start); 416 from_kernel = (pc >= kmem_k_start) && (!from_userland);
381 if (from_kernel && (va >= VM_MIN_KERNEL_ADDRESS)) 417 if (from_kernel && (va >= VM_MIN_KERNEL_ADDRESS))
382 vm_map = kernel_map; 418 vm_map = kernel_map;
383 419
384#if 0 420#if 0
385 thunk_printf("pagefault : pc %p, va %p\n", 421 thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb);
386 (void *) pc, (void *) va); 422 thunk_printf("\tpc %p, va %p\n", (void *) pc, (void *) va);
387#endif 423#endif
388 424
389 /* can pmap handle it? on its own? (r/m) emulation */ 425 /* can pmap handle it? on its own? (r/m) emulation */
390 if (pmap_fault(vm_map->pmap, va, &atype)) { 426 if (pmap_fault(vm_map->pmap, va, &atype)) {
391// thunk_printf("pagefault leave (pmap)\n"); 
392 /* no use doing anything else here */ 427 /* no use doing anything else here */
393 goto out_quick; 428 goto out_quick;
394 } 429 }
395 430
396 /* ask UVM */ 431 /* ask UVM */
397 thunk_printf_debug("pmap fault couldn't handle it! : " 432 thunk_printf_debug("pmap fault couldn't handle it! : "
398 "derived atype %d\n", atype); 433 "derived atype %d\n", atype);
399 434
400 onfault = pcb->pcb_onfault; 435 onfault = pcb->pcb_onfault;
401 pcb->pcb_onfault = NULL; 436 pcb->pcb_onfault = NULL;
402 error = uvm_fault(vm_map, va, atype); 437 error = uvm_fault(vm_map, va, atype);
403 pcb->pcb_onfault = onfault; 438 pcb->pcb_onfault = onfault;
404 439
@@ -406,47 +441,48 @@ pagefault(vaddr_t from_userland, vaddr_t @@ -406,47 +441,48 @@ pagefault(vaddr_t from_userland, vaddr_t
406 if (error == 0) 441 if (error == 0)
407 uvm_grow(l->l_proc, va); 442 uvm_grow(l->l_proc, va);
408 } 443 }
409 if (error == EACCES) 444 if (error == EACCES)
410 error = EFAULT; 445 error = EFAULT;
411 446
412 /* if uvm handled it, return */ 447 /* if uvm handled it, return */
413 if (error == 0) { 448 if (error == 0) {
414// thunk_printf("pagefault leave (uvm)\n"); 449// thunk_printf("pagefault leave (uvm)\n");
415 goto out; 450 goto out;
416 } 451 }
417 452
418 /* something got wrong */ 453 /* something got wrong */
419 thunk_printf("%s: uvm fault %d, pc %p, from_kernel %d\n", 454 thunk_printf("%s: uvm fault %d, pc %p, va %p, from_kernel %d\n",
420 __func__, error, (void *) pc, from_kernel); 455 __func__, error, (void *) pc, (void *) va, from_kernel);
421 456
422 /* check if its from copyin/copyout */ 457 /* check if its from copyin/copyout */
423 if (onfault) { 458 if (onfault) {
424 panic("%s: can't call onfault yet\n", __func__); 459 panic("%s: can't call onfault yet\n", __func__);
425 /* XXX implement me ? */ 460 /* XXX implement me ? */
426 /* jump to given onfault */ 461 /* jump to given onfault */
427 // tf = &kernel_tf; 462 // tf = &kernel_tf;
428 // memset(tf, 0, sizeof(struct trapframe)); 463 // memset(tf, 0, sizeof(struct trapframe));
429 // tf->tf_pc = onfault; 464 // tf->tf_pc = onfault;
430 // tf->tf_io[0] = (rv == EACCES) ? EFAULT : rv; 465 // tf->tf_io[0] = (rv == EACCES) ? EFAULT : rv;
431 goto out; 466 goto out;
432 } 467 }
433 468
434 if (from_kernel) 469 if (from_kernel)
435 panic("Unhandled page fault in kernel mode"); 470 panic("Unhandled page fault in kernel mode");
436 471
437 /* send signal */ 472 /* send signal */
438 thunk_printf("giving signal to userland\n"); 473 thunk_printf("giving signal to userland\n");
439 474
 475 KASSERT(from_userland);
440 KSI_INIT_TRAP(&ksi); 476 KSI_INIT_TRAP(&ksi);
441 ksi.ksi_signo = SIGSEGV; 477 ksi.ksi_signo = SIGSEGV;
442 ksi.ksi_trap = 0; /* XXX */ 478 ksi.ksi_trap = 0; /* XXX */
443 ksi.ksi_code = (error == EPERM) ? SEGV_ACCERR : SEGV_MAPERR; 479 ksi.ksi_code = (error == EPERM) ? SEGV_ACCERR : SEGV_MAPERR;
444 ksi.ksi_addr = (void *) va; 480 ksi.ksi_addr = (void *) va;
445 481
446 if (error == ENOMEM) { 482 if (error == ENOMEM) {
447 printf("UVM: pid %d.%d (%s), uid %d killed: " 483 printf("UVM: pid %d.%d (%s), uid %d killed: "
448 "out of swap\n", 484 "out of swap\n",
449 p->p_pid, l->l_lid, p->p_comm, 485 p->p_pid, l->l_lid, p->p_comm,
450 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); 486 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1);
451 ksi.ksi_signo = SIGKILL; 487 ksi.ksi_signo = SIGKILL;
452 } 488 }
@@ -458,51 +494,123 @@ pagefault(vaddr_t from_userland, vaddr_t @@ -458,51 +494,123 @@ pagefault(vaddr_t from_userland, vaddr_t
458#endif 494#endif
459 495
460// thunk_printf("pagefault leave\n"); 496// thunk_printf("pagefault leave\n");
461out: 497out:
462 if (from_userland) 498 if (from_userland)
463 userret(l); 499 userret(l);
464out_quick: 500out_quick:
465 thunk_seterrno(lwp_errno); 501 thunk_seterrno(lwp_errno);
466 pcb->pcb_errno = lwp_errno; 502 pcb->pcb_errno = lwp_errno;
467} 503}
468 504
469 505
470/* 506/*
471 * Context for handing illegal instruction from the sigill handler 507 * handle an illegal instruction.
 508 *
 509 * arguments 'pc' and 'va' are ignored here
472 */ 510 */
473static void 511static void
474illegal_instruction(vaddr_t from_userland) 512illegal_instruction(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
475{ 513{
476 struct lwp *l = curlwp; 514 struct lwp *l = curlwp;
477 struct pcb *pcb = lwp_getpcb(l); 515 struct pcb *pcb = lwp_getpcb(l);
478 ucontext_t *ucp = &pcb->pcb_userret_ucp; 516 ucontext_t *ucp = &pcb->pcb_userret_ucp;
479 ksiginfo_t ksi; 517 ksiginfo_t ksi;
480 518
481// thunk_printf("illegal instruction\n"); 519// thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb);
 520
 521 KASSERT(from_userland);
 522
482 /* if its a syscall ... */ 523 /* if its a syscall ... */
483 if (md_syscall_check_opcode(ucp)) { 524 if (md_syscall_check_opcode(ucp)) {
484 syscall(); 525 syscall();
485// thunk_printf("illegal instruction leave\n"); 
486 KASSERT(from_userland); 
487 userret(l); 526 userret(l);
488 return; 527 return;
489 } 528 }
490 529
491 thunk_printf("%s: giving SIGILL (TRAP)\n", __func__); 530 thunk_printf("%s: giving SIGILL (TRAP)\n", __func__);
492 531
 532 KASSERT(from_userland);
493 KSI_INIT_TRAP(&ksi); 533 KSI_INIT_TRAP(&ksi);
494 ksi.ksi_signo = SIGILL; 534 ksi.ksi_signo = SIGILL;
495 ksi.ksi_trap = 0; /* XXX */ 535 ksi.ksi_trap = 0; /* XXX */
496 ksi.ksi_errno = 0; // info->si_errno; 536 ksi.ksi_errno = 0; // info->si_errno;
497 ksi.ksi_code = 0; // info->si_code; 537 ksi.ksi_code = 0; // info->si_code;
498 ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */ 538 ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */
499 539
500#if 0 540#if 0
501 p->p_emul->e_trapsignal(l, &ksi); 541 p->p_emul->e_trapsignal(l, &ksi);
502#else 542#else
503 trapsignal(l, &ksi); 543 trapsignal(l, &ksi);
504#endif 544#endif
505 KASSERT(from_userland); 
506 userret(l); 545 userret(l);
507} 546}
508 547
 548
 549/*
 550 * handle alarm, a clock ticker.
 551 *
 552 * arguments 'pc' and 'va' are ignored here
 553 */
 554static void
 555alarm(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
 556{
 557 struct lwp *l = curlwp;
 558 struct pcb *pcb = lwp_getpcb(l); KASSERT(pcb);
 559
 560 if (!clock_running)
 561 return;
 562// thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb);
 563
 564 softint_schedule(alrm_ih);
 565
 566 KASSERT(l == curlwp);
 567 if (from_userland)
 568 userret(l);
 569}
 570
 571
 572/*
 573 * handle sigio, a mux for all io operations.
 574 *
 575 * arguments 'pc' and 'va' are ignored here
 576 */
 577static void
 578sigio(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
 579{
 580 struct lwp *l = curlwp;
 581 struct pcb *pcb = lwp_getpcb(l); KASSERT(pcb);
 582 struct intr_handler *sih;
 583 unsigned int n;
 584
 585// thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb);
 586 for (n = 0; n < SIGIO_MAX_HANDLERS; n++) {
 587 sih = &sigio_intr_handler[n];
 588 if (sih->func)
 589 sih->func(sih->arg);
 590 }
 591
 592 KASSERT(l == curlwp);
 593 if (from_userland)
 594 userret(l); /* or ast? */
 595}
 596
 597
 598/* sigio register function */
 599void *
 600sigio_intr_establish(int (*func)(void *), void *arg)
 601{
 602 struct intr_handler *sih;
 603 unsigned int n;
 604
 605 for (n = 0; n < SIGIO_MAX_HANDLERS; n++) {
 606 sih = &sigio_intr_handler[n];
 607 if (sih->func == NULL) {
 608 sih->func = func;
 609 sih->arg = arg;
 610 return sih;
 611 }
 612 }
 613
 614 panic("increase SIGIO_MAX_HANDLERS");
 615}
 616