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