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