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