1 /* $NetBSD: trap.c,v 1.5 2002/11/15 20:06:01 manu 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 /* #define INTRDEBUG */ 72 /* #define TRAPDEBUG */ 73 /* #define USERTRACE */ 74 75 #include "opt_kgdb.h" 76 #include "opt_syscall_debug.h" 77 #include "opt_ktrace.h" 78 #include "opt_systrace.h" 79 80 #include <sys/param.h> 81 #include <sys/systm.h> 82 #include <sys/kernel.h> 83 #include <sys/syscall.h> 84 #ifdef KTRACE 85 #include <sys/ktrace.h> 86 #endif 87 #ifdef SYSTRACE 88 #include <sys/systrace.h> 89 #endif 90 #include <sys/proc.h> 91 #include <sys/signalvar.h> 92 #include <sys/user.h> 93 #include <sys/acct.h> 94 #include <sys/signal.h> 95 #include <sys/device.h> 96 97 #include <net/netisr.h> 98 99 #ifdef KGDB 100 #include <sys/kgdb.h> 101 #endif 102 103 #include <uvm/uvm.h> 104 105 #include <machine/iomod.h> 106 #include <machine/cpufunc.h> 107 #include <machine/reg.h> 108 #include <machine/autoconf.h> 109 110 #include <machine/db_machdep.h> 111 112 #include <hppa/hppa/machdep.h> 113 114 #if defined(INTRDEBUG) || defined(TRAPDEBUG) 115 #include <ddb/db_output.h> 116 #endif 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 int want_resched; 168 volatile int astpending; 169 170 void pmap_hptdump __P((void)); 171 void syscall __P((struct trapframe *frame, int *args)); 172 173 #ifdef USERTRACE 174 /* 175 * USERTRACE is a crude facility that traces the PC of 176 * a single user process. This tracing is normally 177 * activated by the dispatching of a certain syscall 178 * with certain arguments - see the activation code in 179 * syscall(). 180 */ 181 u_int rctr_next_iioq; 182 #endif 183 184 static __inline void 185 userret (struct proc *p, register_t pc, u_quad_t oticks) 186 { 187 int sig; 188 189 /* take pending signals */ 190 while ((sig = CURSIG(p)) != 0) 191 postsig(sig); 192 193 p->p_priority = p->p_usrpri; 194 if (want_resched) { 195 /* 196 * We're being preempted. 197 */ 198 preempt(NULL); 199 while ((sig = CURSIG(p)) != 0) 200 postsig(sig); 201 } 202 203 /* 204 * If profiling, charge recent system time to the trapped pc. 205 */ 206 if (p->p_flag & P_PROFIL) { 207 extern int psratio; 208 209 addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio); 210 } 211 212 curcpu()->ci_schedstate.spc_curpriority = p->p_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", frame->tf_iioq_head, frame->tf_iioq_tail); 276 #endif 277 if (frame->tf_ipsw & PSW_N) { 278 #ifdef TRAPDEBUG 279 printf("(single stepping past nullified)\n"); 280 #endif 281 282 /* Advance the program counter. */ 283 frame->tf_iioq_head = frame->tf_iioq_tail; 284 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 285 286 /* Clear flags. */ 287 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L); 288 289 /* Simulate another trap. */ 290 type = T_RECOVERY; 291 continue; 292 } 293 frame->tf_rctr = 0; 294 } 295 296 /* We handled this trap. */ 297 return (1); 298 } 299 /* NOTREACHED */ 300 } 301 #else /* !KGDB && !DDB */ 302 #define trap_kdebug(t, c, f) (0) 303 #endif /* !KGDB && !DDB */ 304 305 #ifdef DIAGNOSTIC 306 /* 307 * These functions give a crude usermode backtrace. They 308 * really only work when code has been compiled without 309 * optimization, as they assume a certain function prologue 310 * sets up a frame pointer and stores the return pointer 311 * and arguments in it. 312 */ 313 static void user_backtrace_raw __P((u_int, u_int)); 314 static void 315 user_backtrace_raw(u_int pc, u_int fp) 316 { 317 int frame_number; 318 int arg_number; 319 320 for (frame_number = 0; 321 frame_number < 100 && pc > HPPA_PC_PRIV_MASK && fp; 322 frame_number++) { 323 324 printf("%3d: pc=%08x%s fp=0x%08x", frame_number, 325 pc & ~HPPA_PC_PRIV_MASK, USERMODE(pc) ? "" : "**", fp); 326 for(arg_number = 0; arg_number < 4; arg_number++) 327 printf(" arg%d=0x%08x", arg_number, 328 (int) fuword(HPPA_FRAME_CARG(arg_number, fp))); 329 printf("\n"); 330 pc = fuword(((register_t *) fp) - 5); /* fetch rp */ 331 if (pc == -1) { 332 printf(" fuword for pc failed\n"); 333 break; 334 } 335 fp = fuword(((register_t *) fp) + 0); /* fetch previous fp */ 336 if (fp == -1) { 337 printf(" fuword for fp failed\n"); 338 break; 339 } 340 } 341 printf(" backtrace stopped with pc %08x fp 0x%08x\n", pc, fp); 342 } 343 344 static void user_backtrace __P((struct trapframe *, struct proc *, int)); 345 static void 346 user_backtrace(struct trapframe *tf, struct proc *p, int type) 347 { 348 u_int pc, fp, inst; 349 350 /* 351 * Display any trap type that we have. 352 */ 353 if (type >= 0) 354 printf("pid %d (%s) trap #%d\n", 355 p->p_pid, p->p_comm, type & ~T_USER); 356 357 /* 358 * Assuming that the frame pointer in r3 is valid, 359 * dump out a stack trace. 360 */ 361 fp = tf->tf_r3; 362 printf("pid %d (%s) backtrace, starting with fp 0x%08x\n", 363 p->p_pid, p->p_comm, fp); 364 user_backtrace_raw(tf->tf_iioq_head, fp); 365 366 /* 367 * In case the frame pointer in r3 is not valid, 368 * assuming the stack pointer is valid and the 369 * faulting function is a non-leaf, if we can 370 * find its prologue we can recover its frame 371 * pointer. 372 */ 373 pc = tf->tf_iioq_head; 374 fp = tf->tf_sp - HPPA_FRAME_SIZE; 375 printf("pid %d (%s) backtrace, starting with sp 0x%08x pc 0x%08x\n", 376 p->p_pid, p->p_comm, tf->tf_sp, pc); 377 for(pc &= ~HPPA_PC_PRIV_MASK; pc > 0; pc -= sizeof(inst)) { 378 inst = fuword((register_t *) pc); 379 if (inst == -1) { 380 printf(" fuword for inst at pc %08x failed\n", pc); 381 break; 382 } 383 /* Check for the prologue instruction that sets sp. */ 384 if (STWM_R1_D_SR0_SP(inst)) { 385 fp = tf->tf_sp - STWM_R1_D_SR0_SP(inst); 386 printf(" sp from fp at pc %08x: %08x\n", pc, inst); 387 break; 388 } 389 } 390 user_backtrace_raw(tf->tf_iioq_head, fp); 391 } 392 #endif /* DIAGNOSTIC */ 393 394 #ifdef DEBUG 395 /* 396 * This sanity-checks a trapframe. It is full of various 397 * assumptions about what a healthy CPU state should be, 398 * with some documented elsewhere, some not. 399 */ 400 struct trapframe *sanity_frame; 401 struct proc *sanity_proc; 402 int sanity_checked = 0; 403 void frame_sanity_check __P((struct trapframe *, struct proc *)); 404 void 405 frame_sanity_check(struct trapframe *tf, struct proc *p) 406 { 407 extern int kernel_text; 408 extern int etext; 409 extern register_t kpsw; 410 extern vaddr_t hpt_base; 411 extern vsize_t hpt_mask; 412 vsize_t uspace_size; 413 #define SANITY(e) \ 414 do { \ 415 if (sanity_frame == NULL && !(e)) { \ 416 sanity_frame = tf; \ 417 sanity_proc = p; \ 418 sanity_checked = __LINE__; \ 419 } \ 420 } while (/* CONSTCOND */ 0) 421 422 SANITY((tf->tf_ipsw & kpsw) == kpsw); 423 SANITY(tf->tf_hptm == hpt_mask && tf->tf_vtop == hpt_base); 424 SANITY((kpsw & PSW_I) == 0 || tf->tf_eiem != 0); 425 if (tf->tf_iisq_head == HPPA_SID_KERNEL) { 426 /* 427 * If the trap happened in the gateway 428 * page, we take the easy way out and 429 * assume that the trapframe is okay. 430 */ 431 if ((tf->tf_iioq_head & ~PAGE_MASK) != SYSCALLGATE) { 432 SANITY(!USERMODE(tf->tf_iioq_head)); 433 SANITY(!USERMODE(tf->tf_iioq_tail)); 434 SANITY(tf->tf_iioq_head >= (u_int) &kernel_text); 435 SANITY(tf->tf_iioq_head < (u_int) &etext); 436 SANITY(tf->tf_iioq_tail >= (u_int) &kernel_text); 437 SANITY(tf->tf_iioq_tail < (u_int) &etext); 438 #ifdef HPPA_REDZONE 439 uspace_size = HPPA_REDZONE; 440 #else 441 uspace_size = USPACE; 442 #endif 443 SANITY(p == NULL || 444 ((tf->tf_sp >= (u_int)(p->p_addr) + NBPG && 445 tf->tf_sp < (u_int)(p->p_addr) + uspace_size))); 446 } 447 } else { 448 SANITY(USERMODE(tf->tf_iioq_head)); 449 SANITY(USERMODE(tf->tf_iioq_tail)); 450 SANITY(p != NULL && tf->tf_cr30 == kvtop((caddr_t)p->p_addr)); 451 } 452 #undef SANITY 453 if (sanity_frame == tf) { 454 (void) trap_kdebug(T_IBREAK, 0, tf); 455 sanity_frame = NULL; 456 sanity_proc = NULL; 457 sanity_checked = 0; 458 } 459 } 460 #endif /* DEBUG */ 461 462 void 463 trap(type, frame) 464 int type; 465 struct trapframe *frame; 466 { 467 struct proc *p = curproc; 468 struct pcb *pcbp; 469 register vaddr_t va; 470 register struct vm_map *map; 471 struct vmspace *vm; 472 register vm_prot_t vftype; 473 register pa_space_t space; 474 u_int opcode; 475 int ret; 476 const char *tts; 477 int type_raw; 478 #ifdef DIAGNOSTIC 479 extern int emergency_stack_start, emergency_stack_end; 480 #endif 481 482 type_raw = type & ~T_USER; 483 opcode = frame->tf_iir; 484 if (type_raw == T_ITLBMISS || type_raw == T_ITLBMISSNA) { 485 va = frame->tf_iioq_head; 486 space = frame->tf_iisq_head; 487 vftype = VM_PROT_READ; /* XXX VM_PROT_EXECUTE ??? */ 488 } else { 489 va = frame->tf_ior; 490 space = frame->tf_isr; 491 vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ; 492 } 493 494 #ifdef DIAGNOSTIC 495 /* 496 * If we are on the emergency stack, then we either got 497 * a fault on the kernel stack, or we're just handling 498 * a trap for the machine check handler (which also 499 * runs on the emergency stack). 500 * 501 * We *very crudely* differentiate between the two cases 502 * by checking the faulting instruction: if it is the 503 * function prologue instruction that stores the old 504 * frame pointer and updates the stack pointer, we assume 505 * that we faulted on the kernel stack. 506 * 507 * In this case, not completing that instruction will 508 * probably confuse backtraces in kgdb/ddb. Completing 509 * it would be difficult, because we already faulted on 510 * that part of the stack, so instead we fix up the 511 * frame as if the function called has just returned. 512 * This has peculiar knowledge about what values are in 513 * what registers during the "normal gcc -g" prologue. 514 */ 515 if (&type >= &emergency_stack_start && 516 &type < &emergency_stack_end && 517 type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) { 518 /* Restore the caller's frame pointer. */ 519 frame->tf_r3 = frame->tf_r1; 520 /* Restore the caller's instruction offsets. */ 521 frame->tf_iioq_head = frame->tf_rp; 522 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 523 goto dead_end; 524 } 525 #endif /* DIAGNOSTIC */ 526 527 #ifdef DEBUG 528 frame_sanity_check(frame, p); 529 #endif /* DEBUG */ 530 531 /* If this is a trap, not an interrupt, reenable interrupts. */ 532 if (type_raw != T_INTERRUPT) 533 mtctl(frame->tf_eiem, CR_EIEM); 534 535 if (frame->tf_flags & TFF_LAST) 536 p->p_md.md_regs = frame; 537 538 if ((type & ~T_USER) > trap_types) 539 tts = "reserved"; 540 else 541 tts = trap_type[type & ~T_USER]; 542 543 #ifdef TRAPDEBUG 544 if (type_raw != T_INTERRUPT && type_raw != T_IBREAK) 545 printf("trap: %d, %s for %x:%x at %x:%x, fp=%p, rp=%x\n", 546 type, tts, space, (u_int)va, frame->tf_iisq_head, 547 frame->tf_iioq_head, frame, frame->tf_rp); 548 else if (type_raw == T_IBREAK) 549 printf("trap: break instruction %x:%x at %x:%x, fp=%p\n", 550 break5(opcode), break13(opcode), 551 frame->tf_iisq_head, frame->tf_iioq_head, frame); 552 553 { 554 extern int etext; 555 if (frame < (struct trapframe *)&etext) { 556 printf("trap: bogus frame ptr %p\n", frame); 557 goto dead_end; 558 } 559 } 560 #endif 561 switch (type) { 562 case T_NONEXIST: 563 case T_NONEXIST|T_USER: 564 #if !defined(DDB) && !defined(KGDB) 565 /* we've got screwed up by the central scrutinizer */ 566 panic ("trap: elvis has just left the building!"); 567 break; 568 #else 569 goto dead_end; 570 #endif 571 case T_RECOVERY|T_USER: 572 #ifdef USERTRACE 573 for(;;) { 574 if (frame->tf_iioq_head != rctr_next_iioq) 575 printf("-%08x\nr %08x", 576 rctr_next_iioq - 4, 577 frame->tf_iioq_head); 578 rctr_next_iioq = frame->tf_iioq_head + 4; 579 if (frame->tf_ipsw & PSW_N) { 580 /* Advance the program counter. */ 581 frame->tf_iioq_head = frame->tf_iioq_tail; 582 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 583 /* Clear flags. */ 584 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L); 585 /* Simulate another trap. */ 586 continue; 587 } 588 break; 589 } 590 frame->tf_rctr = 0; 591 break; 592 #endif /* USERTRACE */ 593 case T_RECOVERY: 594 #if !defined(DDB) && !defined(KGDB) 595 /* XXX will implement later */ 596 printf ("trap: handicapped"); 597 break; 598 #else 599 goto dead_end; 600 #endif 601 602 case T_EMULATION | T_USER: 603 #ifdef FPEMUL 604 hppa_fpu_emulate(frame, p); 605 #else /* !FPEMUL */ 606 /* 607 * We don't have FPU emulation, so signal the 608 * process with a SIGFPE. 609 */ 610 trapsignal(p, SIGFPE, frame->tf_iioq_head); 611 #endif /* !FPEMUL */ 612 break; 613 614 #ifdef DIAGNOSTIC 615 case T_EXCEPTION: 616 panic("FPU/SFU emulation botch"); 617 618 /* these just can't happen ever */ 619 case T_PRIV_OP: 620 case T_PRIV_REG: 621 /* these just can't make it to the trap() ever */ 622 case T_HPMC: case T_HPMC | T_USER: 623 case T_EMULATION: 624 #endif 625 case T_IBREAK: 626 case T_DATALIGN: 627 case T_DBREAK: 628 dead_end: 629 if (type & T_USER) { 630 #ifdef DEBUG 631 user_backtrace(frame, p, type); 632 #endif 633 trapsignal(p, SIGILL, frame->tf_iioq_head); 634 break; 635 } 636 if (trap_kdebug(type, va, frame)) 637 return; 638 else if (type == T_DATALIGN) 639 panic ("trap: %s at 0x%x", tts, (u_int) va); 640 else 641 panic ("trap: no debugger for \"%s\" (%d)", tts, type); 642 break; 643 644 case T_IBREAK | T_USER: 645 case T_DBREAK | T_USER: 646 /* pass to user debugger */ 647 break; 648 649 case T_EXCEPTION | T_USER: /* co-proc assist trap */ 650 trapsignal(p, SIGFPE, va); 651 break; 652 653 case T_OVERFLOW | T_USER: 654 trapsignal(p, SIGFPE, va); 655 break; 656 657 case T_CONDITION | T_USER: 658 break; 659 660 case T_ILLEGAL | T_USER: 661 #ifdef DEBUG 662 user_backtrace(frame, p, type); 663 #endif 664 trapsignal(p, SIGILL, va); 665 break; 666 667 case T_PRIV_OP | T_USER: 668 #ifdef DEBUG 669 user_backtrace(frame, p, type); 670 #endif 671 trapsignal(p, SIGILL, va); 672 break; 673 674 case T_PRIV_REG | T_USER: 675 #ifdef DEBUG 676 user_backtrace(frame, p, type); 677 #endif 678 trapsignal(p, SIGILL, va); 679 break; 680 681 /* these should never got here */ 682 case T_HIGHERPL | T_USER: 683 case T_LOWERPL | T_USER: 684 trapsignal(p, SIGSEGV, va); 685 break; 686 687 case T_IPROT | T_USER: 688 case T_DPROT | T_USER: 689 trapsignal(p, SIGSEGV, va); 690 break; 691 692 case T_DATACC: case T_USER | T_DATACC: 693 case T_ITLBMISS: case T_USER | T_ITLBMISS: 694 case T_DTLBMISS: case T_USER | T_DTLBMISS: 695 case T_ITLBMISSNA: case T_USER | T_ITLBMISSNA: 696 case T_DTLBMISSNA: case T_USER | T_DTLBMISSNA: 697 case T_TLB_DIRTY: case T_USER | T_TLB_DIRTY: 698 va = hppa_trunc_page(va); 699 vm = p->p_vmspace; 700 701 if (!vm) { 702 #ifdef TRAPDEBUG 703 printf("trap: no vm, p=%p\n", p); 704 #endif 705 goto dead_end; 706 } 707 708 /* 709 * it could be a kernel map for exec_map faults 710 */ 711 if (!(type & T_USER) && space == HPPA_SID_KERNEL) 712 map = kernel_map; 713 else 714 map = &vm->vm_map; 715 716 if (map->pmap->pmap_space != space) { 717 #ifdef TRAPDEBUG 718 printf("trap: space missmatch %d != %d\n", 719 space, map->pmap->pmap_space); 720 #endif 721 /* actually dump the user, crap the kernel */ 722 goto dead_end; 723 } 724 725 /* Never call uvm_fault in interrupt context. */ 726 KASSERT(hppa_intr_depth == 0); 727 728 ret = uvm_fault(map, va, 0, vftype); 729 730 #ifdef TRAPDEBUG 731 printf("uvm_fault(%p, %x, %d, %d)=%d\n", 732 map, (u_int)va, 0, vftype, ret); 733 #endif 734 735 /* 736 * If this was a stack access we keep track of the maximum 737 * accessed stack size. Also, if uvm_fault gets a protection 738 * failure it is due to accessing the stack region outside 739 * the current limit and we need to reflect that as an access 740 * error. 741 */ 742 if (va >= (vaddr_t)vm->vm_maxsaddr + vm->vm_ssize) { 743 if (ret == 0) { 744 vsize_t nss = btoc(va - USRSTACK + NBPG); 745 if (nss > vm->vm_ssize) 746 vm->vm_ssize = nss; 747 } else if (ret == EACCES) 748 ret = EFAULT; 749 } 750 751 if (ret != 0) { 752 if (type & T_USER) { 753 printf("trapsignal: uvm_fault(%p, %x, %d, %d)=%d\n", 754 map, (u_int)va, 0, vftype, ret); 755 #ifdef DEBUG 756 user_backtrace(frame, p, type); 757 #endif 758 trapsignal(p, SIGSEGV, frame->tf_ior); 759 } else { 760 if (p && p->p_addr->u_pcb.pcb_onfault) { 761 #ifdef PMAPDEBUG 762 printf("trap: copyin/out %d\n",ret); 763 #endif 764 pcbp = &p->p_addr->u_pcb; 765 frame->tf_iioq_tail = 4 + 766 (frame->tf_iioq_head = 767 pcbp->pcb_onfault); 768 pcbp->pcb_onfault = 0; 769 break; 770 } 771 #if 1 772 if (trap_kdebug (type, va, frame)) 773 return; 774 #else 775 panic("trap: uvm_fault(%p, %x, %d, %d): %d", 776 map, va, 0, vftype, ret); 777 #endif 778 } 779 } 780 break; 781 782 case T_DATALIGN | T_USER: 783 #ifdef DEBUG 784 user_backtrace(frame, p, type); 785 #endif 786 trapsignal(p, SIGBUS, va); 787 break; 788 789 case T_INTERRUPT: 790 case T_INTERRUPT|T_USER: 791 hppa_intr(frame); 792 mtctl(frame->tf_eiem, CR_EIEM); 793 #if 0 794 if (trap_kdebug (type, va, frame)) 795 return; 796 #endif 797 break; 798 case T_LOWERPL: 799 case T_DPROT: 800 case T_IPROT: 801 case T_OVERFLOW: 802 case T_CONDITION: 803 case T_ILLEGAL: 804 case T_HIGHERPL: 805 case T_TAKENBR: 806 case T_POWERFAIL: 807 case T_LPMC: 808 case T_PAGEREF: 809 case T_DATAPID: case T_DATAPID | T_USER: 810 if (0 /* T-chip */) { 811 break; 812 } 813 /* FALLTHROUGH to unimplemented */ 814 default: 815 #if 1 816 if (trap_kdebug (type, va, frame)) 817 return; 818 #endif 819 panic ("trap: unimplemented \'%s\' (%d)", tts, type); 820 } 821 822 if (type & T_USER) 823 userret(p, p->p_md.md_regs->tf_iioq_head, 0); 824 825 #ifdef DEBUG 826 frame_sanity_check(frame, p); 827 if (frame->tf_flags & TFF_LAST && curproc != NULL) 828 frame_sanity_check(curproc->p_md.md_regs, curproc); 829 #endif /* DEBUG */ 830 } 831 832 void 833 child_return(arg) 834 void *arg; 835 { 836 struct proc *p = arg; 837 838 userret(p, p->p_md.md_regs->tf_iioq_head, 0); 839 #ifdef KTRACE 840 if (KTRPOINT(p, KTR_SYSRET)) 841 ktrsysret(p, SYS_fork, 0, 0); 842 #endif 843 #ifdef DEBUG 844 frame_sanity_check(p->p_md.md_regs, p); 845 #endif /* DEBUG */ 846 } 847 848 /* 849 * call actual syscall routine 850 * from the low-level syscall handler: 851 * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto 852 * our stack, this wins compared to copyin just needed amount anyway 853 * - register args are copied onto stack too 854 */ 855 void 856 syscall(frame, args) 857 struct trapframe *frame; 858 int *args; 859 { 860 register struct proc *p; 861 register const struct sysent *callp; 862 int nsys, code, argsize, error; 863 int tmp; 864 int rval[2]; 865 866 uvmexp.syscalls++; 867 868 #ifdef DEBUG 869 frame_sanity_check(frame, curproc); 870 #endif /* DEBUG */ 871 872 if (!USERMODE(frame->tf_iioq_head)) 873 panic("syscall"); 874 875 p = curproc; 876 p->p_md.md_regs = frame; 877 nsys = p->p_emul->e_nsysent; 878 callp = p->p_emul->e_sysent; 879 code = frame->tf_t1; 880 881 /* 882 * Restarting a system call is touchy on the HPPA, 883 * because syscall arguments are passed in registers 884 * and the program counter of the syscall "point" 885 * isn't easily divined. 886 * 887 * We handle the first problem by assuming that we 888 * will have to restart this system call, so we 889 * stuff the first four words of the original arguments 890 * back into the frame as arg0...arg3, which is where 891 * we found them in the first place. Any further 892 * arguments are (still) on the user's stack and the 893 * syscall code will fetch them from there (again). 894 * 895 * The program counter problem is addressed below. 896 */ 897 frame->tf_arg0 = args[0]; 898 frame->tf_arg1 = args[1]; 899 frame->tf_arg2 = args[2]; 900 frame->tf_arg3 = args[3]; 901 902 /* 903 * Some special handling for the syscall(2) and 904 * __syscall(2) system calls. 905 */ 906 switch (code) { 907 case SYS_syscall: 908 code = *args; 909 args += 1; 910 break; 911 case SYS___syscall: 912 if (callp != sysent) 913 break; 914 /* 915 * NB: even though __syscall(2) takes a quad_t 916 * containing the system call number, because 917 * our argument copying word-swaps 64-bit arguments, 918 * the least significant word of that quad_t 919 * is the first word in the argument array. 920 */ 921 code = *args; 922 args += 2; 923 } 924 925 /* 926 * Stacks growing from lower addresses to higher 927 * addresses are not really such a good idea, because 928 * it makes it impossible to overlay a struct on top 929 * of C stack arguments (the arguments appear in 930 * reversed order). 931 * 932 * You can do the obvious thing (as locore.S does) and 933 * copy argument words one by one, laying them out in 934 * the "right" order in the destination buffer, but this 935 * ends up word-swapping multi-word arguments (like off_t). 936 * 937 * To compensate, we have some automatically-generated 938 * code that word-swaps these multi-word arguments. 939 * Right now the script that generates this code is 940 * in Perl, because I don't know awk. 941 * 942 * FIXME - this works only on native binaries and 943 * will probably screw up any and all emulation. 944 */ 945 switch (code) { 946 /* 947 * BEGIN automatically generated 948 * by /home/fredette/project/hppa/makescargfix.pl 949 * do not edit! 950 */ 951 case SYS_pread: 952 /* 953 * syscallarg(int) fd; 954 * syscallarg(void *) buf; 955 * syscallarg(size_t) nbyte; 956 * syscallarg(int) pad; 957 * syscallarg(off_t) offset; 958 */ 959 tmp = args[4]; 960 args[4] = args[4 + 1]; 961 args[4 + 1] = tmp; 962 break; 963 case SYS_pwrite: 964 /* 965 * syscallarg(int) fd; 966 * syscallarg(const void *) buf; 967 * syscallarg(size_t) nbyte; 968 * syscallarg(int) pad; 969 * syscallarg(off_t) offset; 970 */ 971 tmp = args[4]; 972 args[4] = args[4 + 1]; 973 args[4 + 1] = tmp; 974 break; 975 case SYS_mmap: 976 /* 977 * syscallarg(void *) addr; 978 * syscallarg(size_t) len; 979 * syscallarg(int) prot; 980 * syscallarg(int) flags; 981 * syscallarg(int) fd; 982 * syscallarg(long) pad; 983 * syscallarg(off_t) pos; 984 */ 985 tmp = args[6]; 986 args[6] = args[6 + 1]; 987 args[6 + 1] = tmp; 988 break; 989 case SYS_lseek: 990 /* 991 * syscallarg(int) fd; 992 * syscallarg(int) pad; 993 * syscallarg(off_t) offset; 994 */ 995 tmp = args[2]; 996 args[2] = args[2 + 1]; 997 args[2 + 1] = tmp; 998 break; 999 case SYS_truncate: 1000 /* 1001 * syscallarg(const char *) path; 1002 * syscallarg(int) pad; 1003 * syscallarg(off_t) length; 1004 */ 1005 tmp = args[2]; 1006 args[2] = args[2 + 1]; 1007 args[2 + 1] = tmp; 1008 break; 1009 case SYS_ftruncate: 1010 /* 1011 * syscallarg(int) fd; 1012 * syscallarg(int) pad; 1013 * syscallarg(off_t) length; 1014 */ 1015 tmp = args[2]; 1016 args[2] = args[2 + 1]; 1017 args[2 + 1] = tmp; 1018 break; 1019 case SYS_preadv: 1020 /* 1021 * syscallarg(int) fd; 1022 * syscallarg(const struct iovec *) iovp; 1023 * syscallarg(int) iovcnt; 1024 * syscallarg(int) pad; 1025 * syscallarg(off_t) offset; 1026 */ 1027 tmp = args[4]; 1028 args[4] = args[4 + 1]; 1029 args[4 + 1] = tmp; 1030 break; 1031 case SYS_pwritev: 1032 /* 1033 * syscallarg(int) fd; 1034 * syscallarg(const struct iovec *) iovp; 1035 * syscallarg(int) iovcnt; 1036 * syscallarg(int) pad; 1037 * syscallarg(off_t) offset; 1038 */ 1039 tmp = args[4]; 1040 args[4] = args[4 + 1]; 1041 args[4 + 1] = tmp; 1042 break; 1043 default: 1044 break; 1045 /* 1046 * END automatically generated 1047 * by /home/fredette/project/hppa/makescargfix.pl 1048 * do not edit! 1049 */ 1050 } 1051 1052 #ifdef USERTRACE 1053 if (0) { 1054 user_backtrace(frame, p, -1); 1055 frame->tf_ipsw |= PSW_R; 1056 frame->tf_rctr = 0; 1057 printf("r %08x", frame->tf_iioq_head); 1058 rctr_next_iioq = frame->tf_iioq_head + 4; 1059 } 1060 #endif 1061 1062 if (code < 0 || code >= nsys) 1063 callp += p->p_emul->e_nosys; /* bad syscall # */ 1064 else 1065 callp += code; 1066 argsize = callp->sy_argsize; 1067 1068 if ((error = trace_enter(p, code, code, args, rval)) != 0) 1069 goto bad; 1070 1071 rval[0] = 0; 1072 rval[1] = 0; 1073 switch (error = (*callp->sy_call)(p, args, rval)) { 1074 case 0: 1075 p = curproc; /* changes on exec() */ 1076 frame = p->p_md.md_regs; 1077 frame->tf_ret0 = rval[0]; 1078 frame->tf_ret1 = rval[1]; 1079 frame->tf_t1 = 0; 1080 break; 1081 case ERESTART: 1082 /* 1083 * Now we have to wind back the instruction 1084 * offset queue to the point where the system 1085 * call will be made again. This is inherently 1086 * tied to the SYSCALL macro. 1087 * 1088 * Currently, the part of the SYSCALL macro 1089 * that we want to rerun reads as: 1090 * 1091 * ldil L%SYSCALLGATE, r1 1092 * ble 4(sr7, r1) 1093 * ldi __CONCAT(SYS_,x), t1 1094 * ldw HPPA_FRAME_ERP(sr0,sp), rp 1095 * 1096 * And our offset queue head points to the 1097 * final ldw instruction. So we need to 1098 * subtract twelve to reach the ldil. 1099 */ 1100 frame->tf_iioq_head -= 12; 1101 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 1102 break; 1103 case EJUSTRETURN: 1104 p = curproc; 1105 break; 1106 default: 1107 bad: 1108 if (p->p_emul->e_errno) 1109 error = p->p_emul->e_errno[error]; 1110 frame->tf_t1 = error; 1111 break; 1112 } 1113 1114 trace_exit(p, code, args, rval, error); 1115 1116 userret(p, frame->tf_iioq_head, 0); 1117 #ifdef DEBUG 1118 frame_sanity_check(frame, p); 1119 #endif /* DEBUG */ 1120 } 1121