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