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