trap.c revision 1.54.8.1 1 /* $NetBSD: trap.c,v 1.54.8.1 2008/05/18 12:32:07 yamt Exp $ */
2
3 /*-
4 * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matthew Fredette.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /* $OpenBSD: trap.c,v 1.30 2001/09/19 20:50:56 mickey Exp $ */
33
34 /*
35 * Copyright (c) 1998-2000 Michael Shalayeff
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Michael Shalayeff.
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.54.8.1 2008/05/18 12:32:07 yamt Exp $");
66
67 /* #define INTRDEBUG */
68 /* #define TRAPDEBUG */
69 /* #define USERTRACE */
70
71 #include "opt_kgdb.h"
72 #include "opt_ptrace.h"
73
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/kernel.h>
77 #include <sys/syscall.h>
78 #include <sys/mutex.h>
79 #include <sys/ktrace.h>
80 #include <sys/proc.h>
81 #include <sys/signalvar.h>
82 #include <sys/user.h>
83 #include <sys/acct.h>
84 #include <sys/signal.h>
85 #include <sys/device.h>
86 #include <sys/pool.h>
87 #include <sys/userret.h>
88
89 #include <net/netisr.h>
90
91 #ifdef KGDB
92 #include <sys/kgdb.h>
93 #endif
94
95 #include <uvm/uvm.h>
96
97 #include <machine/iomod.h>
98 #include <machine/cpufunc.h>
99 #include <machine/reg.h>
100 #include <machine/autoconf.h>
101
102 #include <machine/db_machdep.h>
103
104 #include <hppa/hppa/machdep.h>
105
106 #include <ddb/db_output.h>
107 #include <ddb/db_interface.h>
108
109 #ifdef PTRACE
110 void ss_clear_breakpoints(struct lwp *l);
111 int ss_put_value(struct lwp *, vaddr_t, u_int);
112 int ss_get_value(struct lwp *, vaddr_t, u_int *);
113 #endif
114
115 /* single-step breakpoint */
116 #define SSBREAKPOINT (HPPA_BREAK_KERNEL | (HPPA_BREAK_SS << 13))
117
118 #if defined(DEBUG) || defined(DIAGNOSTIC)
119 /*
120 * 0x6fc1000 is a stwm r1, d(sr0, sp), which is the last
121 * instruction in the function prologue that gcc -O0 uses.
122 * When we have this instruction we know the relationship
123 * between the stack pointer and the gcc -O0 frame pointer
124 * (in r3, loaded with the initial sp) for the body of a
125 * function.
126 *
127 * If the given instruction is a stwm r1, d(sr0, sp) where
128 * d > 0, we evaluate to d, else we evaluate to zero.
129 */
130 #define STWM_R1_D_SR0_SP(inst) \
131 (((inst) & 0xffffc001) == 0x6fc10000 ? (((inst) & 0x00003ff) >> 1) : 0)
132 #endif /* DEBUG || DIAGNOSTIC */
133
134 const char *trap_type[] = {
135 "invalid",
136 "HPMC",
137 "power failure",
138 "recovery counter",
139 "external interrupt",
140 "LPMC",
141 "ITLB miss fault",
142 "instruction protection",
143 "Illegal instruction",
144 "break instruction",
145 "privileged operation",
146 "privileged register",
147 "overflow",
148 "conditional",
149 "assist exception",
150 "DTLB miss",
151 "ITLB non-access miss",
152 "DTLB non-access miss",
153 "data protection/rights/alignment",
154 "data break",
155 "TLB dirty",
156 "page reference",
157 "assist emulation",
158 "higher-priv transfer",
159 "lower-priv transfer",
160 "taken branch",
161 "data access rights",
162 "data protection",
163 "unaligned data ref",
164 };
165 int trap_types = sizeof(trap_type)/sizeof(trap_type[0]);
166
167 uint8_t fpopmap[] = {
168 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 };
177
178 volatile int astpending;
179
180 void pmap_hptdump(void);
181 void syscall(struct trapframe *, int *);
182
183 #if defined(DEBUG)
184 struct trapframe *sanity_frame;
185 struct lwp *sanity_lwp;
186 int sanity_checked = 0;
187 void frame_sanity_check(int, int, struct trapframe *, struct lwp *);
188 #endif
189
190
191 #ifdef USERTRACE
192 /*
193 * USERTRACE is a crude facility that traces the PC of
194 * a single user process. This tracing is normally
195 * activated by the dispatching of a certain syscall
196 * with certain arguments - see the activation code in
197 * syscall().
198 */
199 static void user_backtrace(struct trapframe *, struct lwp *, int);
200 static void user_backtrace_raw(u_int, u_int);
201
202 u_int rctr_next_iioq;
203 #endif
204
205 static inline void
206 userret(struct lwp *l, register_t pc, u_quad_t oticks)
207 {
208 struct proc *p = l->l_proc;
209
210 if (curcpu()->ci_want_resched) {
211 preempt();
212 }
213
214 mi_userret(l);
215
216 /*
217 * If profiling, charge recent system time to the trapped pc.
218 */
219 if (p->p_stflag & PST_PROFIL) {
220 extern int psratio;
221
222 addupc_task(l, pc, (int)(p->p_sticks - oticks) * psratio);
223 }
224 }
225
226 /*
227 * This handles some messy kernel debugger details.
228 * It dispatches into either kgdb or DDB, and knows
229 * about some special things to do, like skipping over
230 * break instructions and how to really set up for
231 * a single-step.
232 */
233 #if defined(KGDB) || defined(DDB)
234 static int
235 trap_kdebug(int type, int code, struct trapframe *frame)
236 {
237 int handled;
238 u_int tf_iioq_head_old;
239 u_int tf_iioq_tail_old;
240
241 for(;;) {
242
243 /* This trap has not been handled. */
244 handled = 0;
245
246 /* Remember the instruction offset queue. */
247 tf_iioq_head_old = frame->tf_iioq_head;
248 tf_iioq_tail_old = frame->tf_iioq_tail;
249
250 #ifdef KGDB
251 /* Let KGDB handle it (if connected) */
252 if (!handled)
253 handled = kgdb_trap(type, frame);
254 #endif
255 #ifdef DDB
256 /* Let DDB handle it. */
257 if (!handled)
258 handled = kdb_trap(type, code, frame);
259 #endif
260
261 /* If this trap wasn't handled, return now. */
262 if (!handled)
263 return(0);
264
265 /*
266 * If the instruction offset queue head changed,
267 * but the offset queue tail didn't, assume that
268 * the user wants to jump to the head offset, and
269 * adjust the tail accordingly. This should fix
270 * the kgdb `jump' command, and can help DDB users
271 * who `set' the offset head but forget the tail.
272 */
273 if (frame->tf_iioq_head != tf_iioq_head_old &&
274 frame->tf_iioq_tail == tf_iioq_tail_old)
275 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
276
277 /*
278 * This is some single-stepping support.
279 * If we're trying to step through a nullified
280 * instruction, just advance by hand and trap
281 * again. Otherwise, load the recovery counter
282 * with zero.
283 */
284 if (frame->tf_ipsw & PSW_R) {
285 #ifdef TRAPDEBUG
286 printf("(single stepping at head 0x%x tail 0x%x)\n",
287 frame->tf_iioq_head, frame->tf_iioq_tail);
288 #endif
289 if (frame->tf_ipsw & PSW_N) {
290 #ifdef TRAPDEBUG
291 printf("(single stepping past nullified)\n");
292 #endif
293
294 /* Advance the program counter. */
295 frame->tf_iioq_head = frame->tf_iioq_tail;
296 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
297
298 /* Clear flags. */
299 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
300
301 /* Simulate another trap. */
302 type = T_RECOVERY;
303 continue;
304 }
305 frame->tf_rctr = 0;
306 }
307
308 /* We handled this trap. */
309 return (1);
310 }
311 /* NOTREACHED */
312 }
313 #else /* !KGDB && !DDB */
314 #define trap_kdebug(t, c, f) (0)
315 #endif /* !KGDB && !DDB */
316
317 #if defined(DEBUG) || defined(USERTRACE)
318 /*
319 * These functions give a crude usermode backtrace. They
320 * really only work when code has been compiled without
321 * optimization, as they assume a certain function prologue
322 * sets up a frame pointer and stores the return pointer
323 * and arguments in it.
324 */
325 static void
326 user_backtrace_raw(u_int pc, u_int fp)
327 {
328 int frame_number;
329 int arg_number;
330
331 for (frame_number = 0;
332 frame_number < 100 && pc > HPPA_PC_PRIV_MASK && fp;
333 frame_number++) {
334
335 printf("%3d: pc=%08x%s fp=0x%08x", frame_number,
336 pc & ~HPPA_PC_PRIV_MASK, USERMODE(pc) ? " " : "**", fp);
337 for(arg_number = 0; arg_number < 4; arg_number++)
338 printf(" arg%d=0x%08x", arg_number,
339 (int) fuword(HPPA_FRAME_CARG(arg_number, fp)));
340 printf("\n");
341 pc = fuword(((register_t *) fp) - 5); /* fetch rp */
342 if (pc == -1) {
343 printf(" fuword for pc failed\n");
344 break;
345 }
346 fp = fuword(((register_t *) fp) + 0); /* fetch previous fp */
347 if (fp == -1) {
348 printf(" fuword for fp failed\n");
349 break;
350 }
351 }
352 printf(" backtrace stopped with pc %08x fp 0x%08x\n", pc, fp);
353 }
354
355 static void
356 user_backtrace(struct trapframe *tf, struct lwp *l, int type)
357 {
358 struct proc *p = l->l_proc;
359 u_int pc, fp, inst;
360
361 /*
362 * Display any trap type that we have.
363 */
364 if (type >= 0)
365 printf("pid %d (%s) trap #%d\n",
366 p->p_pid, p->p_comm, type & ~T_USER);
367
368 /*
369 * Assuming that the frame pointer in r3 is valid,
370 * dump out a stack trace.
371 */
372 fp = tf->tf_r3;
373 printf("pid %d (%s) backtrace, starting with fp 0x%08x\n",
374 p->p_pid, p->p_comm, fp);
375 user_backtrace_raw(tf->tf_iioq_head, fp);
376
377 /*
378 * In case the frame pointer in r3 is not valid,
379 * assuming the stack pointer is valid and the
380 * faulting function is a non-leaf, if we can
381 * find its prologue we can recover its frame
382 * pointer.
383 */
384 pc = tf->tf_iioq_head;
385 fp = tf->tf_sp - HPPA_FRAME_SIZE;
386 printf("pid %d (%s) backtrace, starting with sp 0x%08x pc 0x%08x\n",
387 p->p_pid, p->p_comm, tf->tf_sp, pc);
388 for (pc &= ~HPPA_PC_PRIV_MASK; pc > 0; pc -= sizeof(inst)) {
389 inst = fuword((register_t *) pc);
390 if (inst == -1) {
391 printf(" fuword for inst at pc %08x failed\n", pc);
392 break;
393 }
394 /* Check for the prologue instruction that sets sp. */
395 if (STWM_R1_D_SR0_SP(inst)) {
396 fp = tf->tf_sp - STWM_R1_D_SR0_SP(inst);
397 printf(" sp from fp at pc %08x: %08x\n", pc, inst);
398 break;
399 }
400 }
401 user_backtrace_raw(tf->tf_iioq_head, fp);
402 }
403 #endif /* DEBUG || USERTRACE */
404
405 #ifdef DEBUG
406 /*
407 * This sanity-checks a trapframe. It is full of various
408 * assumptions about what a healthy CPU state should be,
409 * with some documented elsewhere, some not.
410 */
411 void
412 frame_sanity_check(int where, int type, struct trapframe *tf, struct lwp *l)
413 {
414 extern int kernel_text;
415 extern int etext;
416 extern register_t kpsw;
417 extern vaddr_t hpt_base;
418 extern vsize_t hpt_mask;
419 #define SANITY(e) \
420 do { \
421 if (sanity_frame == NULL && !(e)) { \
422 sanity_frame = tf; \
423 sanity_lwp = l; \
424 sanity_checked = __LINE__; \
425 } \
426 } while (/* CONSTCOND */ 0)
427
428 SANITY((tf->tf_ipsw & kpsw) == kpsw);
429 SANITY(tf->tf_hptm == hpt_mask && tf->tf_vtop == hpt_base);
430 SANITY((kpsw & PSW_I) == 0 || tf->tf_eiem != 0);
431 if (tf->tf_iisq_head == HPPA_SID_KERNEL) {
432 vaddr_t minsp, maxsp;
433
434 /*
435 * If the trap happened in the gateway
436 * page, we take the easy way out and
437 * assume that the trapframe is okay.
438 */
439 if ((tf->tf_iioq_head & ~PAGE_MASK) == SYSCALLGATE)
440 goto out;
441
442 SANITY(!USERMODE(tf->tf_iioq_head));
443 SANITY(!USERMODE(tf->tf_iioq_tail));
444
445 /*
446 * Don't check the instruction queues or stack on interrupts
447 * as we could be be in the sti code (outside normal kernel
448 * text) or switching LWPs (curlwp and sp are not in sync)
449 */
450 if ((type & ~T_USER) == T_INTERRUPT)
451 goto out;
452
453 SANITY(tf->tf_iioq_head >= (u_int) &kernel_text);
454 SANITY(tf->tf_iioq_head < (u_int) &etext);
455 SANITY(tf->tf_iioq_tail >= (u_int) &kernel_text);
456 SANITY(tf->tf_iioq_tail < (u_int) &etext);
457
458 #ifdef HPPA_REDZONE
459 maxsp = (u_int)(l->l_addr) + HPPA_REDZONE;
460 #else
461 maxsp = (u_int)(l->l_addr) + USPACE;
462 #endif
463 minsp = (u_int)(l->l_addr) + PAGE_SIZE;
464
465 SANITY(l != NULL || (tf->tf_sp >= minsp && tf->tf_sp < maxsp));
466 } else {
467 SANITY(USERMODE(tf->tf_iioq_head));
468 SANITY(USERMODE(tf->tf_iioq_tail));
469 SANITY(l != NULL && tf->tf_cr30 == kvtop((void *)l->l_addr));
470 }
471 #undef SANITY
472 out:
473 if (sanity_frame == tf) {
474 printf("insanity: where 0x%x type 0x%x tf %p lwp %p line %d "
475 "sp 0x%x pc 0x%x\n",
476 where, type, sanity_frame, sanity_lwp, sanity_checked,
477 tf->tf_sp, tf->tf_iioq_head);
478 (void) trap_kdebug(T_IBREAK, 0, tf);
479 sanity_frame = NULL;
480 sanity_lwp = NULL;
481 sanity_checked = 0;
482 }
483 }
484 #endif /* DEBUG */
485
486 void
487 trap(int type, struct trapframe *frame)
488 {
489 struct lwp *l;
490 struct proc *p;
491 struct pcb *pcbp;
492 vaddr_t va;
493 struct vm_map *map;
494 struct vmspace *vm;
495 vm_prot_t vftype;
496 pa_space_t space;
497 ksiginfo_t ksi;
498 u_int opcode, onfault;
499 int ret;
500 const char *tts;
501 int type_raw;
502 #ifdef DIAGNOSTIC
503 extern int emergency_stack_start, emergency_stack_end;
504 #endif
505
506 type_raw = type & ~T_USER;
507 opcode = frame->tf_iir;
508 if (type_raw == T_ITLBMISS || type_raw == T_ITLBMISSNA ||
509 type_raw == T_IBREAK || type_raw == T_TAKENBR) {
510 va = frame->tf_iioq_head;
511 space = frame->tf_iisq_head;
512 vftype = VM_PROT_EXECUTE;
513 } else {
514 va = frame->tf_ior;
515 space = frame->tf_isr;
516 vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ;
517 }
518
519 l = curlwp;
520 p = l ? l->l_proc : NULL;
521 if ((type & T_USER) != 0)
522 LWP_CACHE_CREDS(l, p);
523
524 tts = (type & ~T_USER) > trap_types ? "reserved" :
525 trap_type[type & ~T_USER];
526
527 #ifdef DIAGNOSTIC
528 /*
529 * If we are on the emergency stack, then we either got
530 * a fault on the kernel stack, or we're just handling
531 * a trap for the machine check handler (which also
532 * runs on the emergency stack).
533 *
534 * We *very crudely* differentiate between the two cases
535 * by checking the faulting instruction: if it is the
536 * function prologue instruction that stores the old
537 * frame pointer and updates the stack pointer, we assume
538 * that we faulted on the kernel stack.
539 *
540 * In this case, not completing that instruction will
541 * probably confuse backtraces in kgdb/ddb. Completing
542 * it would be difficult, because we already faulted on
543 * that part of the stack, so instead we fix up the
544 * frame as if the function called has just returned.
545 * This has peculiar knowledge about what values are in
546 * what registers during the "normal gcc -g" prologue.
547 */
548 if (&type >= &emergency_stack_start &&
549 &type < &emergency_stack_end &&
550 type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) {
551 /* Restore the caller's frame pointer. */
552 frame->tf_r3 = frame->tf_r1;
553 /* Restore the caller's instruction offsets. */
554 frame->tf_iioq_head = frame->tf_rp;
555 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
556 goto dead_end;
557 }
558 #endif /* DIAGNOSTIC */
559
560 #ifdef DEBUG
561 frame_sanity_check(0xdead01, type, frame, l);
562 #endif /* DEBUG */
563
564 /* If this is a trap, not an interrupt, reenable interrupts. */
565 if (type_raw != T_INTERRUPT)
566 mtctl(frame->tf_eiem, CR_EIEM);
567
568 if (frame->tf_flags & TFF_LAST)
569 l->l_md.md_regs = frame;
570
571 #ifdef TRAPDEBUG
572 if (type_raw != T_INTERRUPT && type_raw != T_IBREAK)
573 printf("trap: %d, %s for %x:%x at %x:%x, fp=%p, rp=%x\n",
574 type, tts, space, (u_int)va, frame->tf_iisq_head,
575 frame->tf_iioq_head, frame, frame->tf_rp);
576 else if (type_raw == T_IBREAK)
577 printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",
578 break5(opcode), break13(opcode),
579 frame->tf_iisq_head, frame->tf_iioq_head, frame);
580
581 {
582 extern int etext;
583 if (frame < (struct trapframe *)&etext) {
584 printf("trap: bogus frame ptr %p\n", frame);
585 goto dead_end;
586 }
587 }
588 #endif
589 switch (type) {
590 case T_NONEXIST:
591 case T_NONEXIST|T_USER:
592 #if !defined(DDB) && !defined(KGDB)
593 /* we've got screwed up by the central scrutinizer */
594 panic ("trap: elvis has just left the building!");
595 break;
596 #else
597 goto dead_end;
598 #endif
599 case T_RECOVERY|T_USER:
600 #ifdef USERTRACE
601 for(;;) {
602 if (frame->tf_iioq_head != rctr_next_iioq)
603 printf("-%08x\nr %08x",
604 rctr_next_iioq - 4,
605 frame->tf_iioq_head);
606 rctr_next_iioq = frame->tf_iioq_head + 4;
607 if (frame->tf_ipsw & PSW_N) {
608 /* Advance the program counter. */
609 frame->tf_iioq_head = frame->tf_iioq_tail;
610 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
611 /* Clear flags. */
612 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
613 /* Simulate another trap. */
614 continue;
615 }
616 break;
617 }
618 frame->tf_rctr = 0;
619 break;
620 #endif /* USERTRACE */
621 case T_RECOVERY:
622 #if !defined(DDB) && !defined(KGDB)
623 /* XXX will implement later */
624 printf ("trap: handicapped");
625 break;
626 #else
627 goto dead_end;
628 #endif
629
630 case T_EMULATION | T_USER:
631 #ifdef FPEMUL
632 hppa_fpu_emulate(frame, l, opcode);
633 #else /* !FPEMUL */
634 /*
635 * We don't have FPU emulation, so signal the
636 * process with a SIGFPE.
637 */
638
639 KSI_INIT_TRAP(&ksi);
640 ksi.ksi_signo = SIGFPE;
641 ksi.ksi_code = SI_NOINFO;
642 ksi.ksi_trap = type;
643 ksi.ksi_addr = (void *)frame->tf_iioq_head;
644 trapsignal(l, &ksi);
645 #endif /* !FPEMUL */
646 break;
647
648 case T_DATALIGN:
649 if (l->l_addr->u_pcb.pcb_onfault) {
650 do_onfault:
651 pcbp = &l->l_addr->u_pcb;
652 frame->tf_iioq_tail = 4 +
653 (frame->tf_iioq_head =
654 pcbp->pcb_onfault);
655 pcbp->pcb_onfault = 0;
656 break;
657 }
658 /*FALLTHROUGH*/
659
660 #ifdef DIAGNOSTIC
661 /* these just can't happen ever */
662 case T_PRIV_OP:
663 case T_PRIV_REG:
664 /* these just can't make it to the trap() ever */
665 case T_HPMC:
666 case T_HPMC | T_USER:
667 case T_EMULATION:
668 case T_EXCEPTION:
669 #endif
670 case T_IBREAK:
671 case T_DBREAK:
672 dead_end:
673 if (type & T_USER) {
674 #ifdef DEBUG
675 user_backtrace(frame, l, type);
676 #endif
677 KSI_INIT_TRAP(&ksi);
678 ksi.ksi_signo = SIGILL;
679 ksi.ksi_code = ILL_ILLTRP;
680 ksi.ksi_trap = type;
681 ksi.ksi_addr = (void *)frame->tf_iioq_head;
682 trapsignal(l, &ksi);
683 break;
684 }
685 if (trap_kdebug(type, va, frame))
686 return;
687 else if (type == T_DATALIGN)
688 panic ("trap: %s at 0x%x", tts, (u_int) va);
689 else
690 panic ("trap: no debugger for \"%s\" (%d)", tts, type);
691 break;
692
693 case T_IBREAK | T_USER:
694 case T_DBREAK | T_USER:
695 KSI_INIT_TRAP(&ksi);
696 ksi.ksi_signo = SIGTRAP;
697 ksi.ksi_code = TRAP_TRACE;
698 ksi.ksi_trap = type_raw;
699 ksi.ksi_addr = (void *)frame->tf_iioq_head;
700 #ifdef PTRACE
701 ss_clear_breakpoints(l);
702 if (opcode == SSBREAKPOINT)
703 ksi.ksi_code = TRAP_BRKPT;
704 #endif
705 /* pass to user debugger */
706 trapsignal(l, &ksi);
707
708 break;
709
710 #ifdef PTRACE
711 case T_TAKENBR | T_USER:
712 ss_clear_breakpoints(l);
713
714 KSI_INIT_TRAP(&ksi);
715 ksi.ksi_signo = SIGTRAP;
716 ksi.ksi_code = TRAP_TRACE;
717 ksi.ksi_trap = type_raw;
718 ksi.ksi_addr = (void *)frame->tf_iioq_head;
719
720 /* pass to user debugger */
721 trapsignal(l, &ksi);
722 break;
723 #endif
724
725 case T_EXCEPTION | T_USER: { /* co-proc assist trap */
726 uint64_t *fpp;
727 uint32_t *pex, ex, inst;
728 int i;
729
730 hppa_fpu_flush(l);
731 fpp = l->l_addr->u_pcb.pcb_fpregs;
732 pex = (uint32_t *)&fpp[1];
733 for (i = 1; i < 8 && !*pex; i++, pex++)
734 ;
735 KASSERT(i < 8);
736 ex = *pex;
737 *pex = 0;
738
739 /* reset the trap flag, as if there was none */
740 fpp[0] &= ~(((uint64_t)HPPA_FPU_T) << 32);
741
742 /* emulate the instruction */
743 inst = ((uint32_t)fpopmap[ex >> 26] << 26) | (ex & 0x03ffffff);
744 hppa_fpu_emulate(frame, l, inst);
745 }
746 break;
747
748 case T_OVERFLOW | T_USER:
749 KSI_INIT_TRAP(&ksi);
750 ksi.ksi_signo = SIGFPE;
751 ksi.ksi_code = SI_NOINFO;
752 ksi.ksi_trap = type;
753 ksi.ksi_addr = (void *)va;
754 trapsignal(l, &ksi);
755 break;
756
757 case T_CONDITION | T_USER:
758 KSI_INIT_TRAP(&ksi);
759 ksi.ksi_signo = SIGFPE;
760 ksi.ksi_code = FPE_INTDIV;
761 ksi.ksi_trap = type;
762 ksi.ksi_addr = (void *)va;
763 trapsignal(l, &ksi);
764 break;
765
766 case T_ILLEGAL | T_USER:
767 #ifdef DEBUG
768 user_backtrace(frame, l, type);
769 #endif
770 KSI_INIT_TRAP(&ksi);
771 ksi.ksi_signo = SIGILL;
772 ksi.ksi_code = ILL_ILLOPC;
773 ksi.ksi_trap = type;
774 ksi.ksi_addr = (void *)va;
775 trapsignal(l, &ksi);
776 break;
777
778 case T_PRIV_OP | T_USER:
779 #ifdef DEBUG
780 user_backtrace(frame, l, type);
781 #endif
782 KSI_INIT_TRAP(&ksi);
783 ksi.ksi_signo = SIGILL;
784 ksi.ksi_code = ILL_PRVOPC;
785 ksi.ksi_trap = type;
786 ksi.ksi_addr = (void *)va;
787 trapsignal(l, &ksi);
788 break;
789
790 case T_PRIV_REG | T_USER:
791 #ifdef DEBUG
792 user_backtrace(frame, l, type);
793 #endif
794 KSI_INIT_TRAP(&ksi);
795 ksi.ksi_signo = SIGILL;
796 ksi.ksi_code = ILL_PRVREG;
797 ksi.ksi_trap = type;
798 ksi.ksi_addr = (void *)va;
799 trapsignal(l, &ksi);
800 break;
801
802 /* these should never got here */
803 case T_HIGHERPL | T_USER:
804 case T_LOWERPL | T_USER:
805 KSI_INIT_TRAP(&ksi);
806 ksi.ksi_signo = SIGSEGV;
807 ksi.ksi_code = SEGV_ACCERR;
808 ksi.ksi_trap = type;
809 ksi.ksi_addr = (void *)va;
810 trapsignal(l, &ksi);
811 break;
812
813 case T_IPROT | T_USER:
814 case T_DPROT | T_USER:
815 KSI_INIT_TRAP(&ksi);
816 ksi.ksi_signo = SIGSEGV;
817 ksi.ksi_code = SEGV_ACCERR;
818 ksi.ksi_trap = type;
819 ksi.ksi_addr = (void *)va;
820 trapsignal(l, &ksi);
821 break;
822
823 case T_DATACC: case T_USER | T_DATACC:
824 case T_ITLBMISS: case T_USER | T_ITLBMISS:
825 case T_DTLBMISS: case T_USER | T_DTLBMISS:
826 case T_ITLBMISSNA: case T_USER | T_ITLBMISSNA:
827 case T_DTLBMISSNA: case T_USER | T_DTLBMISSNA:
828 case T_TLB_DIRTY: case T_USER | T_TLB_DIRTY:
829 vm = p->p_vmspace;
830
831 if (!vm) {
832 #ifdef TRAPDEBUG
833 printf("trap: no vm, p=%p\n", p);
834 #endif
835 goto dead_end;
836 }
837
838 /*
839 * it could be a kernel map for exec_map faults
840 */
841 if (!(type & T_USER) && space == HPPA_SID_KERNEL)
842 map = kernel_map;
843 else
844 map = &vm->vm_map;
845
846 va = trunc_page(va);
847
848 if (map->pmap->pmap_space != space) {
849 #ifdef TRAPDEBUG
850 printf("trap: space mismatch %d != %d\n",
851 space, map->pmap->pmap_space);
852 #endif
853 /* actually dump the user, crap the kernel */
854 goto dead_end;
855 }
856
857 /* Never call uvm_fault in interrupt context. */
858 KASSERT(hppa_intr_depth == 0);
859
860 onfault = l->l_addr->u_pcb.pcb_onfault;
861 l->l_addr->u_pcb.pcb_onfault = 0;
862 ret = uvm_fault(map, va, vftype);
863 l->l_addr->u_pcb.pcb_onfault = onfault;
864
865 #ifdef TRAPDEBUG
866 printf("uvm_fault(%p, %x, %d)=%d\n",
867 map, (u_int)va, vftype, ret);
868 #endif
869
870 /*
871 * If this was a stack access we keep track of the maximum
872 * accessed stack size. Also, if uvm_fault gets a protection
873 * failure it is due to accessing the stack region outside
874 * the current limit and we need to reflect that as an access
875 * error.
876 */
877 if (map != kernel_map && va >= (vaddr_t)vm->vm_minsaddr) {
878 if (ret == 0)
879 uvm_grow(l->l_proc, va);
880 else if (ret == EACCES)
881 ret = EFAULT;
882 }
883
884 if (ret != 0) {
885 if (type & T_USER) {
886 #ifdef DEBUG
887 user_backtrace(frame, l, type);
888 #endif
889 KSI_INIT_TRAP(&ksi);
890 ksi.ksi_signo = SIGSEGV;
891 ksi.ksi_code = (ret == EACCES ?
892 SEGV_ACCERR : SEGV_MAPERR);
893 ksi.ksi_trap = type;
894 ksi.ksi_addr = (void *)va;
895 trapsignal(l, &ksi);
896 } else {
897 if (l->l_addr->u_pcb.pcb_onfault) {
898 goto do_onfault;
899 }
900 panic("trap: uvm_fault(%p, %lx, %d): %d",
901 map, va, vftype, ret);
902 }
903 }
904 break;
905
906 case T_DATALIGN | T_USER:
907 #ifdef DEBUG
908 user_backtrace(frame, l, type);
909 #endif
910 KSI_INIT_TRAP(&ksi);
911 ksi.ksi_signo = SIGBUS;
912 ksi.ksi_code = BUS_ADRALN;
913 ksi.ksi_trap = type;
914 ksi.ksi_addr = (void *)va;
915 trapsignal(l, &ksi);
916 break;
917
918 case T_INTERRUPT:
919 case T_INTERRUPT|T_USER:
920 hppa_intr(frame);
921 mtctl(frame->tf_eiem, CR_EIEM);
922 break;
923
924 case T_LOWERPL:
925 case T_DPROT:
926 case T_IPROT:
927 case T_OVERFLOW:
928 case T_CONDITION:
929 case T_ILLEGAL:
930 case T_HIGHERPL:
931 case T_TAKENBR:
932 case T_POWERFAIL:
933 case T_LPMC:
934 case T_PAGEREF:
935 case T_DATAPID: case T_DATAPID | T_USER:
936 if (0 /* T-chip */) {
937 break;
938 }
939 /* FALLTHROUGH to unimplemented */
940 default:
941 panic ("trap: unimplemented \'%s\' (%d)", tts, type);
942 }
943
944 if (type & T_USER)
945 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
946
947 #ifdef DEBUG
948 frame_sanity_check(0xdead02, type, frame, l);
949 if (frame->tf_flags & TFF_LAST && (curlwp->l_flag & LW_IDLE) == 0)
950 frame_sanity_check(0xdead03, type, curlwp->l_md.md_regs,
951 curlwp);
952 #endif /* DEBUG */
953 }
954
955 void
956 child_return(void *arg)
957 {
958 struct lwp *l = arg;
959
960 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
961 ktrsysret(SYS_fork, 0, 0);
962 #ifdef DEBUG
963 frame_sanity_check(0xdead04, 0, l->l_md.md_regs, l);
964 #endif /* DEBUG */
965 }
966
967 #ifdef PTRACE
968
969 #include <sys/ptrace.h>
970
971 int
972 ss_get_value(struct lwp *l, vaddr_t addr, u_int *value)
973 {
974 struct uio uio;
975 struct iovec iov;
976
977 iov.iov_base = (void *)value;
978 iov.iov_len = sizeof(u_int);
979 uio.uio_iov = &iov;
980 uio.uio_iovcnt = 1;
981 uio.uio_offset = (off_t)addr;
982 uio.uio_resid = sizeof(u_int);
983 uio.uio_rw = UIO_READ;
984 UIO_SETUP_SYSSPACE(&uio);
985
986 return (process_domem(curlwp, l, &uio));
987 }
988
989 int
990 ss_put_value(struct lwp *l, vaddr_t addr, u_int value)
991 {
992 struct uio uio;
993 struct iovec iov;
994
995 iov.iov_base = (void *)&value;
996 iov.iov_len = sizeof(u_int);
997 uio.uio_iov = &iov;
998 uio.uio_iovcnt = 1;
999 uio.uio_offset = (off_t)addr;
1000 uio.uio_resid = sizeof(u_int);
1001 uio.uio_rw = UIO_WRITE;
1002 UIO_SETUP_SYSSPACE(&uio);
1003
1004 return (process_domem(curlwp, l, &uio));
1005 }
1006
1007 void
1008 ss_clear_breakpoints(struct lwp *l)
1009 {
1010 /* Restore origional instructions. */
1011 if (l->l_md.md_bpva != 0) {
1012 ss_put_value(l, l->l_md.md_bpva, l->l_md.md_bpsave[0]);
1013 ss_put_value(l, l->l_md.md_bpva + 4, l->l_md.md_bpsave[1]);
1014 l->l_md.md_bpva = 0;
1015 }
1016 }
1017
1018
1019 int
1020 process_sstep(struct lwp *l, int sstep)
1021 {
1022 struct trapframe *tf = l->l_md.md_regs;
1023 int error;
1024
1025 ss_clear_breakpoints(l);
1026
1027 /* We're continuing... */
1028 /* Don't touch the syscall gateway page. */
1029 /* XXX head */
1030 if (sstep == 0 ||
1031 (tf->tf_iioq_tail & ~PAGE_MASK) == SYSCALLGATE) {
1032 tf->tf_ipsw &= ~PSW_T;
1033 return 0;
1034 }
1035
1036 l->l_md.md_bpva = tf->tf_iioq_tail & ~HPPA_PC_PRIV_MASK;
1037
1038 /*
1039 * Insert two breakpoint instructions; the first one might be
1040 * nullified. Of course we need to save two instruction
1041 * first.
1042 */
1043
1044 error = ss_get_value(l, l->l_md.md_bpva, &l->l_md.md_bpsave[0]);
1045 if (error)
1046 return (error);
1047 error = ss_get_value(l, l->l_md.md_bpva + 4, &l->l_md.md_bpsave[1]);
1048 if (error)
1049 return (error);
1050
1051 error = ss_put_value(l, l->l_md.md_bpva, SSBREAKPOINT);
1052 if (error)
1053 return error;
1054 error = ss_put_value(l, l->l_md.md_bpva + 4, SSBREAKPOINT);
1055 if (error)
1056 return error;
1057
1058 tf->tf_ipsw |= PSW_T;
1059
1060 return 0;
1061 }
1062 #endif
1063
1064
1065 /*
1066 * call actual syscall routine
1067 * from the low-level syscall handler:
1068 * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto
1069 * our stack, this wins compared to copyin just needed amount anyway
1070 * - register args are copied onto stack too
1071 */
1072 void
1073 syscall(struct trapframe *frame, int *args)
1074 {
1075 struct lwp *l;
1076 struct proc *p;
1077 const struct sysent *callp;
1078 int nsys, code, error;
1079 int tmp;
1080 int rval[2];
1081
1082 uvmexp.syscalls++;
1083
1084 #ifdef DEBUG
1085 frame_sanity_check(0xdead04, 0, frame, curlwp);
1086 #endif /* DEBUG */
1087
1088 if (!USERMODE(frame->tf_iioq_head))
1089 panic("syscall");
1090
1091 l = curlwp;
1092 p = l->l_proc;
1093 l->l_md.md_regs = frame;
1094 nsys = p->p_emul->e_nsysent;
1095 callp = p->p_emul->e_sysent;
1096 code = frame->tf_t1;
1097 LWP_CACHE_CREDS(l, p);
1098
1099 /*
1100 * Restarting a system call is touchy on the HPPA,
1101 * because syscall arguments are passed in registers
1102 * and the program counter of the syscall "point"
1103 * isn't easily divined.
1104 *
1105 * We handle the first problem by assuming that we
1106 * will have to restart this system call, so we
1107 * stuff the first four words of the original arguments
1108 * back into the frame as arg0...arg3, which is where
1109 * we found them in the first place. Any further
1110 * arguments are (still) on the user's stack and the
1111 * syscall code will fetch them from there (again).
1112 *
1113 * The program counter problem is addressed below.
1114 */
1115 frame->tf_arg0 = args[0];
1116 frame->tf_arg1 = args[1];
1117 frame->tf_arg2 = args[2];
1118 frame->tf_arg3 = args[3];
1119
1120 /*
1121 * Some special handling for the syscall(2) and
1122 * __syscall(2) system calls.
1123 */
1124 switch (code) {
1125 case SYS_syscall:
1126 code = *args;
1127 args += 1;
1128 break;
1129 case SYS___syscall:
1130 if (callp != sysent)
1131 break;
1132 /*
1133 * NB: even though __syscall(2) takes a quad_t
1134 * containing the system call number, because
1135 * our argument copying word-swaps 64-bit arguments,
1136 * the least significant word of that quad_t
1137 * is the first word in the argument array.
1138 */
1139 code = *args;
1140 args += 2;
1141 }
1142
1143 /*
1144 * Stacks growing from lower addresses to higher
1145 * addresses are not really such a good idea, because
1146 * it makes it impossible to overlay a struct on top
1147 * of C stack arguments (the arguments appear in
1148 * reversed order).
1149 *
1150 * You can do the obvious thing (as locore.S does) and
1151 * copy argument words one by one, laying them out in
1152 * the "right" order in the destination buffer, but this
1153 * ends up word-swapping multi-word arguments (like off_t).
1154 *
1155 * To compensate, we have some automatically-generated
1156 * code that word-swaps these multi-word arguments.
1157 * Right now the script that generates this code is
1158 * in Perl, because I don't know awk.
1159 *
1160 * FIXME - this works only on native binaries and
1161 * will probably screw up any and all emulation.
1162 */
1163 switch (code) {
1164 /*
1165 * BEGIN automatically generated
1166 * by /home/fredette/project/hppa/makescargfix.pl
1167 * do not edit!
1168 */
1169 case SYS_pread:
1170 /*
1171 * syscallarg(int) fd;
1172 * syscallarg(void *) buf;
1173 * syscallarg(size_t) nbyte;
1174 * syscallarg(int) pad;
1175 * syscallarg(off_t) offset;
1176 */
1177 tmp = args[4];
1178 args[4] = args[4 + 1];
1179 args[4 + 1] = tmp;
1180 break;
1181 case SYS_pwrite:
1182 /*
1183 * syscallarg(int) fd;
1184 * syscallarg(const void *) buf;
1185 * syscallarg(size_t) nbyte;
1186 * syscallarg(int) pad;
1187 * syscallarg(off_t) offset;
1188 */
1189 tmp = args[4];
1190 args[4] = args[4 + 1];
1191 args[4 + 1] = tmp;
1192 break;
1193 case SYS_mmap:
1194 /*
1195 * syscallarg(void *) addr;
1196 * syscallarg(size_t) len;
1197 * syscallarg(int) prot;
1198 * syscallarg(int) flags;
1199 * syscallarg(int) fd;
1200 * syscallarg(long) pad;
1201 * syscallarg(off_t) pos;
1202 */
1203 tmp = args[6];
1204 args[6] = args[6 + 1];
1205 args[6 + 1] = tmp;
1206 break;
1207 case SYS_lseek:
1208 /*
1209 * syscallarg(int) fd;
1210 * syscallarg(int) pad;
1211 * syscallarg(off_t) offset;
1212 */
1213 tmp = args[2];
1214 args[2] = args[2 + 1];
1215 args[2 + 1] = tmp;
1216 break;
1217 case SYS_truncate:
1218 /*
1219 * syscallarg(const char *) path;
1220 * syscallarg(int) pad;
1221 * syscallarg(off_t) length;
1222 */
1223 tmp = args[2];
1224 args[2] = args[2 + 1];
1225 args[2 + 1] = tmp;
1226 break;
1227 case SYS_ftruncate:
1228 /*
1229 * syscallarg(int) fd;
1230 * syscallarg(int) pad;
1231 * syscallarg(off_t) length;
1232 */
1233 tmp = args[2];
1234 args[2] = args[2 + 1];
1235 args[2 + 1] = tmp;
1236 break;
1237 case SYS_preadv:
1238 /*
1239 * syscallarg(int) fd;
1240 * syscallarg(const struct iovec *) iovp;
1241 * syscallarg(int) iovcnt;
1242 * syscallarg(int) pad;
1243 * syscallarg(off_t) offset;
1244 */
1245 tmp = args[4];
1246 args[4] = args[4 + 1];
1247 args[4 + 1] = tmp;
1248 break;
1249 case SYS_pwritev:
1250 /*
1251 * syscallarg(int) fd;
1252 * syscallarg(const struct iovec *) iovp;
1253 * syscallarg(int) iovcnt;
1254 * syscallarg(int) pad;
1255 * syscallarg(off_t) offset;
1256 */
1257 tmp = args[4];
1258 args[4] = args[4 + 1];
1259 args[4 + 1] = tmp;
1260 break;
1261 default:
1262 break;
1263 /*
1264 * END automatically generated
1265 * by /home/fredette/project/hppa/makescargfix.pl
1266 * do not edit!
1267 */
1268 }
1269
1270 #ifdef USERTRACE
1271 if (0) {
1272 user_backtrace(frame, l, -1);
1273 frame->tf_ipsw |= PSW_R;
1274 frame->tf_rctr = 0;
1275 printf("r %08x", frame->tf_iioq_head);
1276 rctr_next_iioq = frame->tf_iioq_head + 4;
1277 }
1278 #endif
1279
1280 if (code < 0 || code >= nsys)
1281 callp += p->p_emul->e_nosys; /* bad syscall # */
1282 else
1283 callp += code;
1284
1285 if ((error = trace_enter(code, args, callp->sy_narg)) != 0)
1286 goto out;
1287
1288 rval[0] = 0;
1289 rval[1] = 0;
1290 error = (*callp->sy_call)(l, args, rval);
1291 out:
1292 switch (error) {
1293 case 0:
1294 l = curlwp; /* changes on exec() */
1295 frame = l->l_md.md_regs;
1296 frame->tf_ret0 = rval[0];
1297 frame->tf_ret1 = rval[1];
1298 frame->tf_t1 = 0;
1299 break;
1300 case ERESTART:
1301 /*
1302 * Now we have to wind back the instruction
1303 * offset queue to the point where the system
1304 * call will be made again. This is inherently
1305 * tied to the SYSCALL macro.
1306 *
1307 * Currently, the part of the SYSCALL macro
1308 * that we want to rerun reads as:
1309 *
1310 * ldil L%SYSCALLGATE, r1
1311 * ble 4(sr7, r1)
1312 * ldi __CONCAT(SYS_,x), t1
1313 * comb,<> %r0, %t1, __cerror
1314 *
1315 * And our offset queue head points to the
1316 * comb instruction. So we need to
1317 * subtract twelve to reach the ldil.
1318 */
1319 frame->tf_iioq_head -= 12;
1320 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
1321 break;
1322 case EJUSTRETURN:
1323 p = curproc;
1324 break;
1325 default:
1326 if (p->p_emul->e_errno)
1327 error = p->p_emul->e_errno[error];
1328 frame->tf_t1 = error;
1329 break;
1330 }
1331
1332 trace_exit(code, rval, error);
1333
1334 userret(l, frame->tf_iioq_head, 0);
1335 #ifdef DEBUG
1336 frame_sanity_check(0xdead05, 0, frame, l);
1337 #endif /* DEBUG */
1338 }
1339
1340 /*
1341 * Start a new LWP
1342 */
1343 void
1344 startlwp(void *arg)
1345 {
1346 int err;
1347 ucontext_t *uc = arg;
1348 struct lwp *l = curlwp;
1349
1350 err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
1351 #if DIAGNOSTIC
1352 if (err) {
1353 printf("Error %d from cpu_setmcontext.", err);
1354 }
1355 #endif
1356 pool_put(&lwp_uc_pool, uc);
1357
1358 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1359 }
1360