trap.c revision 1.60 1 /* $NetBSD: trap.c,v 1.60 2009/11/03 05:07:26 snj 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-2004 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 *
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
51 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
56 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
57 * THE POSSIBILITY OF SUCH DAMAGE.
58 */
59
60 #include <sys/cdefs.h>
61 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.60 2009/11/03 05:07:26 snj Exp $");
62
63 /* #define INTRDEBUG */
64 /* #define TRAPDEBUG */
65 /* #define USERTRACE */
66
67 #include "opt_kgdb.h"
68 #include "opt_ptrace.h"
69 #include "opt_sa.h"
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/kernel.h>
74 #include <sys/syscall.h>
75 #include <sys/syscallvar.h>
76 #include <sys/sa.h>
77 #include <sys/savar.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 #define SANITY(e) \
418 do { \
419 if (sanity_frame == NULL && !(e)) { \
420 sanity_frame = tf; \
421 sanity_lwp = l; \
422 sanity_checked = __LINE__; \
423 } \
424 } while (/* CONSTCOND */ 0)
425
426 SANITY((tf->tf_ipsw & kpsw) == kpsw);
427 SANITY((kpsw & PSW_I) == 0 || tf->tf_eiem != 0);
428 if (tf->tf_iisq_head == HPPA_SID_KERNEL) {
429 vaddr_t minsp, maxsp;
430
431 /*
432 * If the trap happened in the gateway
433 * page, we take the easy way out and
434 * assume that the trapframe is okay.
435 */
436 if ((tf->tf_iioq_head & ~PAGE_MASK) == SYSCALLGATE)
437 goto out;
438
439 SANITY(!USERMODE(tf->tf_iioq_head));
440 SANITY(!USERMODE(tf->tf_iioq_tail));
441
442 /*
443 * Don't check the instruction queues or stack on interrupts
444 * as we could be be in the sti code (outside normal kernel
445 * text) or switching LWPs (curlwp and sp are not in sync)
446 */
447 if ((type & ~T_USER) == T_INTERRUPT)
448 goto out;
449
450 SANITY(tf->tf_iioq_head >= (u_int) &kernel_text);
451 SANITY(tf->tf_iioq_head < (u_int) &etext);
452 SANITY(tf->tf_iioq_tail >= (u_int) &kernel_text);
453 SANITY(tf->tf_iioq_tail < (u_int) &etext);
454
455 maxsp = (u_int)(l->l_addr) + USPACE + PAGE_SIZE;
456 minsp = (u_int)(l->l_addr) + PAGE_SIZE;
457
458 SANITY(l != NULL || (tf->tf_sp >= minsp && tf->tf_sp < maxsp));
459 } else {
460 SANITY(USERMODE(tf->tf_iioq_head));
461 SANITY(USERMODE(tf->tf_iioq_tail));
462 SANITY(l != NULL && tf->tf_cr30 == kvtop((void *)l->l_addr));
463 }
464 #undef SANITY
465 out:
466 if (sanity_frame == tf) {
467 printf("insanity: where 0x%x type 0x%x tf %p lwp %p line %d "
468 "sp 0x%x pc 0x%x\n",
469 where, type, sanity_frame, sanity_lwp, sanity_checked,
470 tf->tf_sp, tf->tf_iioq_head);
471 (void) trap_kdebug(T_IBREAK, 0, tf);
472 sanity_frame = NULL;
473 sanity_lwp = NULL;
474 sanity_checked = 0;
475 }
476 }
477 #endif /* DEBUG */
478
479 void
480 trap(int type, struct trapframe *frame)
481 {
482 struct lwp *l;
483 struct proc *p;
484 struct pcb *pcbp;
485 vaddr_t va;
486 struct vm_map *map;
487 struct vmspace *vm;
488 vm_prot_t vftype;
489 pa_space_t space;
490 ksiginfo_t ksi;
491 u_int opcode, onfault;
492 int ret;
493 const char *tts;
494 int type_raw;
495 #ifdef DIAGNOSTIC
496 extern int emergency_stack_start, emergency_stack_end;
497 #endif
498
499 type_raw = type & ~T_USER;
500 opcode = frame->tf_iir;
501 if (type_raw == T_ITLBMISS || type_raw == T_ITLBMISSNA ||
502 type_raw == T_IBREAK || type_raw == T_TAKENBR) {
503 va = frame->tf_iioq_head;
504 space = frame->tf_iisq_head;
505 vftype = VM_PROT_EXECUTE;
506 } else {
507 va = frame->tf_ior;
508 space = frame->tf_isr;
509 vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ;
510 }
511
512 l = curlwp;
513 p = l ? l->l_proc : NULL;
514 if ((type & T_USER) != 0)
515 LWP_CACHE_CREDS(l, p);
516
517 tts = (type & ~T_USER) > trap_types ? "reserved" :
518 trap_type[type & ~T_USER];
519
520 #ifdef DIAGNOSTIC
521 /*
522 * If we are on the emergency stack, then we either got
523 * a fault on the kernel stack, or we're just handling
524 * a trap for the machine check handler (which also
525 * runs on the emergency stack).
526 *
527 * We *very crudely* differentiate between the two cases
528 * by checking the faulting instruction: if it is the
529 * function prologue instruction that stores the old
530 * frame pointer and updates the stack pointer, we assume
531 * that we faulted on the kernel stack.
532 *
533 * In this case, not completing that instruction will
534 * probably confuse backtraces in kgdb/ddb. Completing
535 * it would be difficult, because we already faulted on
536 * that part of the stack, so instead we fix up the
537 * frame as if the function called has just returned.
538 * This has peculiar knowledge about what values are in
539 * what registers during the "normal gcc -g" prologue.
540 */
541 if (&type >= &emergency_stack_start &&
542 &type < &emergency_stack_end &&
543 type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) {
544 /* Restore the caller's frame pointer. */
545 frame->tf_r3 = frame->tf_r1;
546 /* Restore the caller's instruction offsets. */
547 frame->tf_iioq_head = frame->tf_rp;
548 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
549 goto dead_end;
550 }
551 #endif /* DIAGNOSTIC */
552
553 #ifdef DEBUG
554 frame_sanity_check(0xdead01, type, frame, l);
555 #endif /* DEBUG */
556
557 /* If this is a trap, not an interrupt, reenable interrupts. */
558 if (type_raw != T_INTERRUPT)
559 mtctl(frame->tf_eiem, CR_EIEM);
560
561 if (frame->tf_flags & TFF_LAST)
562 l->l_md.md_regs = frame;
563
564 #ifdef TRAPDEBUG
565 if (type_raw != T_INTERRUPT && type_raw != T_IBREAK)
566 printf("trap: %d, %s for %x:%x at %x:%x, fp=%p, rp=%x\n",
567 type, tts, space, (u_int)va, frame->tf_iisq_head,
568 frame->tf_iioq_head, frame, frame->tf_rp);
569 else if (type_raw == T_IBREAK)
570 printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",
571 break5(opcode), break13(opcode),
572 frame->tf_iisq_head, frame->tf_iioq_head, frame);
573
574 {
575 extern int etext;
576 if (frame < (struct trapframe *)&etext) {
577 printf("trap: bogus frame ptr %p\n", frame);
578 goto dead_end;
579 }
580 }
581 #endif
582 switch (type) {
583 case T_NONEXIST:
584 case T_NONEXIST|T_USER:
585 #if !defined(DDB) && !defined(KGDB)
586 /* we've got screwed up by the central scrutinizer */
587 panic ("trap: elvis has just left the building!");
588 break;
589 #else
590 goto dead_end;
591 #endif
592 case T_RECOVERY|T_USER:
593 #ifdef USERTRACE
594 for(;;) {
595 if (frame->tf_iioq_head != rctr_next_iioq)
596 printf("-%08x\nr %08x",
597 rctr_next_iioq - 4,
598 frame->tf_iioq_head);
599 rctr_next_iioq = frame->tf_iioq_head + 4;
600 if (frame->tf_ipsw & PSW_N) {
601 /* Advance the program counter. */
602 frame->tf_iioq_head = frame->tf_iioq_tail;
603 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
604 /* Clear flags. */
605 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L);
606 /* Simulate another trap. */
607 continue;
608 }
609 break;
610 }
611 frame->tf_rctr = 0;
612 break;
613 #endif /* USERTRACE */
614 case T_RECOVERY:
615 #if !defined(DDB) && !defined(KGDB)
616 /* XXX will implement later */
617 printf ("trap: handicapped");
618 break;
619 #else
620 goto dead_end;
621 #endif
622
623 case T_EMULATION | T_USER:
624 #ifdef FPEMUL
625 hppa_fpu_emulate(frame, l, opcode);
626 #else /* !FPEMUL */
627 /*
628 * We don't have FPU emulation, so signal the
629 * process with a SIGFPE.
630 */
631
632 KSI_INIT_TRAP(&ksi);
633 ksi.ksi_signo = SIGFPE;
634 ksi.ksi_code = SI_NOINFO;
635 ksi.ksi_trap = type;
636 ksi.ksi_addr = (void *)frame->tf_iioq_head;
637 trapsignal(l, &ksi);
638 #endif /* !FPEMUL */
639 break;
640
641 case T_DATALIGN:
642 if (l->l_addr->u_pcb.pcb_onfault) {
643 do_onfault:
644 pcbp = &l->l_addr->u_pcb;
645 frame->tf_iioq_tail = 4 +
646 (frame->tf_iioq_head =
647 pcbp->pcb_onfault);
648 pcbp->pcb_onfault = 0;
649 break;
650 }
651 /*FALLTHROUGH*/
652
653 #ifdef DIAGNOSTIC
654 /* these just can't happen ever */
655 case T_PRIV_OP:
656 case T_PRIV_REG:
657 /* these just can't make it to the trap() ever */
658 case T_HPMC:
659 case T_HPMC | T_USER:
660 case T_EMULATION:
661 case T_EXCEPTION:
662 #endif
663 case T_IBREAK:
664 case T_DBREAK:
665 dead_end:
666 if (type & T_USER) {
667 #ifdef DEBUG
668 user_backtrace(frame, l, type);
669 #endif
670 KSI_INIT_TRAP(&ksi);
671 ksi.ksi_signo = SIGILL;
672 ksi.ksi_code = ILL_ILLTRP;
673 ksi.ksi_trap = type;
674 ksi.ksi_addr = (void *)frame->tf_iioq_head;
675 trapsignal(l, &ksi);
676 break;
677 }
678 if (trap_kdebug(type, va, frame))
679 return;
680 else if (type == T_DATALIGN)
681 panic ("trap: %s at 0x%x", tts, (u_int) va);
682 else
683 panic ("trap: no debugger for \"%s\" (%d)", tts, type);
684 break;
685
686 case T_IBREAK | T_USER:
687 case T_DBREAK | T_USER:
688 KSI_INIT_TRAP(&ksi);
689 ksi.ksi_signo = SIGTRAP;
690 ksi.ksi_code = TRAP_TRACE;
691 ksi.ksi_trap = type_raw;
692 ksi.ksi_addr = (void *)frame->tf_iioq_head;
693 #ifdef PTRACE
694 ss_clear_breakpoints(l);
695 if (opcode == SSBREAKPOINT)
696 ksi.ksi_code = TRAP_BRKPT;
697 #endif
698 /* pass to user debugger */
699 trapsignal(l, &ksi);
700
701 break;
702
703 #ifdef PTRACE
704 case T_TAKENBR | T_USER:
705 ss_clear_breakpoints(l);
706
707 KSI_INIT_TRAP(&ksi);
708 ksi.ksi_signo = SIGTRAP;
709 ksi.ksi_code = TRAP_TRACE;
710 ksi.ksi_trap = type_raw;
711 ksi.ksi_addr = (void *)frame->tf_iioq_head;
712
713 /* pass to user debugger */
714 trapsignal(l, &ksi);
715 break;
716 #endif
717
718 case T_EXCEPTION | T_USER: { /* co-proc assist trap */
719 uint64_t *fpp;
720 uint32_t *pex, ex, inst;
721 int i;
722
723 hppa_fpu_flush(l);
724 fpp = l->l_addr->u_pcb.pcb_fpregs;
725 pex = (uint32_t *)&fpp[1];
726 for (i = 1; i < 8 && !*pex; i++, pex++)
727 ;
728 KASSERT(i < 8);
729 ex = *pex;
730 *pex = 0;
731
732 /* reset the trap flag, as if there was none */
733 fpp[0] &= ~(((uint64_t)HPPA_FPU_T) << 32);
734
735 /* emulate the instruction */
736 inst = ((uint32_t)fpopmap[ex >> 26] << 26) | (ex & 0x03ffffff);
737 hppa_fpu_emulate(frame, l, inst);
738 }
739 break;
740
741 case T_OVERFLOW | T_USER:
742 KSI_INIT_TRAP(&ksi);
743 ksi.ksi_signo = SIGFPE;
744 ksi.ksi_code = SI_NOINFO;
745 ksi.ksi_trap = type;
746 ksi.ksi_addr = (void *)va;
747 trapsignal(l, &ksi);
748 break;
749
750 case T_CONDITION | T_USER:
751 KSI_INIT_TRAP(&ksi);
752 ksi.ksi_signo = SIGFPE;
753 ksi.ksi_code = FPE_INTDIV;
754 ksi.ksi_trap = type;
755 ksi.ksi_addr = (void *)va;
756 trapsignal(l, &ksi);
757 break;
758
759 case T_ILLEGAL | T_USER:
760 #ifdef DEBUG
761 user_backtrace(frame, l, type);
762 #endif
763 KSI_INIT_TRAP(&ksi);
764 ksi.ksi_signo = SIGILL;
765 ksi.ksi_code = ILL_ILLOPC;
766 ksi.ksi_trap = type;
767 ksi.ksi_addr = (void *)va;
768 trapsignal(l, &ksi);
769 break;
770
771 case T_PRIV_OP | T_USER:
772 #ifdef DEBUG
773 user_backtrace(frame, l, type);
774 #endif
775 KSI_INIT_TRAP(&ksi);
776 ksi.ksi_signo = SIGILL;
777 ksi.ksi_code = ILL_PRVOPC;
778 ksi.ksi_trap = type;
779 ksi.ksi_addr = (void *)va;
780 trapsignal(l, &ksi);
781 break;
782
783 case T_PRIV_REG | T_USER:
784 #ifdef DEBUG
785 user_backtrace(frame, l, type);
786 #endif
787 KSI_INIT_TRAP(&ksi);
788 ksi.ksi_signo = SIGILL;
789 ksi.ksi_code = ILL_PRVREG;
790 ksi.ksi_trap = type;
791 ksi.ksi_addr = (void *)va;
792 trapsignal(l, &ksi);
793 break;
794
795 /* these should never got here */
796 case T_HIGHERPL | T_USER:
797 case T_LOWERPL | T_USER:
798 KSI_INIT_TRAP(&ksi);
799 ksi.ksi_signo = SIGSEGV;
800 ksi.ksi_code = SEGV_ACCERR;
801 ksi.ksi_trap = type;
802 ksi.ksi_addr = (void *)va;
803 trapsignal(l, &ksi);
804 break;
805
806 case T_IPROT | T_USER:
807 case T_DPROT | T_USER:
808 KSI_INIT_TRAP(&ksi);
809 ksi.ksi_signo = SIGSEGV;
810 ksi.ksi_code = SEGV_ACCERR;
811 ksi.ksi_trap = type;
812 ksi.ksi_addr = (void *)va;
813 trapsignal(l, &ksi);
814 break;
815
816 case T_DATACC: case T_USER | T_DATACC:
817 case T_ITLBMISS: case T_USER | T_ITLBMISS:
818 case T_DTLBMISS: case T_USER | T_DTLBMISS:
819 case T_ITLBMISSNA: case T_USER | T_ITLBMISSNA:
820 case T_DTLBMISSNA: case T_USER | T_DTLBMISSNA:
821 case T_TLB_DIRTY: case T_USER | T_TLB_DIRTY:
822 vm = p->p_vmspace;
823
824 if (!vm) {
825 #ifdef TRAPDEBUG
826 printf("trap: no vm, p=%p\n", p);
827 #endif
828 goto dead_end;
829 }
830
831 /*
832 * it could be a kernel map for exec_map faults
833 */
834 if (!(type & T_USER) && space == HPPA_SID_KERNEL)
835 map = kernel_map;
836 else {
837 map = &vm->vm_map;
838 if ((l->l_flag & LW_SA)
839 && (~l->l_pflag & LP_SA_NOBLOCK)) {
840 l->l_savp->savp_faultaddr = va;
841 l->l_pflag |= LP_SA_PAGEFAULT;
842 }
843 }
844
845 va = trunc_page(va);
846
847 if (map->pmap->pm_space != space) {
848 #ifdef TRAPDEBUG
849 printf("trap: space mismatch %d != %d\n",
850 space, map->pmap->pm_space);
851 #endif
852 /* actually dump the user, crap the kernel */
853 goto dead_end;
854 }
855
856 /* Never call uvm_fault in interrupt context. */
857 KASSERT(hppa_intr_depth == 0);
858
859 onfault = l->l_addr->u_pcb.pcb_onfault;
860 l->l_addr->u_pcb.pcb_onfault = 0;
861 ret = uvm_fault(map, va, vftype);
862 l->l_addr->u_pcb.pcb_onfault = onfault;
863
864 #ifdef TRAPDEBUG
865 printf("uvm_fault(%p, %x, %d)=%d\n",
866 map, (u_int)va, vftype, ret);
867 #endif
868
869 if (map != kernel_map)
870 l->l_pflag &= ~LP_SA_PAGEFAULT;
871
872 /*
873 * If this was a stack access we keep track of the maximum
874 * accessed stack size. Also, if uvm_fault gets a protection
875 * failure it is due to accessing the stack region outside
876 * the current limit and we need to reflect that as an access
877 * error.
878 */
879 if (map != kernel_map && va >= (vaddr_t)vm->vm_minsaddr) {
880 if (ret == 0)
881 uvm_grow(l->l_proc, va);
882 else if (ret == EACCES)
883 ret = EFAULT;
884 }
885
886 if (ret != 0) {
887 if (type & T_USER) {
888 #ifdef DEBUG
889 user_backtrace(frame, l, type);
890 #endif
891 KSI_INIT_TRAP(&ksi);
892 ksi.ksi_signo = SIGSEGV;
893 ksi.ksi_code = (ret == EACCES ?
894 SEGV_ACCERR : SEGV_MAPERR);
895 ksi.ksi_trap = type;
896 ksi.ksi_addr = (void *)va;
897 trapsignal(l, &ksi);
898 } else {
899 if (l->l_addr->u_pcb.pcb_onfault) {
900 goto do_onfault;
901 }
902 panic("trap: uvm_fault(%p, %lx, %d): %d",
903 map, va, vftype, ret);
904 }
905 }
906 break;
907
908 case T_DATALIGN | T_USER:
909 #ifdef DEBUG
910 user_backtrace(frame, l, type);
911 #endif
912 KSI_INIT_TRAP(&ksi);
913 ksi.ksi_signo = SIGBUS;
914 ksi.ksi_code = BUS_ADRALN;
915 ksi.ksi_trap = type;
916 ksi.ksi_addr = (void *)va;
917 trapsignal(l, &ksi);
918 break;
919
920 case T_INTERRUPT:
921 case T_INTERRUPT|T_USER:
922 hppa_intr(frame);
923 mtctl(frame->tf_eiem, CR_EIEM);
924 break;
925
926 case T_LOWERPL:
927 case T_DPROT:
928 case T_IPROT:
929 case T_OVERFLOW:
930 case T_CONDITION:
931 case T_ILLEGAL:
932 case T_HIGHERPL:
933 case T_TAKENBR:
934 case T_POWERFAIL:
935 case T_LPMC:
936 case T_PAGEREF:
937 case T_DATAPID: case T_DATAPID | T_USER:
938 if (0 /* T-chip */) {
939 break;
940 }
941 /* FALLTHROUGH to unimplemented */
942 default:
943 panic ("trap: unimplemented \'%s\' (%d)", tts, type);
944 }
945
946 if (type & T_USER)
947 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
948
949 #ifdef DEBUG
950 frame_sanity_check(0xdead02, type, frame, l);
951 if (frame->tf_flags & TFF_LAST && (curlwp->l_flag & LW_IDLE) == 0)
952 frame_sanity_check(0xdead03, type, curlwp->l_md.md_regs,
953 curlwp);
954 #endif /* DEBUG */
955 }
956
957 void
958 child_return(void *arg)
959 {
960 struct lwp *l = arg;
961
962 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
963 ktrsysret(SYS_fork, 0, 0);
964 #ifdef DEBUG
965 frame_sanity_check(0xdead04, 0, l->l_md.md_regs, l);
966 #endif /* DEBUG */
967 }
968
969 #ifdef PTRACE
970
971 #include <sys/ptrace.h>
972
973 int
974 ss_get_value(struct lwp *l, vaddr_t addr, u_int *value)
975 {
976 struct uio uio;
977 struct iovec iov;
978
979 iov.iov_base = (void *)value;
980 iov.iov_len = sizeof(u_int);
981 uio.uio_iov = &iov;
982 uio.uio_iovcnt = 1;
983 uio.uio_offset = (off_t)addr;
984 uio.uio_resid = sizeof(u_int);
985 uio.uio_rw = UIO_READ;
986 UIO_SETUP_SYSSPACE(&uio);
987
988 return (process_domem(curlwp, l, &uio));
989 }
990
991 int
992 ss_put_value(struct lwp *l, vaddr_t addr, u_int value)
993 {
994 struct uio uio;
995 struct iovec iov;
996
997 iov.iov_base = (void *)&value;
998 iov.iov_len = sizeof(u_int);
999 uio.uio_iov = &iov;
1000 uio.uio_iovcnt = 1;
1001 uio.uio_offset = (off_t)addr;
1002 uio.uio_resid = sizeof(u_int);
1003 uio.uio_rw = UIO_WRITE;
1004 UIO_SETUP_SYSSPACE(&uio);
1005
1006 return (process_domem(curlwp, l, &uio));
1007 }
1008
1009 void
1010 ss_clear_breakpoints(struct lwp *l)
1011 {
1012 /* Restore origional instructions. */
1013 if (l->l_md.md_bpva != 0) {
1014 ss_put_value(l, l->l_md.md_bpva, l->l_md.md_bpsave[0]);
1015 ss_put_value(l, l->l_md.md_bpva + 4, l->l_md.md_bpsave[1]);
1016 l->l_md.md_bpva = 0;
1017 }
1018 }
1019
1020
1021 int
1022 process_sstep(struct lwp *l, int sstep)
1023 {
1024 struct trapframe *tf = l->l_md.md_regs;
1025 int error;
1026
1027 ss_clear_breakpoints(l);
1028
1029 /* We're continuing... */
1030 /* Don't touch the syscall gateway page. */
1031 /* XXX head */
1032 if (sstep == 0 ||
1033 (tf->tf_iioq_tail & ~PAGE_MASK) == SYSCALLGATE) {
1034 tf->tf_ipsw &= ~PSW_T;
1035 return 0;
1036 }
1037
1038 l->l_md.md_bpva = tf->tf_iioq_tail & ~HPPA_PC_PRIV_MASK;
1039
1040 /*
1041 * Insert two breakpoint instructions; the first one might be
1042 * nullified. Of course we need to save two instruction
1043 * first.
1044 */
1045
1046 error = ss_get_value(l, l->l_md.md_bpva, &l->l_md.md_bpsave[0]);
1047 if (error)
1048 return (error);
1049 error = ss_get_value(l, l->l_md.md_bpva + 4, &l->l_md.md_bpsave[1]);
1050 if (error)
1051 return (error);
1052
1053 error = ss_put_value(l, l->l_md.md_bpva, SSBREAKPOINT);
1054 if (error)
1055 return error;
1056 error = ss_put_value(l, l->l_md.md_bpva + 4, SSBREAKPOINT);
1057 if (error)
1058 return error;
1059
1060 tf->tf_ipsw |= PSW_T;
1061
1062 return 0;
1063 }
1064 #endif
1065
1066
1067 /*
1068 * call actual syscall routine
1069 * from the low-level syscall handler:
1070 * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto
1071 * our stack, this wins compared to copyin just needed amount anyway
1072 * - register args are copied onto stack too
1073 */
1074 void
1075 syscall(struct trapframe *frame, int *args)
1076 {
1077 struct lwp *l;
1078 struct proc *p;
1079 const struct sysent *callp;
1080 int nsys, code, error;
1081 int tmp;
1082 int rval[2];
1083
1084 uvmexp.syscalls++;
1085
1086 #ifdef DEBUG
1087 frame_sanity_check(0xdead04, 0, frame, curlwp);
1088 #endif /* DEBUG */
1089
1090 if (!USERMODE(frame->tf_iioq_head))
1091 panic("syscall");
1092
1093 l = curlwp;
1094 p = l->l_proc;
1095 l->l_md.md_regs = frame;
1096 nsys = p->p_emul->e_nsysent;
1097 callp = p->p_emul->e_sysent;
1098 code = frame->tf_t1;
1099 LWP_CACHE_CREDS(l, p);
1100
1101 #ifdef KERN_SA
1102 if (__predict_false((l->l_savp)
1103 && (l->l_savp->savp_pflags & SAVP_FLAG_DELIVERING)))
1104 l->l_savp->savp_pflags &= ~SAVP_FLAG_DELIVERING;
1105 #endif
1106
1107 /*
1108 * Restarting a system call is touchy on the HPPA,
1109 * because syscall arguments are passed in registers
1110 * and the program counter of the syscall "point"
1111 * isn't easily divined.
1112 *
1113 * We handle the first problem by assuming that we
1114 * will have to restart this system call, so we
1115 * stuff the first four words of the original arguments
1116 * back into the frame as arg0...arg3, which is where
1117 * we found them in the first place. Any further
1118 * arguments are (still) on the user's stack and the
1119 * syscall code will fetch them from there (again).
1120 *
1121 * The program counter problem is addressed below.
1122 */
1123 frame->tf_arg0 = args[0];
1124 frame->tf_arg1 = args[1];
1125 frame->tf_arg2 = args[2];
1126 frame->tf_arg3 = args[3];
1127
1128 /*
1129 * Some special handling for the syscall(2) and
1130 * __syscall(2) system calls.
1131 */
1132 switch (code) {
1133 case SYS_syscall:
1134 code = *args;
1135 args += 1;
1136 break;
1137 case SYS___syscall:
1138 if (callp != sysent)
1139 break;
1140 /*
1141 * NB: even though __syscall(2) takes a quad_t
1142 * containing the system call number, because
1143 * our argument copying word-swaps 64-bit arguments,
1144 * the least significant word of that quad_t
1145 * is the first word in the argument array.
1146 */
1147 code = *args;
1148 args += 2;
1149 }
1150
1151 /*
1152 * Stacks growing from lower addresses to higher
1153 * addresses are not really such a good idea, because
1154 * it makes it impossible to overlay a struct on top
1155 * of C stack arguments (the arguments appear in
1156 * reversed order).
1157 *
1158 * You can do the obvious thing (as locore.S does) and
1159 * copy argument words one by one, laying them out in
1160 * the "right" order in the destination buffer, but this
1161 * ends up word-swapping multi-word arguments (like off_t).
1162 *
1163 * To compensate, we have some automatically-generated
1164 * code that word-swaps these multi-word arguments.
1165 * Right now the script that generates this code is
1166 * in Perl, because I don't know awk.
1167 *
1168 * FIXME - this works only on native binaries and
1169 * will probably screw up any and all emulation.
1170 */
1171 switch (code) {
1172 case SYS_pread:
1173 /*
1174 * syscallarg(int) fd;
1175 * syscallarg(void *) buf;
1176 * syscallarg(size_t) nbyte;
1177 * syscallarg(int) pad;
1178 * syscallarg(off_t) offset;
1179 */
1180 tmp = args[4];
1181 args[4] = args[4 + 1];
1182 args[4 + 1] = tmp;
1183 break;
1184 case SYS_pwrite:
1185 /*
1186 * syscallarg(int) fd;
1187 * syscallarg(const void *) buf;
1188 * syscallarg(size_t) nbyte;
1189 * syscallarg(int) pad;
1190 * syscallarg(off_t) offset;
1191 */
1192 tmp = args[4];
1193 args[4] = args[4 + 1];
1194 args[4 + 1] = tmp;
1195 break;
1196 case SYS_mmap:
1197 /*
1198 * syscallarg(void *) addr;
1199 * syscallarg(size_t) len;
1200 * syscallarg(int) prot;
1201 * syscallarg(int) flags;
1202 * syscallarg(int) fd;
1203 * syscallarg(long) pad;
1204 * syscallarg(off_t) pos;
1205 */
1206 tmp = args[6];
1207 args[6] = args[6 + 1];
1208 args[6 + 1] = tmp;
1209 break;
1210 case SYS_lseek:
1211 /*
1212 * syscallarg(int) fd;
1213 * syscallarg(int) pad;
1214 * syscallarg(off_t) offset;
1215 */
1216 tmp = args[2];
1217 args[2] = args[2 + 1];
1218 args[2 + 1] = tmp;
1219 break;
1220 case SYS_truncate:
1221 /*
1222 * syscallarg(const char *) path;
1223 * syscallarg(int) pad;
1224 * syscallarg(off_t) length;
1225 */
1226 tmp = args[2];
1227 args[2] = args[2 + 1];
1228 args[2 + 1] = tmp;
1229 break;
1230 case SYS_ftruncate:
1231 /*
1232 * syscallarg(int) fd;
1233 * syscallarg(int) pad;
1234 * syscallarg(off_t) length;
1235 */
1236 tmp = args[2];
1237 args[2] = args[2 + 1];
1238 args[2 + 1] = tmp;
1239 break;
1240 case SYS_preadv:
1241 /*
1242 * syscallarg(int) fd;
1243 * syscallarg(const struct iovec *) iovp;
1244 * syscallarg(int) iovcnt;
1245 * syscallarg(int) pad;
1246 * syscallarg(off_t) offset;
1247 */
1248 tmp = args[4];
1249 args[4] = args[4 + 1];
1250 args[4 + 1] = tmp;
1251 break;
1252 case SYS_pwritev:
1253 /*
1254 * syscallarg(int) fd;
1255 * syscallarg(const struct iovec *) iovp;
1256 * syscallarg(int) iovcnt;
1257 * syscallarg(int) pad;
1258 * syscallarg(off_t) offset;
1259 */
1260 tmp = args[4];
1261 args[4] = args[4 + 1];
1262 args[4 + 1] = tmp;
1263 break;
1264 case SYS___posix_fadvise50:
1265 /*
1266 * syscallarg(int) fd;
1267 * syscallarg(int) pad;
1268 * syscallarg(off_t) offset;
1269 * syscallarg(off_t) len;
1270 * syscallarg(int) advice;
1271 */
1272 tmp = args[2];
1273 args[2] = args[2 + 1];
1274 args[2 + 1] = tmp;
1275 tmp = args[4];
1276 args[4] = args[4 + 1];
1277 args[4 + 1] = tmp;
1278 case SYS___mknod50:
1279 /*
1280 * syscallarg(const char *) path;
1281 * syscallarg(mode_t) mode;
1282 * syscallarg(dev_t) dev;
1283 */
1284 tmp = args[2];
1285 args[2] = args[2 + 1];
1286 args[2 + 1] = tmp;
1287 default:
1288 break;
1289 }
1290
1291 #ifdef USERTRACE
1292 if (0) {
1293 user_backtrace(frame, l, -1);
1294 frame->tf_ipsw |= PSW_R;
1295 frame->tf_rctr = 0;
1296 printf("r %08x", frame->tf_iioq_head);
1297 rctr_next_iioq = frame->tf_iioq_head + 4;
1298 }
1299 #endif
1300
1301 if (code < 0 || code >= nsys)
1302 callp += p->p_emul->e_nosys; /* bad syscall # */
1303 else
1304 callp += code;
1305
1306 if ((error = trace_enter(code, args, callp->sy_narg)) != 0)
1307 goto out;
1308
1309 rval[0] = 0;
1310 rval[1] = 0;
1311 error = sy_call(callp, l, args, rval);
1312 out:
1313 switch (error) {
1314 case 0:
1315 l = curlwp; /* changes on exec() */
1316 frame = l->l_md.md_regs;
1317 frame->tf_ret0 = rval[0];
1318 frame->tf_ret1 = rval[1];
1319 frame->tf_t1 = 0;
1320 break;
1321 case ERESTART:
1322 /*
1323 * Now we have to wind back the instruction
1324 * offset queue to the point where the system
1325 * call will be made again. This is inherently
1326 * tied to the SYSCALL macro.
1327 *
1328 * Currently, the part of the SYSCALL macro
1329 * that we want to rerun reads as:
1330 *
1331 * ldil L%SYSCALLGATE, r1
1332 * ble 4(sr7, r1)
1333 * ldi __CONCAT(SYS_,x), t1
1334 * comb,<> %r0, %t1, __cerror
1335 *
1336 * And our offset queue head points to the
1337 * comb instruction. So we need to
1338 * subtract twelve to reach the ldil.
1339 */
1340 frame->tf_iioq_head -= 12;
1341 frame->tf_iioq_tail = frame->tf_iioq_head + 4;
1342 break;
1343 case EJUSTRETURN:
1344 p = curproc;
1345 break;
1346 default:
1347 if (p->p_emul->e_errno)
1348 error = p->p_emul->e_errno[error];
1349 frame->tf_t1 = error;
1350 break;
1351 }
1352
1353 trace_exit(code, rval, error);
1354
1355 userret(l, frame->tf_iioq_head, 0);
1356 #ifdef DEBUG
1357 frame_sanity_check(0xdead05, 0, frame, l);
1358 #endif /* DEBUG */
1359 }
1360
1361 /*
1362 * Start a new LWP
1363 */
1364 void
1365 startlwp(void *arg)
1366 {
1367 int err;
1368 ucontext_t *uc = arg;
1369 struct lwp *l = curlwp;
1370
1371 err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
1372 #if DIAGNOSTIC
1373 if (err) {
1374 printf("Error %d from cpu_setmcontext.", err);
1375 }
1376 #endif
1377 pool_put(&lwp_uc_pool, uc);
1378
1379 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1380 }
1381
1382 /*
1383 * XXX This is a terrible name.
1384 */
1385 void
1386 upcallret(struct lwp *l)
1387 {
1388 userret(l, l->l_md.md_regs->tf_iioq_head, 0);
1389 }
1390