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