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