1 /* $NetBSD: trap.c,v 1.7 2002/10/20 02:37:23 chs Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1982, 1986, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * from: Utah $Hdr: trap.c 1.37 92/12/20$ 41 * 42 * @(#)trap.c 8.5 (Berkeley) 1/4/94 43 */ 44 45 #include "opt_ddb.h" 46 #include "opt_execfmt.h" 47 #include "opt_kgdb.h" 48 #include "opt_ktrace.h" 49 #include "opt_compat_netbsd.h" 50 #include "opt_compat_sunos.h" 51 #include "opt_compat_hpux.h" 52 #include "opt_compat_linux.h" 53 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/proc.h> 57 #include <sys/acct.h> 58 #include <sys/kernel.h> 59 #include <sys/signalvar.h> 60 #include <sys/resourcevar.h> 61 #include <sys/syscall.h> 62 #include <sys/syslog.h> 63 #include <sys/user.h> 64 #ifdef KTRACE 65 #include <sys/ktrace.h> 66 #endif 67 #ifdef KGDB 68 #include <sys/kgdb.h> 69 #endif 70 71 #include <m68k/frame.h> 72 #include <m68k/cacheops.h> 73 74 #include <machine/db_machdep.h> 75 #include <machine/psl.h> 76 #include <machine/trap.h> 77 #include <machine/cpu.h> 78 #include <machine/reg.h> 79 80 #include <uvm/uvm_extern.h> 81 82 #include <dev/cons.h> 83 84 #ifdef COMPAT_HPUX 85 #include <compat/hpux/hpux.h> 86 extern struct emul emul_hpux; 87 #endif 88 89 #ifdef COMPAT_SUNOS 90 #include <compat/sunos/sunos_syscall.h> 91 extern struct emul emul_sunos; 92 #endif 93 94 int writeback __P((struct frame *fp, int docachepush)); 95 void trap __P((int type, u_int code, u_int v, struct frame frame)); 96 void syscall __P((register_t code, struct frame frame)); 97 void trap_kdebug __P((int, struct trapframe)); 98 99 #ifdef DEBUG 100 void dumpssw __P((u_short)); 101 void dumpwb __P((int, u_short, u_int, u_int)); 102 #endif 103 104 static inline void userret __P((struct proc *p, struct frame *fp, 105 u_quad_t oticks, u_int faultaddr, int fromtrap)); 106 107 int astpending; 108 109 char *trap_type[] = { 110 "Bus error", 111 "Address error", 112 "Illegal instruction", 113 "Zero divide", 114 "CHK instruction", 115 "TRAPV instruction", 116 "Privilege violation", 117 "Trace trap", 118 "MMU fault", 119 "SSIR trap", 120 "Format error", 121 "68881 exception", 122 "Coprocessor violation", 123 "Async system trap" 124 }; 125 int trap_types = sizeof trap_type / sizeof trap_type[0]; 126 127 /* 128 * Size of various exception stack frames (minus the standard 8 bytes) 129 */ 130 short exframesize[] = { 131 FMT0SIZE, /* type 0 - normal (68020/030/040/060) */ 132 FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ 133 FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */ 134 FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */ 135 FMT4SIZE, /* type 4 - access error/fp disabled (68060) */ 136 -1, -1, /* type 5-6 - undefined */ 137 FMT7SIZE, /* type 7 - access error (68040) */ 138 58, /* type 8 - bus fault (68010) */ 139 FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ 140 FMTASIZE, /* type A - short bus fault (68020/030) */ 141 FMTBSIZE, /* type B - long bus fault (68020/030) */ 142 -1, -1, -1, -1 /* type C-F - undefined */ 143 }; 144 145 #ifdef M68060 146 #define KDFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_TM_SV)) 147 #define WRFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_RW_W)) 148 #else 149 #define KDFAULT_060(c) 0 150 #define WRFAULT_060(c) 0 151 #endif 152 153 #ifdef M68040 154 #define KDFAULT_040(c) (cputype == CPU_68040 && \ 155 ((c) & SSW4_TMMASK) == SSW4_TMKD) 156 #define WRFAULT_040(c) (cputype == CPU_68040 && \ 157 ((c) & SSW4_RW) == 0) 158 #else 159 #define KDFAULT_040(c) 0 160 #define WRFAULT_040(c) 0 161 #endif 162 163 #if defined(M68030) || defined(M68020) 164 #define KDFAULT_OTH(c) (cputype <= CPU_68030 && \ 165 ((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD)) 166 #define WRFAULT_OTH(c) (cputype <= CPU_68030 && \ 167 ((c) & (SSW_DF|SSW_RW)) == SSW_DF) 168 #else 169 #define KDFAULT_OTH(c) 0 170 #define WRFAULT_OTH(c) 0 171 #endif 172 173 #define KDFAULT(c) (KDFAULT_060(c) || KDFAULT_040(c) || KDFAULT_OTH(c)) 174 #define WRFAULT(c) (WRFAULT_060(c) || WRFAULT_040(c) || WRFAULT_OTH(c)) 175 176 #ifdef DEBUG 177 int mmudebug = 0; 178 int mmupid = -1; 179 #define MDB_FOLLOW 1 180 #define MDB_WBFOLLOW 2 181 #define MDB_WBFAILED 4 182 #define MDB_ISPID(p) ((p) == mmupid) 183 #endif 184 185 /* 186 * trap and syscall both need the following work done before returning 187 * to user mode. 188 */ 189 static inline void 190 userret(p, fp, oticks, faultaddr, fromtrap) 191 struct proc *p; 192 struct frame *fp; 193 u_quad_t oticks; 194 u_int faultaddr; 195 int fromtrap; 196 { 197 int sig; 198 #ifdef M68040 199 int beenhere = 0; 200 201 again: 202 #endif 203 /* take pending signals */ 204 while ((sig = CURSIG(p)) != 0) 205 postsig(sig); 206 p->p_priority = p->p_usrpri; 207 if (want_resched) { 208 /* 209 * We are being preempted. 210 */ 211 preempt(NULL); 212 while ((sig = CURSIG(p)) != 0) 213 postsig(sig); 214 } 215 216 /* 217 * If profiling, charge system time to the trapped pc. 218 */ 219 if (p->p_flag & P_PROFIL) { 220 extern int psratio; 221 222 addupc_task(p, fp->f_pc, 223 (int)(p->p_sticks - oticks) * psratio); 224 } 225 #ifdef M68040 226 /* 227 * Deal with user mode writebacks (from trap, or from sigreturn). 228 * If any writeback fails, go back and attempt signal delivery. 229 * unless we have already been here and attempted the writeback 230 * (e.g. bad address with user ignoring SIGSEGV). In that case 231 * we just return to the user without sucessfully completing 232 * the writebacks. Maybe we should just drop the sucker? 233 */ 234 if (cputype == CPU_68040 && fp->f_format == FMT7) { 235 if (beenhere) { 236 #ifdef DEBUG 237 if (mmudebug & MDB_WBFAILED) 238 printf(fromtrap ? 239 "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" : 240 "pid %d(%s): writeback aborted in sigreturn, pc=%x\n", 241 p->p_pid, p->p_comm, fp->f_pc, faultaddr); 242 #endif 243 } else if ((sig = writeback(fp, fromtrap))) { 244 beenhere = 1; 245 oticks = p->p_sticks; 246 trapsignal(p, sig, faultaddr); 247 goto again; 248 } 249 } 250 #endif 251 curcpu()->ci_schedstate.spc_curpriority = p->p_priority; 252 } 253 254 /* 255 * Used by the common m68k syscall() and child_return() functions. 256 * XXX: Temporary until all m68k ports share common trap()/userret() code. 257 */ 258 void machine_userret(struct proc *, struct frame *, u_quad_t); 259 260 void 261 machine_userret(p, f, t) 262 struct proc *p; 263 struct frame *f; 264 u_quad_t t; 265 { 266 267 userret(p, f, t, 0, 0); 268 } 269 270 /* 271 * Trap is called from locore to handle most types of processor traps, 272 * including events such as simulated software interrupts/AST's. 273 * System calls are broken out for efficiency. 274 */ 275 /*ARGSUSED*/ 276 void 277 trap(type, code, v, frame) 278 int type; 279 unsigned code; 280 unsigned v; 281 struct frame frame; 282 { 283 extern char fubail[], subail[]; 284 struct proc *p; 285 int i, s; 286 u_int ucode; 287 u_quad_t sticks = 0 /* XXX initializer works around compiler bug */; 288 289 uvmexp.traps++; 290 p = curproc; 291 ucode = 0; 292 293 /* I have verified that this DOES happen! -gwr */ 294 if (p == NULL) 295 p = &proc0; 296 #ifdef DIAGNOSTIC 297 if (p->p_addr == NULL) 298 panic("trap: no pcb"); 299 #endif 300 301 if (USERMODE(frame.f_sr)) { 302 type |= T_USER; 303 sticks = p->p_sticks; 304 p->p_md.md_regs = frame.f_regs; 305 } 306 switch (type) { 307 308 default: 309 dopanic: 310 printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); 311 printf("%s program counter = 0x%x\n", 312 (type & T_USER) ? "user" : "kernel", frame.f_pc); 313 /* 314 * Let the kernel debugger see the trap frame that 315 * caused us to panic. This is a convenience so 316 * one can see registers at the point of failure. 317 */ 318 s = splhigh(); 319 #ifdef KGDB 320 /* If connected, step or cont returns 1 */ 321 if (kgdb_trap(type, &frame)) 322 goto kgdb_cont; 323 #endif 324 #ifdef DDB 325 (void)kdb_trap(type, (db_regs_t *)&frame); 326 #endif 327 #ifdef KGDB 328 kgdb_cont: 329 #endif 330 splx(s); 331 if (panicstr) { 332 printf("trap during panic!\n"); 333 #ifdef DEBUG 334 /* XXX should be a machine-dependent hook */ 335 printf("(press a key)\n"); (void)cngetc(); 336 #endif 337 } 338 regdump((struct trapframe *)&frame, 128); 339 type &= ~T_USER; 340 if ((u_int)type < trap_types) 341 panic(trap_type[type]); 342 panic("trap"); 343 344 case T_BUSERR: /* kernel bus error */ 345 if (p->p_addr->u_pcb.pcb_onfault == 0) 346 goto dopanic; 347 /* FALLTHROUGH */ 348 349 copyfault: 350 /* 351 * If we have arranged to catch this fault in any of the 352 * copy to/from user space routines, set PC to return to 353 * indicated location and set flag informing buserror code 354 * that it may need to clean up stack frame. 355 */ 356 frame.f_stackadj = exframesize[frame.f_format]; 357 frame.f_format = frame.f_vector = 0; 358 frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 359 return; 360 361 case T_BUSERR|T_USER: /* bus error */ 362 case T_ADDRERR|T_USER: /* address error */ 363 ucode = v; 364 i = SIGBUS; 365 break; 366 367 case T_COPERR: /* kernel coprocessor violation */ 368 case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ 369 case T_FMTERR: /* ...just in case... */ 370 /* 371 * The user has most likely trashed the RTE or FP state info 372 * in the stack frame of a signal handler. 373 */ 374 printf("pid %d: kernel %s exception\n", p->p_pid, 375 type==T_COPERR ? "coprocessor" : "format"); 376 type |= T_USER; 377 SIGACTION(p, SIGILL).sa_handler = SIG_DFL; 378 sigdelset(&p->p_sigctx.ps_sigignore, SIGILL); 379 sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL); 380 sigdelset(&p->p_sigctx.ps_sigmask, SIGILL); 381 i = SIGILL; 382 ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 383 break; 384 385 case T_COPERR|T_USER: /* user coprocessor violation */ 386 /* What is a proper response here? */ 387 ucode = 0; 388 i = SIGFPE; 389 break; 390 391 case T_FPERR|T_USER: /* 68881 exceptions */ 392 /* 393 * We pass along the 68881 status which locore stashed 394 * in code for us. Note that there is a possibility that the 395 * bit pattern of this will conflict with one of the 396 * FPE_* codes defined in signal.h. Fortunately for us, the 397 * only such codes we use are all in the range 1-7 and the low 398 * 3 bits of the status are defined as 0 so there is 399 * no clash. 400 */ 401 ucode = code; 402 i = SIGFPE; 403 break; 404 405 #ifdef M68040 406 case T_FPEMULI|T_USER: /* unimplemented FP instuction */ 407 case T_FPEMULD|T_USER: /* unimplemented FP data type */ 408 /* XXX need to FSAVE */ 409 printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", 410 p->p_pid, p->p_comm, 411 frame.f_format == 2 ? "instruction" : "data type", 412 frame.f_pc, frame.f_fmt2.f_iaddr); 413 /* XXX need to FRESTORE */ 414 i = SIGFPE; 415 break; 416 #endif 417 418 case T_ILLINST|T_USER: /* illegal instruction fault */ 419 #ifdef COMPAT_HPUX 420 if (p->p_emul == &emul_hpux) { 421 ucode = HPUX_ILL_ILLINST_TRAP; 422 i = SIGILL; 423 break; 424 } 425 /* fall through */ 426 #endif 427 case T_PRIVINST|T_USER: /* privileged instruction fault */ 428 #ifdef COMPAT_HPUX 429 if (p->p_emul == &emul_hpux) 430 ucode = HPUX_ILL_PRIV_TRAP; 431 else 432 #endif 433 ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 434 i = SIGILL; 435 break; 436 437 case T_ZERODIV|T_USER: /* Divide by zero */ 438 #ifdef COMPAT_HPUX 439 if (p->p_emul == &emul_hpux) 440 ucode = HPUX_FPE_INTDIV_TRAP; 441 else 442 #endif 443 ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 444 i = SIGFPE; 445 break; 446 447 case T_CHKINST|T_USER: /* CHK instruction trap */ 448 #ifdef COMPAT_HPUX 449 if (p->p_emul == &emul_hpux) { 450 /* handled differently under hp-ux */ 451 i = SIGILL; 452 ucode = HPUX_ILL_CHK_TRAP; 453 break; 454 } 455 #endif 456 ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 457 i = SIGFPE; 458 break; 459 460 case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ 461 #ifdef COMPAT_HPUX 462 if (p->p_emul == &emul_hpux) { 463 /* handled differently under hp-ux */ 464 i = SIGILL; 465 ucode = HPUX_ILL_TRAPV_TRAP; 466 break; 467 } 468 #endif 469 ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 470 i = SIGFPE; 471 break; 472 473 /* 474 * XXX: Trace traps are a nightmare. 475 * 476 * HP-UX uses trap #1 for breakpoints, 477 * NetBSD/m68k uses trap #2, 478 * SUN 3.x uses trap #15, 479 * DDB and KGDB uses trap #15 (for kernel breakpoints; 480 * handled elsewhere). 481 * 482 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 483 * SUN 3.x traps get passed through as T_TRAP15 and are not really 484 * supported yet. 485 * 486 * XXX: We should never get kernel-mode T_TRACE or T_TRAP15 487 * XXX: because locore.s now gives them special treatment. 488 */ 489 case T_TRACE: /* kernel trace trap */ 490 case T_TRAP15: /* kernel breakpoint */ 491 #ifdef DEBUG 492 printf("unexpected kernel trace trap, type = %d\n", type); 493 printf("program counter = 0x%x\n", frame.f_pc); 494 #endif 495 frame.f_sr &= ~PSL_T; 496 return; 497 498 case T_TRACE|T_USER: /* user trace trap */ 499 case T_TRAP15|T_USER: /* SUN user trace trap */ 500 #ifdef COMPAT_SUNOS 501 /* 502 * SunOS uses Trap #2 for a "CPU cache flush". 503 * Just flush the on-chip caches and return. 504 */ 505 if (p->p_emul == &emul_sunos) { 506 ICIA(); 507 DCIU(); 508 return; 509 } 510 #endif 511 frame.f_sr &= ~PSL_T; 512 i = SIGTRAP; 513 break; 514 515 case T_ASTFLT: /* system async trap, cannot happen */ 516 goto dopanic; 517 518 case T_ASTFLT|T_USER: /* user async trap */ 519 astpending = 0; 520 /* 521 * We check for software interrupts first. This is because 522 * they are at a higher level than ASTs, and on a VAX would 523 * interrupt the AST. We assume that if we are processing 524 * an AST that we must be at IPL0 so we don't bother to 525 * check. Note that we ensure that we are at least at SIR 526 * IPL while processing the SIR. 527 */ 528 spl1(); 529 /* fall into... */ 530 531 case T_SSIR: /* software interrupt */ 532 case T_SSIR|T_USER: 533 if (ssir & SIR_NET) { 534 void netintr __P((void)); 535 siroff(SIR_NET); 536 uvmexp.softs++; 537 netintr(); 538 } 539 if (ssir & SIR_CLOCK) { 540 siroff(SIR_CLOCK); 541 uvmexp.softs++; 542 softclock(NULL); 543 } 544 if (ssir & SIR_ZS) { 545 siroff(SIR_ZS); 546 uvmexp.softs++; 547 softzs(); 548 } 549 /* 550 * If this was not an AST trap, we are all done. 551 */ 552 if (type != (T_ASTFLT|T_USER)) { 553 uvmexp.traps--; 554 return; 555 } 556 spl0(); 557 if (p->p_flag & P_OWEUPC) { 558 p->p_flag &= ~P_OWEUPC; 559 ADDUPROF(p); 560 } 561 goto out; 562 563 case T_MMUFLT: /* kernel mode page fault */ 564 /* 565 * If we were doing profiling ticks or other user mode 566 * stuff from interrupt code, Just Say No. 567 */ 568 if (p->p_addr->u_pcb.pcb_onfault == fubail || 569 p->p_addr->u_pcb.pcb_onfault == subail) 570 goto copyfault; 571 /* fall into ... */ 572 573 case T_MMUFLT|T_USER: /* page fault */ 574 { 575 vaddr_t va; 576 struct vmspace *vm = p->p_vmspace; 577 struct vm_map *map; 578 int rv; 579 vm_prot_t ftype; 580 extern struct vm_map *kernel_map; 581 582 #ifdef DEBUG 583 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 584 printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", 585 p->p_pid, code, v, frame.f_pc, frame.f_sr); 586 #endif 587 /* 588 * It is only a kernel address space fault iff: 589 * 1. (type & T_USER) == 0 and 590 * 2. pcb_onfault not set or 591 * 3. pcb_onfault set but supervisor space data fault 592 * The last can occur during an exec() copyin where the 593 * argument space is lazy-allocated. 594 */ 595 if ((type & T_USER) == 0 && 596 ((p->p_addr->u_pcb.pcb_onfault == 0) || KDFAULT(code))) 597 map = kernel_map; 598 else 599 map = vm ? &vm->vm_map : kernel_map; 600 601 if (WRFAULT(code)) 602 ftype = VM_PROT_WRITE; 603 else 604 ftype = VM_PROT_READ; 605 606 va = trunc_page((vaddr_t)v); 607 608 if (map == kernel_map && va == 0) { 609 printf("trap: bad kernel %s access at 0x%x\n", 610 (ftype & VM_PROT_WRITE) ? "read/write" : 611 "read", v); 612 goto dopanic; 613 } 614 615 #ifdef COMPAT_HPUX 616 if (ISHPMMADDR(va)) { 617 int pmap_mapmulti __P((pmap_t, vaddr_t)); 618 vaddr_t bva; 619 620 rv = pmap_mapmulti(map->pmap, va); 621 if (rv != 0) { 622 bva = HPMMBASEADDR(va); 623 rv = uvm_fault(map, bva, 0, ftype); 624 if (rv == 0) 625 (void) pmap_mapmulti(map->pmap, va); 626 } 627 } else 628 #endif 629 rv = uvm_fault(map, va, 0, ftype); 630 #ifdef DEBUG 631 if (rv && MDB_ISPID(p->p_pid)) 632 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 633 map, va, ftype, rv); 634 #endif 635 /* 636 * If this was a stack access we keep track of the maximum 637 * accessed stack size. Also, if vm_fault gets a protection 638 * failure it is due to accessing the stack region outside 639 * the current limit and we need to reflect that as an access 640 * error. 641 */ 642 if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr) 643 && map != kernel_map) { 644 if (rv == 0) { 645 unsigned nss; 646 647 nss = btoc(USRSTACK-(unsigned)va); 648 if (nss > vm->vm_ssize) 649 vm->vm_ssize = nss; 650 } else if (rv == EACCES) 651 rv = EFAULT; 652 } 653 if (rv == 0) { 654 if (type == T_MMUFLT) { 655 #ifdef M68040 656 if (cputype == CPU_68040) 657 (void) writeback(&frame, 1); 658 #endif 659 return; 660 } 661 goto out; 662 } 663 if (type == T_MMUFLT) { 664 if (p->p_addr->u_pcb.pcb_onfault) 665 goto copyfault; 666 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 667 map, va, ftype, rv); 668 printf(" type %x, code [mmu,,ssw]: %x\n", 669 type, code); 670 goto dopanic; 671 } 672 ucode = v; 673 if (rv == ENOMEM) { 674 printf("UVM: pid %d (%s), uid %d killed: out of swap\n", 675 p->p_pid, p->p_comm, 676 p->p_cred && p->p_ucred ? 677 p->p_ucred->cr_uid : -1); 678 i = SIGKILL; 679 } else { 680 i = SIGSEGV; 681 } 682 break; 683 } 684 } 685 trapsignal(p, i, ucode); 686 if ((type & T_USER) == 0) 687 return; 688 out: 689 userret(p, &frame, sticks, v, 1); 690 } 691 692 #ifdef M68040 693 #ifdef DEBUG 694 struct writebackstats { 695 int calls; 696 int cpushes; 697 int move16s; 698 int wb1s, wb2s, wb3s; 699 int wbsize[4]; 700 } wbstats; 701 702 char *f7sz[] = { "longword", "byte", "word", "line" }; 703 char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 704 char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 705 "M-code", "k-data", "k-code", "RES" }; 706 char wberrstr[] = 707 "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 708 #endif 709 710 int 711 writeback(fp, docachepush) 712 struct frame *fp; 713 int docachepush; 714 { 715 struct fmt7 *f = &fp->f_fmt7; 716 struct proc *p = curproc; 717 int err = 0; 718 u_int fa; 719 caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault; 720 paddr_t pa; 721 722 #ifdef DEBUG 723 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 724 printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 725 dumpssw(f->f_ssw); 726 } 727 wbstats.calls++; 728 #endif 729 /* 730 * Deal with special cases first. 731 */ 732 if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 733 /* 734 * Dcache push fault. 735 * Line-align the address and write out the push data to 736 * the indicated physical address. 737 */ 738 #ifdef DEBUG 739 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 740 printf(" pushing %s to PA %x, data %x", 741 f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 742 f->f_fa, f->f_pd0); 743 if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 744 printf("/%x/%x/%x", 745 f->f_pd1, f->f_pd2, f->f_pd3); 746 printf("\n"); 747 } 748 if (f->f_wb1s & SSW4_WBSV) 749 panic("writeback: cache push with WB1S valid"); 750 wbstats.cpushes++; 751 #endif 752 /* 753 * XXX there are security problems if we attempt to do a 754 * cache push after a signal handler has been called. 755 */ 756 if (docachepush) { 757 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, 758 trunc_page(f->f_fa), VM_PROT_WRITE, 759 VM_PROT_WRITE|PMAP_WIRED); 760 pmap_update(pmap_kernel()); 761 fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 762 bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 763 pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa); 764 DCFL(pa); 765 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, 766 (vaddr_t)&vmmap[NBPG]); 767 pmap_update(pmap_kernel()); 768 } else 769 printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 770 p->p_pid, p->p_comm, p->p_ucred->cr_uid); 771 } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 772 /* 773 * MOVE16 fault. 774 * Line-align the address and write out the push data to 775 * the indicated virtual address. 776 */ 777 #ifdef DEBUG 778 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 779 printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 780 f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 781 f->f_pd2, f->f_pd3); 782 if (f->f_wb1s & SSW4_WBSV) 783 panic("writeback: MOVE16 with WB1S valid"); 784 wbstats.move16s++; 785 #endif 786 if (KDFAULT(f->f_wb1s)) 787 bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 788 else 789 err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 790 if (err) { 791 fa = f->f_fa & ~0xF; 792 #ifdef DEBUG 793 if (mmudebug & MDB_WBFAILED) 794 printf(wberrstr, p->p_pid, p->p_comm, 795 "MOVE16", fp->f_pc, f->f_fa, 796 f->f_fa & ~0xF, f->f_pd0); 797 #endif 798 } 799 } else if (f->f_wb1s & SSW4_WBSV) { 800 /* 801 * Writeback #1. 802 * Position the "memory-aligned" data and write it out. 803 */ 804 u_int wb1d = f->f_wb1d; 805 int off; 806 807 #ifdef DEBUG 808 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 809 dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 810 wbstats.wb1s++; 811 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 812 #endif 813 off = (f->f_wb1a & 3) * 8; 814 switch (f->f_wb1s & SSW4_SZMASK) { 815 case SSW4_SZLW: 816 if (off) 817 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 818 if (KDFAULT(f->f_wb1s)) 819 *(long *)f->f_wb1a = wb1d; 820 else 821 err = suword((caddr_t)f->f_wb1a, wb1d); 822 break; 823 case SSW4_SZB: 824 off = 24 - off; 825 if (off) 826 wb1d >>= off; 827 if (KDFAULT(f->f_wb1s)) 828 *(char *)f->f_wb1a = wb1d; 829 else 830 err = subyte((caddr_t)f->f_wb1a, wb1d); 831 break; 832 case SSW4_SZW: 833 off = (off + 16) % 32; 834 if (off) 835 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 836 if (KDFAULT(f->f_wb1s)) 837 *(short *)f->f_wb1a = wb1d; 838 else 839 err = susword((caddr_t)f->f_wb1a, wb1d); 840 break; 841 } 842 if (err) { 843 fa = f->f_wb1a; 844 #ifdef DEBUG 845 if (mmudebug & MDB_WBFAILED) 846 printf(wberrstr, p->p_pid, p->p_comm, 847 "#1", fp->f_pc, f->f_fa, 848 f->f_wb1a, f->f_wb1d); 849 #endif 850 } 851 } 852 /* 853 * Deal with the "normal" writebacks. 854 * 855 * XXX writeback2 is known to reflect a LINE size writeback after 856 * a MOVE16 was already dealt with above. Ignore it. 857 */ 858 if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 859 (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 860 #ifdef DEBUG 861 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 862 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 863 wbstats.wb2s++; 864 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 865 #endif 866 switch (f->f_wb2s & SSW4_SZMASK) { 867 case SSW4_SZLW: 868 if (KDFAULT(f->f_wb2s)) 869 *(long *)f->f_wb2a = f->f_wb2d; 870 else 871 err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 872 break; 873 case SSW4_SZB: 874 if (KDFAULT(f->f_wb2s)) 875 *(char *)f->f_wb2a = f->f_wb2d; 876 else 877 err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 878 break; 879 case SSW4_SZW: 880 if (KDFAULT(f->f_wb2s)) 881 *(short *)f->f_wb2a = f->f_wb2d; 882 else 883 err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 884 break; 885 } 886 if (err) { 887 fa = f->f_wb2a; 888 #ifdef DEBUG 889 if (mmudebug & MDB_WBFAILED) { 890 printf(wberrstr, p->p_pid, p->p_comm, 891 "#2", fp->f_pc, f->f_fa, 892 f->f_wb2a, f->f_wb2d); 893 dumpssw(f->f_ssw); 894 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 895 } 896 #endif 897 } 898 } 899 if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 900 #ifdef DEBUG 901 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 902 dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 903 wbstats.wb3s++; 904 wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 905 #endif 906 switch (f->f_wb3s & SSW4_SZMASK) { 907 case SSW4_SZLW: 908 if (KDFAULT(f->f_wb3s)) 909 *(long *)f->f_wb3a = f->f_wb3d; 910 else 911 err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 912 break; 913 case SSW4_SZB: 914 if (KDFAULT(f->f_wb3s)) 915 *(char *)f->f_wb3a = f->f_wb3d; 916 else 917 err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 918 break; 919 case SSW4_SZW: 920 if (KDFAULT(f->f_wb3s)) 921 *(short *)f->f_wb3a = f->f_wb3d; 922 else 923 err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 924 break; 925 #ifdef DEBUG 926 case SSW4_SZLN: 927 panic("writeback: wb3s indicates LINE write"); 928 #endif 929 } 930 if (err) { 931 fa = f->f_wb3a; 932 #ifdef DEBUG 933 if (mmudebug & MDB_WBFAILED) 934 printf(wberrstr, p->p_pid, p->p_comm, 935 "#3", fp->f_pc, f->f_fa, 936 f->f_wb3a, f->f_wb3d); 937 #endif 938 } 939 } 940 p->p_addr->u_pcb.pcb_onfault = oonfault; 941 if (err) 942 err = SIGSEGV; 943 return (err); 944 } 945 946 #ifdef DEBUG 947 void 948 dumpssw(ssw) 949 u_short ssw; 950 { 951 printf(" SSW: %x: ", ssw); 952 if (ssw & SSW4_CP) 953 printf("CP,"); 954 if (ssw & SSW4_CU) 955 printf("CU,"); 956 if (ssw & SSW4_CT) 957 printf("CT,"); 958 if (ssw & SSW4_CM) 959 printf("CM,"); 960 if (ssw & SSW4_MA) 961 printf("MA,"); 962 if (ssw & SSW4_ATC) 963 printf("ATC,"); 964 if (ssw & SSW4_LK) 965 printf("LK,"); 966 if (ssw & SSW4_RW) 967 printf("RW,"); 968 printf(" SZ=%s, TT=%s, TM=%s\n", 969 f7sz[(ssw & SSW4_SZMASK) >> 5], 970 f7tt[(ssw & SSW4_TTMASK) >> 3], 971 f7tm[ssw & SSW4_TMMASK]); 972 } 973 974 void 975 dumpwb(num, s, a, d) 976 int num; 977 u_short s; 978 u_int a, d; 979 { 980 struct proc *p = curproc; 981 paddr_t pa; 982 983 printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 984 num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 985 f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 986 printf(" PA "); 987 if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == FALSE) 988 printf("<invalid address>"); 989 else 990 printf("%lx, current value %lx", pa, fuword((caddr_t)a)); 991 printf("\n"); 992 } 993 #endif 994 #endif 995 996 /* 997 * This is called by locore for supervisor-mode trace and 998 * breakpoint traps. This is separate from trap() above 999 * so that breakpoints in trap() will work. 1000 * 1001 * If we have both DDB and KGDB, let KGDB see it first, 1002 * because KGDB will just return 0 if not connected. 1003 */ 1004 void 1005 trap_kdebug(type, tf) 1006 int type; 1007 struct trapframe tf; 1008 { 1009 #ifdef KGDB 1010 /* Let KGDB handle it (if connected) */ 1011 if (kgdb_trap(type, &tf)) 1012 return; 1013 #endif 1014 #ifdef DDB 1015 /* Let DDB handle it. */ 1016 if (kdb_trap(type, &tf)) 1017 return; 1018 #endif 1019 1020 panic("unexpected BPT trap"); 1021 } 1022