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