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