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