trap.c revision 1.23
1/* $NetBSD: trap.c,v 1.23 2004/08/07 21:47:05 chs Exp $ */ 2 3/*- 4 * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matthew Fredette. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* $OpenBSD: trap.c,v 1.30 2001/09/19 20:50:56 mickey Exp $ */ 40 41/* 42 * Copyright (c) 1998-2000 Michael Shalayeff 43 * All rights reserved. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by Michael Shalayeff. 56 * 4. The name of the author may not be used to endorse or promote products 57 * derived from this software without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 60 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 61 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 62 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 63 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 64 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 65 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 66 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 67 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 68 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 */ 70 71#include <sys/cdefs.h> 72__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.23 2004/08/07 21:47:05 chs Exp $"); 73 74/* #define INTRDEBUG */ 75/* #define TRAPDEBUG */ 76/* #define USERTRACE */ 77 78#include "opt_kgdb.h" 79#include "opt_syscall_debug.h" 80#include "opt_ktrace.h" 81#include "opt_systrace.h" 82 83#include <sys/param.h> 84#include <sys/systm.h> 85#include <sys/kernel.h> 86#include <sys/syscall.h> 87#include <sys/sa.h> 88#include <sys/savar.h> 89#ifdef KTRACE 90#include <sys/ktrace.h> 91#endif 92#ifdef SYSTRACE 93#include <sys/systrace.h> 94#endif 95#include <sys/proc.h> 96#include <sys/signalvar.h> 97#include <sys/user.h> 98#include <sys/acct.h> 99#include <sys/signal.h> 100#include <sys/device.h> 101#include <sys/pool.h> 102#include <sys/userret.h> 103 104#include <net/netisr.h> 105 106#ifdef KGDB 107#include <sys/kgdb.h> 108#endif 109 110#include <uvm/uvm.h> 111 112#include <machine/iomod.h> 113#include <machine/cpufunc.h> 114#include <machine/reg.h> 115#include <machine/autoconf.h> 116 117#include <machine/db_machdep.h> 118 119#include <hppa/hppa/machdep.h> 120 121#include <ddb/db_output.h> 122#include <ddb/db_interface.h> 123 124#if defined(DEBUG) || defined(DIAGNOSTIC) 125/* 126 * 0x6fc1000 is a stwm r1, d(sr0, sp), which is the last 127 * instruction in the function prologue that gcc -O0 uses. 128 * When we have this instruction we know the relationship 129 * between the stack pointer and the gcc -O0 frame pointer 130 * (in r3, loaded with the initial sp) for the body of a 131 * function. 132 * 133 * If the given instruction is a stwm r1, d(sr0, sp) where 134 * d > 0, we evaluate to d, else we evaluate to zero. 135 */ 136#define STWM_R1_D_SR0_SP(inst) \ 137 (((inst) & 0xffffc001) == 0x6fc10000 ? (((inst) & 0x00003ff) >> 1) : 0) 138#endif /* DEBUG || DIAGNOSTIC */ 139 140const 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}; 171int trap_types = sizeof(trap_type)/sizeof(trap_type[0]); 172 173uint8_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 184int want_resched; 185volatile int astpending; 186 187void pmap_hptdump(void); 188void 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 */ 198u_int rctr_next_iioq; 199#endif 200 201static __inline void 202userret(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) 233static int 234trap_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#ifdef DIAGNOSTIC 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 */ 323static void user_backtrace_raw(u_int, u_int); 324static void 325user_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 354static void user_backtrace(struct trapframe *, struct lwp *, int); 355static void 356user_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 /* DIAGNOSTIC */ 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 */ 411struct trapframe *sanity_frame; 412struct lwp *sanity_lwp; 413int sanity_checked = 0; 414void frame_sanity_check(struct trapframe *, struct lwp *); 415void 416frame_sanity_check(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) \ 425do { \ 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: tf %p lwp %p line %d sp 0x%x pc 0x%x\n", 466 sanity_frame, sanity_lwp, sanity_checked, 467 tf->tf_sp, tf->tf_iioq_head); 468 (void) trap_kdebug(T_IBREAK, 0, tf); 469 sanity_frame = NULL; 470 sanity_lwp = NULL; 471 sanity_checked = 0; 472 } 473} 474#endif /* DEBUG */ 475 476void 477trap(int type, struct trapframe *frame) 478{ 479 struct lwp *l; 480 struct proc *p; 481 struct pcb *pcbp; 482 vaddr_t va; 483 struct vm_map *map; 484 struct vmspace *vm; 485 vm_prot_t vftype; 486 pa_space_t space; 487 ksiginfo_t ksi; 488 u_int opcode, onfault; 489 int ret; 490 const char *tts; 491 int type_raw; 492#ifdef DIAGNOSTIC 493 extern int emergency_stack_start, emergency_stack_end; 494#endif 495 496 type_raw = type & ~T_USER; 497 opcode = frame->tf_iir; 498 if (type_raw == T_ITLBMISS || type_raw == T_ITLBMISSNA) { 499 va = frame->tf_iioq_head; 500 space = frame->tf_iisq_head; 501 vftype = VM_PROT_EXECUTE; 502 } else { 503 va = frame->tf_ior; 504 space = frame->tf_isr; 505 vftype = inst_store(opcode) ? VM_PROT_WRITE : VM_PROT_READ; 506 } 507 508 l = curlwp; 509 p = l ? l->l_proc : NULL; 510 511 tts = (type & ~T_USER) > trap_types ? "reserved" : 512 trap_type[type & ~T_USER]; 513 514#ifdef DIAGNOSTIC 515 /* 516 * If we are on the emergency stack, then we either got 517 * a fault on the kernel stack, or we're just handling 518 * a trap for the machine check handler (which also 519 * runs on the emergency stack). 520 * 521 * We *very crudely* differentiate between the two cases 522 * by checking the faulting instruction: if it is the 523 * function prologue instruction that stores the old 524 * frame pointer and updates the stack pointer, we assume 525 * that we faulted on the kernel stack. 526 * 527 * In this case, not completing that instruction will 528 * probably confuse backtraces in kgdb/ddb. Completing 529 * it would be difficult, because we already faulted on 530 * that part of the stack, so instead we fix up the 531 * frame as if the function called has just returned. 532 * This has peculiar knowledge about what values are in 533 * what registers during the "normal gcc -g" prologue. 534 */ 535 if (&type >= &emergency_stack_start && 536 &type < &emergency_stack_end && 537 type != T_IBREAK && STWM_R1_D_SR0_SP(opcode)) { 538 /* Restore the caller's frame pointer. */ 539 frame->tf_r3 = frame->tf_r1; 540 /* Restore the caller's instruction offsets. */ 541 frame->tf_iioq_head = frame->tf_rp; 542 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 543 goto dead_end; 544 } 545#endif /* DIAGNOSTIC */ 546 547#ifdef DEBUG 548 frame_sanity_check(frame, l); 549#endif /* DEBUG */ 550 551 /* If this is a trap, not an interrupt, reenable interrupts. */ 552 if (type_raw != T_INTERRUPT) 553 mtctl(frame->tf_eiem, CR_EIEM); 554 555 if (frame->tf_flags & TFF_LAST) 556 l->l_md.md_regs = frame; 557 558#ifdef TRAPDEBUG 559 if (type_raw != T_INTERRUPT && type_raw != T_IBREAK) 560 printf("trap: %d, %s for %x:%x at %x:%x, fp=%p, rp=%x\n", 561 type, tts, space, (u_int)va, frame->tf_iisq_head, 562 frame->tf_iioq_head, frame, frame->tf_rp); 563 else if (type_raw == T_IBREAK) 564 printf("trap: break instruction %x:%x at %x:%x, fp=%p\n", 565 break5(opcode), break13(opcode), 566 frame->tf_iisq_head, frame->tf_iioq_head, frame); 567 568 { 569 extern int etext; 570 if (frame < (struct trapframe *)&etext) { 571 printf("trap: bogus frame ptr %p\n", frame); 572 goto dead_end; 573 } 574 } 575#endif 576 switch (type) { 577 case T_NONEXIST: 578 case T_NONEXIST|T_USER: 579#if !defined(DDB) && !defined(KGDB) 580 /* we've got screwed up by the central scrutinizer */ 581 panic ("trap: elvis has just left the building!"); 582 break; 583#else 584 goto dead_end; 585#endif 586 case T_RECOVERY|T_USER: 587#ifdef USERTRACE 588 for(;;) { 589 if (frame->tf_iioq_head != rctr_next_iioq) 590 printf("-%08x\nr %08x", 591 rctr_next_iioq - 4, 592 frame->tf_iioq_head); 593 rctr_next_iioq = frame->tf_iioq_head + 4; 594 if (frame->tf_ipsw & PSW_N) { 595 /* Advance the program counter. */ 596 frame->tf_iioq_head = frame->tf_iioq_tail; 597 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 598 /* Clear flags. */ 599 frame->tf_ipsw &= ~(PSW_N|PSW_X|PSW_Y|PSW_Z|PSW_B|PSW_T|PSW_H|PSW_L); 600 /* Simulate another trap. */ 601 continue; 602 } 603 break; 604 } 605 frame->tf_rctr = 0; 606 break; 607#endif /* USERTRACE */ 608 case T_RECOVERY: 609#if !defined(DDB) && !defined(KGDB) 610 /* XXX will implement later */ 611 printf ("trap: handicapped"); 612 break; 613#else 614 goto dead_end; 615#endif 616 617 case T_EMULATION | T_USER: 618#ifdef FPEMUL 619 hppa_fpu_emulate(frame, l, opcode); 620#else /* !FPEMUL */ 621 /* 622 * We don't have FPU emulation, so signal the 623 * process with a SIGFPE. 624 */ 625 626 KSI_INIT_TRAP(&ksi); 627 ksi.ksi_signo = SIGFPE; 628 ksi.ksi_code = SI_NOINFO; 629 ksi.ksi_trap = type; 630 ksi.ksi_addr = (void *)frame->tf_iioq_head; 631 trapsignal(l, &ksi); 632#endif /* !FPEMUL */ 633 break; 634 635#ifdef DIAGNOSTIC 636 case T_EXCEPTION: 637 panic("FPU/SFU emulation botch"); 638 639 /* these just can't happen ever */ 640 case T_PRIV_OP: 641 case T_PRIV_REG: 642 /* these just can't make it to the trap() ever */ 643 case T_HPMC: case T_HPMC | T_USER: 644 case T_EMULATION: 645#endif 646 case T_IBREAK: 647 case T_DATALIGN: 648 case T_DBREAK: 649 dead_end: 650 if (type & T_USER) { 651#ifdef DEBUG 652 user_backtrace(frame, l, type); 653#endif 654 KSI_INIT_TRAP(&ksi); 655 ksi.ksi_signo = SIGILL; 656 ksi.ksi_code = ILL_ILLTRP; 657 ksi.ksi_trap = type; 658 ksi.ksi_addr = (void *)frame->tf_iioq_head; 659 trapsignal(l, &ksi); 660 break; 661 } 662 if (trap_kdebug(type, va, frame)) 663 return; 664 else if (type == T_DATALIGN) 665 panic ("trap: %s at 0x%x", tts, (u_int) va); 666 else 667 panic ("trap: no debugger for \"%s\" (%d)", tts, type); 668 break; 669 670 case T_IBREAK | T_USER: 671 case T_DBREAK | T_USER: 672 /* pass to user debugger */ 673 break; 674 675 case T_EXCEPTION | T_USER: { /* co-proc assist trap */ 676 uint64_t *fpp; 677 uint32_t *pex, ex, inst; 678 int i; 679 680 hppa_fpu_flush(l); 681 fpp = l->l_addr->u_pcb.pcb_fpregs; 682 pex = (uint32_t *)&fpp[1]; 683 for (i = 1; i < 8 && !*pex; i++, pex++) 684 ; 685 KASSERT(i < 8); 686 ex = *pex; 687 *pex = 0; 688 689 /* reset the trap flag, as if there was none */ 690 fpp[0] &= ~(((uint64_t)HPPA_FPU_T) << 32); 691 692 /* emulate the instruction */ 693 inst = ((uint32_t)fpopmap[ex >> 26] << 26) | (ex & 0x03ffffff); 694 hppa_fpu_emulate(frame, l, inst); 695 } 696 break; 697 698 case T_OVERFLOW | T_USER: 699 KSI_INIT_TRAP(&ksi); 700 ksi.ksi_signo = SIGFPE; 701 ksi.ksi_code = SI_NOINFO; 702 ksi.ksi_trap = type; 703 ksi.ksi_addr = (void *)va; 704 trapsignal(l, &ksi); 705 break; 706 707 case T_CONDITION | T_USER: 708 KSI_INIT_TRAP(&ksi); 709 ksi.ksi_signo = SIGFPE; 710 ksi.ksi_code = FPE_INTDIV; 711 ksi.ksi_trap = type; 712 ksi.ksi_addr = (void *)va; 713 trapsignal(l, &ksi); 714 break; 715 716 case T_ILLEGAL | T_USER: 717#ifdef DEBUG 718 user_backtrace(frame, l, type); 719#endif 720 KSI_INIT_TRAP(&ksi); 721 ksi.ksi_signo = SIGILL; 722 ksi.ksi_code = ILL_ILLOPC; 723 ksi.ksi_trap = type; 724 ksi.ksi_addr = (void *)va; 725 trapsignal(l, &ksi); 726 break; 727 728 case T_PRIV_OP | T_USER: 729#ifdef DEBUG 730 user_backtrace(frame, l, type); 731#endif 732 KSI_INIT_TRAP(&ksi); 733 ksi.ksi_signo = SIGILL; 734 ksi.ksi_code = ILL_PRVOPC; 735 ksi.ksi_trap = type; 736 ksi.ksi_addr = (void *)va; 737 trapsignal(l, &ksi); 738 break; 739 740 case T_PRIV_REG | T_USER: 741#ifdef DEBUG 742 user_backtrace(frame, l, type); 743#endif 744 KSI_INIT_TRAP(&ksi); 745 ksi.ksi_signo = SIGILL; 746 ksi.ksi_code = ILL_PRVREG; 747 ksi.ksi_trap = type; 748 ksi.ksi_addr = (void *)va; 749 trapsignal(l, &ksi); 750 break; 751 752 /* these should never got here */ 753 case T_HIGHERPL | T_USER: 754 case T_LOWERPL | T_USER: 755 KSI_INIT_TRAP(&ksi); 756 ksi.ksi_signo = SIGSEGV; 757 ksi.ksi_code = SEGV_ACCERR; 758 ksi.ksi_trap = type; 759 ksi.ksi_addr = (void *)va; 760 trapsignal(l, &ksi); 761 break; 762 763 case T_IPROT | T_USER: 764 case T_DPROT | T_USER: 765 KSI_INIT_TRAP(&ksi); 766 ksi.ksi_signo = SIGSEGV; 767 ksi.ksi_code = SEGV_ACCERR; 768 ksi.ksi_trap = type; 769 ksi.ksi_addr = (void *)va; 770 trapsignal(l, &ksi); 771 break; 772 773 case T_DATACC: case T_USER | T_DATACC: 774 case T_ITLBMISS: case T_USER | T_ITLBMISS: 775 case T_DTLBMISS: case T_USER | T_DTLBMISS: 776 case T_ITLBMISSNA: case T_USER | T_ITLBMISSNA: 777 case T_DTLBMISSNA: case T_USER | T_DTLBMISSNA: 778 case T_TLB_DIRTY: case T_USER | T_TLB_DIRTY: 779 vm = p->p_vmspace; 780 781 if (!vm) { 782#ifdef TRAPDEBUG 783 printf("trap: no vm, p=%p\n", p); 784#endif 785 goto dead_end; 786 } 787 788 /* 789 * it could be a kernel map for exec_map faults 790 */ 791 if (!(type & T_USER) && space == HPPA_SID_KERNEL) 792 map = kernel_map; 793 else { 794 map = &vm->vm_map; 795 if (l->l_flag & L_SA) { 796 l->l_savp->savp_faultaddr = va; 797 l->l_flag |= L_SA_PAGEFAULT; 798 } 799 } 800 801 va = hppa_trunc_page(va); 802 803 if (map->pmap->pmap_space != space) { 804#ifdef TRAPDEBUG 805 printf("trap: space missmatch %d != %d\n", 806 space, map->pmap->pmap_space); 807#endif 808 /* actually dump the user, crap the kernel */ 809 goto dead_end; 810 } 811 812 /* Never call uvm_fault in interrupt context. */ 813 KASSERT(hppa_intr_depth == 0); 814 815 onfault = l->l_addr->u_pcb.pcb_onfault; 816 l->l_addr->u_pcb.pcb_onfault = 0; 817 ret = uvm_fault(map, va, 0, vftype); 818 l->l_addr->u_pcb.pcb_onfault = onfault; 819 820#ifdef TRAPDEBUG 821 printf("uvm_fault(%p, %x, %d, %d)=%d\n", 822 map, (u_int)va, 0, vftype, ret); 823#endif 824 825 if (map != kernel_map) 826 l->l_flag &= ~L_SA_PAGEFAULT; 827 828 /* 829 * If this was a stack access we keep track of the maximum 830 * accessed stack size. Also, if uvm_fault gets a protection 831 * failure it is due to accessing the stack region outside 832 * the current limit and we need to reflect that as an access 833 * error. 834 */ 835 if (va >= (vaddr_t)vm->vm_maxsaddr + vm->vm_ssize) { 836 if (ret == 0) { 837 vsize_t nss = btoc(va - USRSTACK + PAGE_SIZE); 838 if (nss > vm->vm_ssize) 839 vm->vm_ssize = nss; 840 } else if (ret == EACCES) 841 ret = EFAULT; 842 } 843 844 if (ret != 0) { 845 if (type & T_USER) { 846#ifdef DEBUG 847 user_backtrace(frame, l, type); 848#endif 849 KSI_INIT_TRAP(&ksi); 850 ksi.ksi_signo = SIGSEGV; 851 ksi.ksi_code = (ret == EACCES ? 852 SEGV_ACCERR : SEGV_MAPERR); 853 ksi.ksi_trap = type; 854 ksi.ksi_addr = (void *)va; 855 trapsignal(l, &ksi); 856 } else { 857 if (l->l_addr->u_pcb.pcb_onfault) { 858#ifdef TRAPDEBUG 859 printf("trap: copyin/out %d\n",ret); 860#endif 861 pcbp = &l->l_addr->u_pcb; 862 frame->tf_iioq_tail = 4 + 863 (frame->tf_iioq_head = 864 pcbp->pcb_onfault); 865 pcbp->pcb_onfault = 0; 866 break; 867 } 868 panic("trap: uvm_fault(%p, %lx, %d, %d): %d", 869 map, va, 0, vftype, ret); 870 } 871 } 872 break; 873 874 case T_DATALIGN | T_USER: 875#ifdef DEBUG 876 user_backtrace(frame, l, type); 877#endif 878 KSI_INIT_TRAP(&ksi); 879 ksi.ksi_signo = SIGBUS; 880 ksi.ksi_code = BUS_ADRALN; 881 ksi.ksi_trap = type; 882 ksi.ksi_addr = (void *)va; 883 trapsignal(l, &ksi); 884 break; 885 886 case T_INTERRUPT: 887 case T_INTERRUPT|T_USER: 888 hppa_intr(frame); 889 mtctl(frame->tf_eiem, CR_EIEM); 890 break; 891 892 case T_LOWERPL: 893 case T_DPROT: 894 case T_IPROT: 895 case T_OVERFLOW: 896 case T_CONDITION: 897 case T_ILLEGAL: 898 case T_HIGHERPL: 899 case T_TAKENBR: 900 case T_POWERFAIL: 901 case T_LPMC: 902 case T_PAGEREF: 903 case T_DATAPID: case T_DATAPID | T_USER: 904 if (0 /* T-chip */) { 905 break; 906 } 907 /* FALLTHROUGH to unimplemented */ 908 default: 909 panic ("trap: unimplemented \'%s\' (%d)", tts, type); 910 } 911 912 if (type & T_USER) 913 userret(l, l->l_md.md_regs->tf_iioq_head, 0); 914 915#ifdef DEBUG 916 frame_sanity_check(frame, l); 917 if (frame->tf_flags & TFF_LAST && curlwp != NULL) 918 frame_sanity_check(curlwp->l_md.md_regs, curlwp); 919#endif /* DEBUG */ 920} 921 922void 923child_return(void *arg) 924{ 925 struct lwp *l = arg; 926 struct proc *p = l->l_proc; 927 928 userret(l, l->l_md.md_regs->tf_iioq_head, 0); 929#ifdef KTRACE 930 if (KTRPOINT(p, KTR_SYSRET)) 931 ktrsysret(p, SYS_fork, 0, 0); 932#endif 933#ifdef DEBUG 934 frame_sanity_check(l->l_md.md_regs, l); 935#endif /* DEBUG */ 936} 937 938/* 939 * call actual syscall routine 940 * from the low-level syscall handler: 941 * - all HPPA_FRAME_NARGS syscall's arguments supposed to be copied onto 942 * our stack, this wins compared to copyin just needed amount anyway 943 * - register args are copied onto stack too 944 */ 945void 946syscall(struct trapframe *frame, int *args) 947{ 948 struct lwp *l; 949 struct proc *p; 950 const struct sysent *callp; 951 int nsys, code, argsize, error; 952 int tmp; 953 int rval[2]; 954 955 uvmexp.syscalls++; 956 957#ifdef DEBUG 958 frame_sanity_check(frame, curlwp); 959#endif /* DEBUG */ 960 961 if (!USERMODE(frame->tf_iioq_head)) 962 panic("syscall"); 963 964 l = curlwp; 965 p = l->l_proc; 966 l->l_md.md_regs = frame; 967 nsys = p->p_emul->e_nsysent; 968 callp = p->p_emul->e_sysent; 969 code = frame->tf_t1; 970 971 /* 972 * Restarting a system call is touchy on the HPPA, 973 * because syscall arguments are passed in registers 974 * and the program counter of the syscall "point" 975 * isn't easily divined. 976 * 977 * We handle the first problem by assuming that we 978 * will have to restart this system call, so we 979 * stuff the first four words of the original arguments 980 * back into the frame as arg0...arg3, which is where 981 * we found them in the first place. Any further 982 * arguments are (still) on the user's stack and the 983 * syscall code will fetch them from there (again). 984 * 985 * The program counter problem is addressed below. 986 */ 987 frame->tf_arg0 = args[0]; 988 frame->tf_arg1 = args[1]; 989 frame->tf_arg2 = args[2]; 990 frame->tf_arg3 = args[3]; 991 992 /* 993 * Some special handling for the syscall(2) and 994 * __syscall(2) system calls. 995 */ 996 switch (code) { 997 case SYS_syscall: 998 code = *args; 999 args += 1; 1000 break; 1001 case SYS___syscall: 1002 if (callp != sysent) 1003 break; 1004 /* 1005 * NB: even though __syscall(2) takes a quad_t 1006 * containing the system call number, because 1007 * our argument copying word-swaps 64-bit arguments, 1008 * the least significant word of that quad_t 1009 * is the first word in the argument array. 1010 */ 1011 code = *args; 1012 args += 2; 1013 } 1014 1015 /* 1016 * Stacks growing from lower addresses to higher 1017 * addresses are not really such a good idea, because 1018 * it makes it impossible to overlay a struct on top 1019 * of C stack arguments (the arguments appear in 1020 * reversed order). 1021 * 1022 * You can do the obvious thing (as locore.S does) and 1023 * copy argument words one by one, laying them out in 1024 * the "right" order in the destination buffer, but this 1025 * ends up word-swapping multi-word arguments (like off_t). 1026 * 1027 * To compensate, we have some automatically-generated 1028 * code that word-swaps these multi-word arguments. 1029 * Right now the script that generates this code is 1030 * in Perl, because I don't know awk. 1031 * 1032 * FIXME - this works only on native binaries and 1033 * will probably screw up any and all emulation. 1034 */ 1035 switch (code) { 1036 /* 1037 * BEGIN automatically generated 1038 * by /home/fredette/project/hppa/makescargfix.pl 1039 * do not edit! 1040 */ 1041 case SYS_pread: 1042 /* 1043 * syscallarg(int) fd; 1044 * syscallarg(void *) buf; 1045 * syscallarg(size_t) nbyte; 1046 * syscallarg(int) pad; 1047 * syscallarg(off_t) offset; 1048 */ 1049 tmp = args[4]; 1050 args[4] = args[4 + 1]; 1051 args[4 + 1] = tmp; 1052 break; 1053 case SYS_pwrite: 1054 /* 1055 * syscallarg(int) fd; 1056 * syscallarg(const void *) buf; 1057 * syscallarg(size_t) nbyte; 1058 * syscallarg(int) pad; 1059 * syscallarg(off_t) offset; 1060 */ 1061 tmp = args[4]; 1062 args[4] = args[4 + 1]; 1063 args[4 + 1] = tmp; 1064 break; 1065 case SYS_mmap: 1066 /* 1067 * syscallarg(void *) addr; 1068 * syscallarg(size_t) len; 1069 * syscallarg(int) prot; 1070 * syscallarg(int) flags; 1071 * syscallarg(int) fd; 1072 * syscallarg(long) pad; 1073 * syscallarg(off_t) pos; 1074 */ 1075 tmp = args[6]; 1076 args[6] = args[6 + 1]; 1077 args[6 + 1] = tmp; 1078 break; 1079 case SYS_lseek: 1080 /* 1081 * syscallarg(int) fd; 1082 * syscallarg(int) pad; 1083 * syscallarg(off_t) offset; 1084 */ 1085 tmp = args[2]; 1086 args[2] = args[2 + 1]; 1087 args[2 + 1] = tmp; 1088 break; 1089 case SYS_truncate: 1090 /* 1091 * syscallarg(const char *) path; 1092 * syscallarg(int) pad; 1093 * syscallarg(off_t) length; 1094 */ 1095 tmp = args[2]; 1096 args[2] = args[2 + 1]; 1097 args[2 + 1] = tmp; 1098 break; 1099 case SYS_ftruncate: 1100 /* 1101 * syscallarg(int) fd; 1102 * syscallarg(int) pad; 1103 * syscallarg(off_t) length; 1104 */ 1105 tmp = args[2]; 1106 args[2] = args[2 + 1]; 1107 args[2 + 1] = tmp; 1108 break; 1109 case SYS_preadv: 1110 /* 1111 * syscallarg(int) fd; 1112 * syscallarg(const struct iovec *) iovp; 1113 * syscallarg(int) iovcnt; 1114 * syscallarg(int) pad; 1115 * syscallarg(off_t) offset; 1116 */ 1117 tmp = args[4]; 1118 args[4] = args[4 + 1]; 1119 args[4 + 1] = tmp; 1120 break; 1121 case SYS_pwritev: 1122 /* 1123 * syscallarg(int) fd; 1124 * syscallarg(const struct iovec *) iovp; 1125 * syscallarg(int) iovcnt; 1126 * syscallarg(int) pad; 1127 * syscallarg(off_t) offset; 1128 */ 1129 tmp = args[4]; 1130 args[4] = args[4 + 1]; 1131 args[4 + 1] = tmp; 1132 break; 1133 default: 1134 break; 1135 /* 1136 * END automatically generated 1137 * by /home/fredette/project/hppa/makescargfix.pl 1138 * do not edit! 1139 */ 1140 } 1141 1142#ifdef USERTRACE 1143 if (0) { 1144 user_backtrace(frame, p, -1); 1145 frame->tf_ipsw |= PSW_R; 1146 frame->tf_rctr = 0; 1147 printf("r %08x", frame->tf_iioq_head); 1148 rctr_next_iioq = frame->tf_iioq_head + 4; 1149 } 1150#endif 1151 1152 if (code < 0 || code >= nsys) 1153 callp += p->p_emul->e_nosys; /* bad syscall # */ 1154 else 1155 callp += code; 1156 argsize = callp->sy_argsize; 1157 1158 if ((error = trace_enter(l, code, code, NULL, args)) != 0) 1159 goto bad; 1160 1161 rval[0] = 0; 1162 rval[1] = 0; 1163 switch (error = (*callp->sy_call)(l, args, rval)) { 1164 case 0: 1165 l = curlwp; /* changes on exec() */ 1166 frame = l->l_md.md_regs; 1167 frame->tf_ret0 = rval[0]; 1168 frame->tf_ret1 = rval[1]; 1169 frame->tf_t1 = 0; 1170 break; 1171 case ERESTART: 1172 /* 1173 * Now we have to wind back the instruction 1174 * offset queue to the point where the system 1175 * call will be made again. This is inherently 1176 * tied to the SYSCALL macro. 1177 * 1178 * Currently, the part of the SYSCALL macro 1179 * that we want to rerun reads as: 1180 * 1181 * ldil L%SYSCALLGATE, r1 1182 * ble 4(sr7, r1) 1183 * ldi __CONCAT(SYS_,x), t1 1184 * ldw HPPA_FRAME_ERP(sr0,sp), rp 1185 * 1186 * And our offset queue head points to the 1187 * final ldw instruction. So we need to 1188 * subtract twelve to reach the ldil. 1189 */ 1190 frame->tf_iioq_head -= 12; 1191 frame->tf_iioq_tail = frame->tf_iioq_head + 4; 1192 break; 1193 case EJUSTRETURN: 1194 p = curproc; 1195 break; 1196 default: 1197 bad: 1198 if (p->p_emul->e_errno) 1199 error = p->p_emul->e_errno[error]; 1200 frame->tf_t1 = error; 1201 break; 1202 } 1203 1204 trace_exit(l, code, args, rval, error); 1205 1206 userret(l, frame->tf_iioq_head, 0); 1207#ifdef DEBUG 1208 frame_sanity_check(frame, l); 1209#endif /* DEBUG */ 1210} 1211 1212/* 1213 * Start a new LWP 1214 */ 1215void 1216startlwp(void *arg) 1217{ 1218 int err; 1219 ucontext_t *uc = arg; 1220 struct lwp *l = curlwp; 1221 1222 err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); 1223#if DIAGNOSTIC 1224 if (err) { 1225 printf("Error %d from cpu_setmcontext.", err); 1226 } 1227#endif 1228 pool_put(&lwp_uc_pool, uc); 1229 1230 userret(l, l->l_md.md_regs->tf_iioq_head, 0); 1231} 1232 1233/* 1234 * XXX This is a terrible name. 1235 */ 1236void 1237upcallret(struct lwp *l) 1238{ 1239 userret(l, l->l_md.md_regs->tf_iioq_head, 0); 1240} 1241