Tue Jan 17 19:46:55 2012 UTC ()
Clean up userret/ast handling. Now called ONLY when its 100% clear that it is
returning to userland.


(reinoud)
diff -r1.57 -r1.58 src/sys/arch/usermode/usermode/trap.c

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

--- src/sys/arch/usermode/usermode/trap.c 2012/01/14 21:45:28 1.57
+++ src/sys/arch/usermode/usermode/trap.c 2012/01/17 19:46:55 1.58
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: trap.c,v 1.57 2012/01/14 21:45:28 reinoud Exp $ */ 1/* $NetBSD: trap.c,v 1.58 2012/01/17 19:46:55 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,57 +17,56 @@ @@ -17,57 +17,56 @@
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.57 2012/01/14 21:45:28 reinoud Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.58 2012/01/17 19:46:55 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 49
50/* forwards and externals */ 50/* forwards and externals */
51void setup_signal_handlers(void); 51void setup_signal_handlers(void);
52void stop_all_signal_handlers(void); 52void stop_all_signal_handlers(void);
53void userret(struct lwp *l); 
54 53
55static void mem_access_handler(int sig, siginfo_t *info, void *ctx); 54static void mem_access_handler(int sig, siginfo_t *info, void *ctx);
56static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx); 55static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx);
57extern int errno; 56extern int errno;
58 57
59static void pagefault(vaddr_t pc, vaddr_t va); 58static void pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va);
60static void illegal_instruction(void); 59static void illegal_instruction(vaddr_t from_userland);
61 60
62bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype); 61bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype);
63 62
64static stack_t sigstk; 63static stack_t sigstk;
65 64
66int astpending; 65int astpending;
67 66
68void 67void
69startlwp(void *arg) 68startlwp(void *arg)
70{ 69{
71 /* nothing here */ 70 /* nothing here */
72} 71}
73 72
@@ -110,34 +109,62 @@ setup_signal_handlers(void) @@ -110,34 +109,62 @@ setup_signal_handlers(void)
110 109
111 110
112void 111void
113stop_all_signal_handlers(void) 112stop_all_signal_handlers(void)
114{ 113{
115 thunk_sigblock(SIGALRM); 114 thunk_sigblock(SIGALRM);
116 thunk_sigblock(SIGIO); 115 thunk_sigblock(SIGIO);
117 thunk_sigblock(SIGILL); 116 thunk_sigblock(SIGILL);
118 thunk_sigblock(SIGSEGV); 117 thunk_sigblock(SIGSEGV);
119 thunk_sigblock(SIGBUS); 118 thunk_sigblock(SIGBUS);
120} 119}
121 120
122 121
 122/* ast and userret */
 123void
 124userret(struct lwp *l)
 125{
 126 /* invoke MI userret code */
 127 mi_userret(l);
 128
 129 while (astpending) {
 130 astpending = 0;
 131
 132 curcpu()->ci_data.cpu_ntrap++;
 133#if 0
 134 /* profiling */
 135 if (l->l_pflag & LP_OWEUPC) {
 136 l->l_pflag &= ~LP_OWEUPC;
 137 ADDUPROF(l);
 138 }
 139#endif
 140 /* allow a forced task switch */
 141 if (l->l_cpu->ci_want_resched)
 142 preempt();
 143
 144 mi_userret(l);
 145 }
 146}
 147
 148
123/* signal handler switching to a pagefault context */ 149/* signal handler switching to a pagefault context */
124static void 150static void
125mem_access_handler(int sig, siginfo_t *info, void *ctx) 151mem_access_handler(int sig, siginfo_t *info, void *ctx)
126{ 152{
127 ucontext_t *ucp = ctx; 153 ucontext_t *ucp = ctx;
128 struct lwp *l; 154 struct lwp *l;
129 struct pcb *pcb; 155 struct pcb *pcb;
130 vaddr_t va, sp, pc, fp; 156 vaddr_t va, sp, pc, fp;
 157 int from_userland;
131 158
132 assert((info->si_signo == SIGSEGV) || (info->si_signo == SIGBUS)); 159 assert((info->si_signo == SIGSEGV) || (info->si_signo == SIGBUS));
133 160
134 if (info->si_code == SI_NOINFO) 161 if (info->si_code == SI_NOINFO)
135 panic("received signal %d with no info", 162 panic("received signal %d with no info",
136 info->si_signo); 163 info->si_signo);
137 164
138#if 0 165#if 0
139 thunk_printf_debug("SIGSEGV or SIGBUS!\n"); 166 thunk_printf_debug("SIGSEGV or SIGBUS!\n");
140 thunk_printf_debug("\tsi_signo = %d\n", info->si_signo); 167 thunk_printf_debug("\tsi_signo = %d\n", info->si_signo);
141 thunk_printf_debug("\tsi_errno = %d\n", info->si_errno); 168 thunk_printf_debug("\tsi_errno = %d\n", info->si_errno);
142 thunk_printf_debug("\tsi_code = %d\n", info->si_code); 169 thunk_printf_debug("\tsi_code = %d\n", info->si_code);
143 if (info->si_code == SEGV_MAPERR) 170 if (info->si_code == SEGV_MAPERR)
@@ -166,106 +193,67 @@ mem_access_handler(int sig, siginfo_t *i @@ -166,106 +193,67 @@ mem_access_handler(int sig, siginfo_t *i
166 193
167 /* setup for pagefault context */ 194 /* setup for pagefault context */
168 sp = md_get_sp(ctx); 195 sp = md_get_sp(ctx);
169 196
170#if 0 197#if 0
171 printf("memaccess error, pc %p, va %p, " 198 printf("memaccess error, pc %p, va %p, "
172 "sys_stack %p, sp %p, stack top %p\n", 199 "sys_stack %p, sp %p, stack top %p\n",
173 (void *) pc, (void *) va, 200 (void *) pc, (void *) va,
174 (void *) pcb->sys_stack, (void *) sp, 201 (void *) pcb->sys_stack, (void *) sp,
175 (void *) pcb->sys_stack_top); 202 (void *) pcb->sys_stack_top);
176#endif 203#endif
177 204
178 /* if we're running on a stack of our own, use the system stack */ 205 /* if we're running on a stack of our own, use the system stack */
 206 from_userland = 0;
179 if ((sp < (vaddr_t) pcb->sys_stack) || (sp > (vaddr_t) pcb->sys_stack_top)) { 207 if ((sp < (vaddr_t) pcb->sys_stack) || (sp > (vaddr_t) pcb->sys_stack_top)) {
180 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); 208 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t);
181 fp = (vaddr_t) &pcb->pcb_userret_ucp; 209 fp = (vaddr_t) &pcb->pcb_userret_ucp;
 210 if (pc < kmem_user_end)
 211 from_userland = 1;
182 } else { 212 } else {
183 /* stack grows down */ 213 /* stack grows down */
184 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ 214 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */
185 sp = fp - sizeof(register_t); /* slack */ 215 sp = fp - sizeof(register_t); /* slack */
186 216
187 /* sanity check before copying */ 217 /* sanity check before copying */
188 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) 218 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack)
189 panic("%s: out of system stack", __func__); 219 panic("%s: out of system stack", __func__);
190 } 220 }
191 221
192 memcpy((void *) fp, ucp, sizeof(ucontext_t)); 222 memcpy((void *) fp, ucp, sizeof(ucontext_t));
193 223
194 /* create context for pagefault */ 224 /* create context for pagefault */
195 pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; 225 pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack;
196 pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; 226 pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack;
197 pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */ 227 pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */
198 228
199 pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; 229 pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU;
200 thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) pagefault, 230 thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) pagefault,
201 2, (void *) pc, (void *) va, NULL); 231 3, (void *) from_userland, (void *) pc, (void *) va);
202 232
203 /* switch to the new pagefault entry on return from signal */ 233 /* switch to the new pagefault entry on return from signal */
204 memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); 234 memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t));
205} 235}
206 236
207 237
208/* ast and userret */ 
209void 
210userret(struct lwp *l) 
211{ 
212 struct pcb *pcb; 
213 ucontext_t ucp, *nucp; 
214 vaddr_t pc; 
215  
216 KASSERT(l); 
217 
218 /* are we going back to userland? */ 
219 pcb = lwp_getpcb(l); 
220 KASSERT(pcb); 
221 
222 /* where are we going back to ? */ 
223 thunk_getcontext(&ucp); 
224 nucp = (ucontext_t *) ucp.uc_link; 
225 pc = md_get_pc(nucp); 
226 
227 if (pc >= kmem_k_start) 
228 return; 
229 
230 /* ok, going to userland, proceed! */ 
231 if (astpending) { 
232 astpending = 0; 
233 
234 curcpu()->ci_data.cpu_ntrap++; 
235#if 0 
236 /* profiling */ 
237 if (l->l_pflag & LP_OWEUPC) { 
238 l->l_pflag &= ~LP_OWEUPC; 
239 ADDUPROF(l); 
240 } 
241#endif 
242 /* allow a forced task switch */ 
243 if (l->l_cpu->ci_want_resched) 
244 preempt(); 
245 } 
246 
247 /* invoke MI userret code */ 
248 mi_userret(l); 
249} 
250 
251/* signal handler switching to a illegal instruction context */ 238/* signal handler switching to a illegal instruction context */
252static void 239static void
253illegal_instruction_handler(int sig, siginfo_t *info, void *ctx) 240illegal_instruction_handler(int sig, siginfo_t *info, void *ctx)
254{ 241{
255 ucontext_t *ucp = ctx; 242 ucontext_t *ucp = ctx;
256 struct lwp *l; 243 struct lwp *l;
257 struct pcb *pcb; 244 struct pcb *pcb;
258 vaddr_t sp, fp; 245 vaddr_t sp, pc, fp;
 246 int from_userland;
259 247
260 assert(info->si_signo == SIGILL); 248 assert(info->si_signo == SIGILL);
261#if 0 249#if 0
262 thunk_printf("SIGILL!\n"); 250 thunk_printf("SIGILL!\n");
263 thunk_printf("\tsi_signo = %d\n", info->si_signo); 251 thunk_printf("\tsi_signo = %d\n", info->si_signo);
264 thunk_printf("\tsi_errno = %d\n", info->si_errno); 252 thunk_printf("\tsi_errno = %d\n", info->si_errno);
265 thunk_printf("\tsi_code = %d\n", info->si_code); 253 thunk_printf("\tsi_code = %d\n", info->si_code);
266 if (info->si_code == ILL_ILLOPC) 254 if (info->si_code == ILL_ILLOPC)
267 thunk_printf("\t\tIllegal opcode"); 255 thunk_printf("\t\tIllegal opcode");
268 if (info->si_code == ILL_ILLOPN) 256 if (info->si_code == ILL_ILLOPN)
269 thunk_printf("\t\tIllegal operand"); 257 thunk_printf("\t\tIllegal operand");
270 if (info->si_code == ILL_ILLADR) 258 if (info->si_code == ILL_ILLADR)
271 thunk_printf("\t\tIllegal addressing mode"); 259 thunk_printf("\t\tIllegal addressing mode");
@@ -281,69 +269,76 @@ illegal_instruction_handler(int sig, sig @@ -281,69 +269,76 @@ illegal_instruction_handler(int sig, sig
281 thunk_printf("\t\tInternal stack error"); 269 thunk_printf("\t\tInternal stack error");
282 thunk_printf("\tsi_addr = %p\n", info->si_addr); 270 thunk_printf("\tsi_addr = %p\n", info->si_addr);
283 thunk_printf("\tsi_trap = %d\n", info->si_trap); 271 thunk_printf("\tsi_trap = %d\n", info->si_trap);
284 272
285 thunk_printf("%p : ", info->si_addr); 273 thunk_printf("%p : ", info->si_addr);
286 for (int i = 0; i < 10; i++) 274 for (int i = 0; i < 10; i++)
287 thunk_printf("%02x ", *((uint8_t *) info->si_addr + i)); 275 thunk_printf("%02x ", *((uint8_t *) info->si_addr + i));
288 thunk_printf("\n"); 276 thunk_printf("\n");
289#endif 277#endif
290 278
291 l = curlwp; 279 l = curlwp;
292 pcb = lwp_getpcb(l); 280 pcb = lwp_getpcb(l);
293 281
 282 /* get PC address of faulted instruction */
 283 pc = md_get_pc(ctx);
 284
294 /* setup for illegal_instruction context */ 285 /* setup for illegal_instruction context */
295 sp = md_get_sp(ctx); 286 sp = md_get_sp(ctx);
296 287
297 /* if we're running on a stack of our own, use the system stack */ 288 /* if we're running on a stack of our own, use the system stack */
 289 from_userland = 0;
298 if ((sp < (vaddr_t) pcb->sys_stack) || 290 if ((sp < (vaddr_t) pcb->sys_stack) ||
299 (sp > (vaddr_t) pcb->sys_stack_top)) { 291 (sp > (vaddr_t) pcb->sys_stack_top)) {
300 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); 292 sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t);
301 fp = (vaddr_t) &pcb->pcb_userret_ucp; 293 fp = (vaddr_t) &pcb->pcb_userret_ucp;
 294
 295 KASSERT(pc < kmem_user_end);
 296 from_userland = 1;
302 } else { 297 } else {
303 panic("illegal instruction inside kernel?"); 298 panic("illegal instruction inside kernel?");
304#if 0 299#if 0
305 /* stack grows down */ 300 /* stack grows down */
306 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ 301 fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */
307 sp = fp - sizeof(register_t); /* slack */ 302 sp = fp - sizeof(register_t); /* slack */
308 303
309 /* sanity check before copying */ 304 /* sanity check before copying */
310 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) 305 if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack)
311 panic("%s: out of system stack", __func__); 306 panic("%s: out of system stack", __func__);
312#endif 307#endif
313 } 308 }
314 309
315 memcpy((void *) fp, ucp, sizeof(ucontext_t)); 310 memcpy((void *) fp, ucp, sizeof(ucontext_t));
316 311
317 /* create context for illegal instruction */ 312 /* create context for illegal instruction */
318 pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; 313 pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack;
319 pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; 314 pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack;
320 pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */ 315 pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */
321 316
322 pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; 317 pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU;
323 thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) illegal_instruction, 318 thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) illegal_instruction,
324 0, NULL, NULL, NULL); 319 1, (void *) from_userland, NULL, NULL);
325 320
326 /* switch to the new illegal instruction entry on return from signal */ 321 /* switch to the new illegal instruction entry on return from signal */
327 memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); 322 memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t));
328} 323}
329 324
330 325
331/* 326/*
332 * Context for handing page faults from the sigsegv handler; check if its a 327 * Context for handing page faults from the sigsegv handler; check if its a
333 * pmap reference fault or let uvm handle it. 328 * pmap reference fault or let uvm handle it.
334 */ 329 */
335static void 330static void
336pagefault(vaddr_t pc, vaddr_t va) 331pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va)
337{ 332{
338 struct proc *p; 333 struct proc *p;
339 struct lwp *l; 334 struct lwp *l;
340 struct pcb *pcb; 335 struct pcb *pcb;
341 struct vmspace *vm; 336 struct vmspace *vm;
342 struct vm_map *vm_map; 337 struct vm_map *vm_map;
343 vm_prot_t atype; 338 vm_prot_t atype;
344 void *onfault; 339 void *onfault;
345 int from_kernel, lwp_errno, error; 340 int from_kernel, lwp_errno, error;
346 ksiginfo_t ksi; 341 ksiginfo_t ksi;
347 342
348 l = curlwp; KASSERT(l); 343 l = curlwp; KASSERT(l);
349 pcb = lwp_getpcb(l); 344 pcb = lwp_getpcb(l);
@@ -425,56 +420,59 @@ pagefault(vaddr_t pc, vaddr_t va) @@ -425,56 +420,59 @@ pagefault(vaddr_t pc, vaddr_t va)
425 p->p_pid, l->l_lid, p->p_comm, 420 p->p_pid, l->l_lid, p->p_comm,
426 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); 421 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1);
427 ksi.ksi_signo = SIGKILL; 422 ksi.ksi_signo = SIGKILL;
428 } 423 }
429 424
430#if 0 425#if 0
431 p->p_emul->e_trapsignal(l, &ksi); 426 p->p_emul->e_trapsignal(l, &ksi);
432#else 427#else
433 trapsignal(l, &ksi); 428 trapsignal(l, &ksi);
434#endif 429#endif
435 430
436// thunk_printf("pagefault leave\n"); 431// thunk_printf("pagefault leave\n");
437out: 432out:
438 userret(l); 433 if (from_userland)
 434 userret(l);
439out_quick: 435out_quick:
440 thunk_seterrno(lwp_errno); 436 thunk_seterrno(lwp_errno);
441 pcb->pcb_errno = lwp_errno; 437 pcb->pcb_errno = lwp_errno;
442} 438}
443 439
444/* 440/*
445 * Context for handing illegal instruction from the sigill handler 441 * Context for handing illegal instruction from the sigill handler
446 */ 442 */
447static void 443static void
448illegal_instruction(void) 444illegal_instruction(vaddr_t from_userland)
449{ 445{
450 struct lwp *l = curlwp; 446 struct lwp *l = curlwp;
451 struct pcb *pcb = lwp_getpcb(l); 447 struct pcb *pcb = lwp_getpcb(l);
452 ucontext_t *ucp = &pcb->pcb_userret_ucp; 448 ucontext_t *ucp = &pcb->pcb_userret_ucp;
453 ksiginfo_t ksi; 449 ksiginfo_t ksi;
454 450
455// thunk_printf("illegal instruction\n"); 451// thunk_printf("illegal instruction\n");
456 /* if its a syscall ... */ 452 /* if its a syscall ... */
457 if (md_syscall_check_opcode(ucp)) { 453 if (md_syscall_check_opcode(ucp)) {
458 syscall(); 454 syscall();
459// thunk_printf("illegal instruction leave\n"); 455// thunk_printf("illegal instruction leave\n");
 456 KASSERT(from_userland);
460 userret(l); 457 userret(l);
461 return; 458 return;
462 } 459 }
463 460
464 thunk_printf("%s: giving SIGILL (TRAP)\n", __func__); 461 thunk_printf("%s: giving SIGILL (TRAP)\n", __func__);
465 462
466 KSI_INIT_TRAP(&ksi); 463 KSI_INIT_TRAP(&ksi);
467 ksi.ksi_signo = SIGILL; 464 ksi.ksi_signo = SIGILL;
468 ksi.ksi_trap = 0; /* XXX */ 465 ksi.ksi_trap = 0; /* XXX */
469 ksi.ksi_errno = 0; // info->si_errno; 466 ksi.ksi_errno = 0; // info->si_errno;
470 ksi.ksi_code = 0; // info->si_code; 467 ksi.ksi_code = 0; // info->si_code;
471 ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */ 468 ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */
472 469
473#if 0 470#if 0
474 p->p_emul->e_trapsignal(l, &ksi); 471 p->p_emul->e_trapsignal(l, &ksi);
475#else 472#else
476 trapsignal(l, &ksi); 473 trapsignal(l, &ksi);
477#endif 474#endif
 475 KASSERT(from_userland);
478 userret(l); 476 userret(l);
479} 477}
480 478