trap.c revision 1.60
1/* $NetBSD: trap.c,v 1.60 2006/07/19 21:11:44 ad 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.60 2006/07/19 21:11:44 ad 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 LWP_CACHE_CREDS(l, p); 343 } 344 switch (type) { 345 346 default: 347 dopanic: 348 /* 349 * Let the kernel debugger see the trap frame that 350 * caused us to panic. This is a convenience so 351 * one can see registers at the point of failure. 352 */ 353 s = splhigh(); 354 panicking = 1; 355 printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); 356 printf("%s program counter = 0x%x\n", 357 (type & T_USER) ? "user" : "kernel", frame.f_pc); 358#ifdef KGDB 359 /* If connected, step or cont returns 1 */ 360 if (kgdb_trap(type, (db_regs_t *)&frame)) 361 goto kgdb_cont; 362#endif 363#ifdef DDB 364 (void)kdb_trap(type, (db_regs_t *)&frame); 365#endif 366#ifdef KGDB 367 kgdb_cont: 368#endif 369 splx(s); 370 if (panicstr) { 371 printf("trap during panic!\n"); 372#ifdef DEBUG 373 /* XXX should be a machine-dependent hook */ 374 printf("(press a key)\n"); (void)cngetc(); 375#endif 376 } 377 regdump((struct trapframe *)&frame, 128); 378 type &= ~T_USER; 379 if ((u_int)type < trap_types) 380 panic(trap_type[type]); 381 panic("trap"); 382 383 case T_BUSERR: /* kernel bus error */ 384 if (l->l_addr->u_pcb.pcb_onfault == 0) 385 goto dopanic; 386 /* FALLTHROUGH */ 387 388 copyfault: 389 /* 390 * If we have arranged to catch this fault in any of the 391 * copy to/from user space routines, set PC to return to 392 * indicated location and set flag informing buserror code 393 * that it may need to clean up stack frame. 394 */ 395 frame.f_stackadj = exframesize[frame.f_format]; 396 frame.f_format = frame.f_vector = 0; 397 frame.f_pc = (int) l->l_addr->u_pcb.pcb_onfault; 398 return; 399 400 case T_BUSERR|T_USER: /* bus error */ 401 case T_ADDRERR|T_USER: /* address error */ 402 ksi.ksi_addr = (void *)v; 403 ksi.ksi_signo = SIGBUS; 404 ksi.ksi_code = (type == (T_BUSERR|T_USER)) ? 405 BUS_OBJERR : BUS_ADRERR; 406 break; 407 408 case T_COPERR: /* kernel coprocessor violation */ 409 case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ 410 case T_FMTERR: /* ...just in case... */ 411 /* 412 * The user has most likely trashed the RTE or FP state info 413 * in the stack frame of a signal handler. 414 */ 415 printf("pid %d: kernel %s exception\n", p->p_pid, 416 type==T_COPERR ? "coprocessor" : "format"); 417 type |= T_USER; 418 SIGACTION(p, SIGILL).sa_handler = SIG_DFL; 419 sigdelset(&p->p_sigctx.ps_sigignore, SIGILL); 420 sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL); 421 sigdelset(&p->p_sigctx.ps_sigmask, SIGILL); 422 ksi.ksi_signo = SIGILL; 423 ksi.ksi_addr = (void *)(int)frame.f_format; 424 /* XXX was ILL_RESAD_FAULT */ 425 ksi.ksi_code = (type == T_COPERR) ? 426 ILL_COPROC : ILL_ILLOPC; 427 break; 428 429 case T_COPERR|T_USER: /* user coprocessor violation */ 430 /* What is a proper response here? */ 431 ksi.ksi_signo = SIGFPE; 432 ksi.ksi_code = FPE_FLTINV; 433 break; 434 435 case T_FPERR|T_USER: /* 68881 exceptions */ 436 /* 437 * We pass along the 68881 status register which locore stashed 438 * in code for us. Note that there is a possibility that the 439 * bit pattern of this register will conflict with one of the 440 * FPE_* codes defined in signal.h. Fortunately for us, the 441 * only such codes we use are all in the range 1-7 and the low 442 * 3 bits of the status register are defined as 0 so there is 443 * no clash. 444 */ 445 ksi.ksi_signo = SIGFPE; 446 ksi.ksi_addr = (void *)code; 447 break; 448 449#ifdef M68040 450 case T_FPEMULI|T_USER: /* unimplemented FP instruction */ 451 case T_FPEMULD|T_USER: /* unimplemented FP data type */ 452 /* XXX need to FSAVE */ 453 printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", 454 p->p_pid, p->p_comm, 455 frame.f_format == 2 ? "instruction" : "data type", 456 frame.f_pc, frame.f_fmt2.f_iaddr); 457 /* XXX need to FRESTORE */ 458 ksi.ksi_signo = SIGFPE; 459 ksi.ksi_code = FPE_FLTINV; 460 break; 461#endif 462 463 case T_ILLINST|T_USER: /* illegal instruction fault */ 464#ifdef COMPAT_HPUX 465 if (p->p_emul == &emul_hpux) { 466 ksi.ksi_addr = (void *)HPUX_ILL_ILLINST_TRAP; 467 ksi.ksi_signo = SIGILL; 468 break; 469 } 470 /* fall through */ 471#endif 472 case T_PRIVINST|T_USER: /* privileged instruction fault */ 473#ifdef COMPAT_HPUX 474 if (p->p_emul == &emul_hpux) 475 ksi.ksi_addr = (void *)HPUX_ILL_PRIV_TRAP; 476 else 477#endif 478 ksi.ksi_addr = (void *)(int)frame.f_format; 479 /* XXX was ILL_PRIVIN_FAULT */ 480 ksi.ksi_signo = SIGILL; 481 ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ? 482 ILL_PRVOPC : ILL_ILLOPC; 483 break; 484 485 case T_ZERODIV|T_USER: /* Divide by zero */ 486#ifdef COMPAT_HPUX 487 if (p->p_emul == &emul_hpux) 488 ksi.ksi_addr = (void *)HPUX_FPE_INTDIV_TRAP; 489 else 490#endif 491 ksi.ksi_addr = (void *)(int)frame.f_format; 492 /* XXX was FPE_INTDIV_TRAP */ 493 ksi.ksi_signo = SIGFPE; 494 ksi.ksi_code = FPE_FLTDIV; 495 break; 496 497 case T_CHKINST|T_USER: /* CHK instruction trap */ 498#ifdef COMPAT_HPUX 499 if (p->p_emul == &emul_hpux) { 500 /* handled differently under hp-ux */ 501 ksi.ksi_signo = SIGILL; 502 ksi.ksi_addr = (void *)HPUX_ILL_CHK_TRAP; 503 break; 504 } 505#endif 506 ksi.ksi_addr = (void *)(int)frame.f_format; 507 /* XXX was FPE_SUBRNG_TRAP */ 508 ksi.ksi_signo = SIGFPE; 509 break; 510 511 case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ 512#ifdef COMPAT_HPUX 513 if (p->p_emul == &emul_hpux) { 514 /* handled differently under hp-ux */ 515 ksi.ksi_signo = SIGILL; 516 ksi.ksi_addr = (void *)HPUX_ILL_TRAPV_TRAP; 517 break; 518 } 519#endif 520 ksi.ksi_addr = (void *)(int)frame.f_format; 521 /* XXX was FPE_INTOVF_TRAP */ 522 ksi.ksi_signo = SIGFPE; 523 break; 524 525 /* 526 * XXX: Trace traps are a nightmare. 527 * 528 * HP-UX uses trap #1 for breakpoints, 529 * NetBSD/m68k uses trap #2, 530 * SUN 3.x uses trap #15, 531 * DDB and KGDB uses trap #15 (for kernel breakpoints; 532 * handled elsewhere). 533 * 534 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 535 * SUN 3.x traps get passed through as T_TRAP15 and are not really 536 * supported yet. 537 * 538 * XXX: We should never get kernel-mode T_TRAP15 539 * XXX: because locore.s now gives them special treatment. 540 */ 541 case T_TRAP15: /* kernel breakpoint */ 542#ifdef DEBUG 543 printf("unexpected kernel trace trap, type = %d\n", type); 544 printf("program counter = 0x%x\n", frame.f_pc); 545#endif 546 frame.f_sr &= ~PSL_T; 547 return; 548 549 case T_TRACE|T_USER: /* user trace trap */ 550#ifdef COMPAT_SUNOS 551 /* 552 * SunOS uses Trap #2 for a "CPU cache flush". 553 * Just flush the on-chip caches and return. 554 */ 555 if (p->p_emul == &emul_sunos) { 556 ICIA(); 557 DCIU(); 558 return; 559 } 560#endif 561 /* FALLTHROUGH */ 562 case T_TRACE: /* tracing a trap instruction */ 563 case T_TRAP15|T_USER: /* SUN user trace trap */ 564 frame.f_sr &= ~PSL_T; 565 ksi.ksi_signo = SIGTRAP; 566 break; 567 568 case T_ASTFLT: /* system async trap, cannot happen */ 569 goto dopanic; 570 571 case T_ASTFLT|T_USER: /* user async trap */ 572 astpending = 0; 573 /* 574 * We check for software interrupts first. This is because 575 * they are at a higher level than ASTs, and on a VAX would 576 * interrupt the AST. We assume that if we are processing 577 * an AST that we must be at IPL0 so we don't bother to 578 * check. Note that we ensure that we are at least at SIR 579 * IPL while processing the SIR. 580 */ 581 spl1(); 582 /* fall into... */ 583 584 case T_SSIR: /* software interrupt */ 585 case T_SSIR|T_USER: 586 while ((bit = ffs(ssir))) { 587 --bit; 588 ssir &= ~(1 << bit); 589 uvmexp.softs++; 590 if (sir_routines[bit]) 591 sir_routines[bit](sir_args[bit]); 592 } 593 /* 594 * If this was not an AST trap, we are all done. 595 */ 596 if (type != (T_ASTFLT|T_USER)) { 597 uvmexp.traps--; 598 return; 599 } 600 spl0(); 601 if (p->p_flag & P_OWEUPC) { 602 p->p_flag &= ~P_OWEUPC; 603 ADDUPROF(p); 604 } 605 if (want_resched) 606 preempt(0); 607 goto out; 608 609 case T_MMUFLT: /* kernel mode page fault */ 610 /* 611 * If we were doing profiling ticks or other user mode 612 * stuff from interrupt code, Just Say No. 613 */ 614 if (l->l_addr->u_pcb.pcb_onfault == fubail || 615 l->l_addr->u_pcb.pcb_onfault == subail) 616 goto copyfault; 617 /* fall into ... */ 618 619 case T_MMUFLT|T_USER: /* page fault */ 620 { 621 vaddr_t va; 622 struct vmspace *vm = p->p_vmspace; 623 struct vm_map *map; 624 int rv; 625 vm_prot_t ftype; 626 extern struct vm_map *kernel_map; 627 628#ifdef DEBUG 629 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 630 printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", 631 p->p_pid, code, v, frame.f_pc, frame.f_sr); 632#endif 633 /* 634 * It is only a kernel address space fault iff: 635 * 1. (type & T_USER) == 0 and 636 * 2. pcb_onfault not set or 637 * 3. pcb_onfault set but supervisor space data fault 638 * The last can occur during an exec() copyin where the 639 * argument space is lazy-allocated. 640 */ 641 if ((type & T_USER) == 0 && 642 ((l->l_addr->u_pcb.pcb_onfault == 0) || KDFAULT(code))) 643 map = kernel_map; 644 else { 645 map = vm ? &vm->vm_map : kernel_map; 646 if (l->l_flag & L_SA) { 647 l->l_savp->savp_faultaddr = (vaddr_t)v; 648 l->l_flag |= L_SA_PAGEFAULT; 649 } 650 } 651 652 if (WRFAULT(code)) 653 ftype = VM_PROT_WRITE; 654 else 655 ftype = VM_PROT_READ; 656 657 va = trunc_page((vaddr_t)v); 658 659 if (map == kernel_map && va == 0) { 660 printf("trap: bad kernel %s access at 0x%x\n", 661 (ftype & VM_PROT_WRITE) ? "read/write" : 662 "read", v); 663 goto dopanic; 664 } 665 666#ifdef DIAGNOSTIC 667 if (interrupt_depth && !panicking) { 668 printf("trap: calling uvm_fault() from interrupt!\n"); 669 goto dopanic; 670 } 671#endif 672 673#ifdef COMPAT_HPUX 674 if (ISHPMMADDR(va)) { 675 int pmap_mapmulti(pmap_t, vaddr_t); 676 vaddr_t bva; 677 678 rv = pmap_mapmulti(map->pmap, va); 679 if (rv != 0) { 680 bva = HPMMBASEADDR(va); 681 rv = uvm_fault(map, bva, ftype); 682 if (rv == 0) 683 (void) pmap_mapmulti(map->pmap, va); 684 } 685 } else 686#endif 687 rv = uvm_fault(map, va, ftype); 688#ifdef DEBUG 689 if (rv && MDB_ISPID(p->p_pid)) 690 printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", 691 map, va, ftype, rv); 692#endif 693 /* 694 * If this was a stack access we keep track of the maximum 695 * accessed stack size. Also, if vm_fault gets a protection 696 * failure it is due to accessing the stack region outside 697 * the current limit and we need to reflect that as an access 698 * error. 699 */ 700 if (rv == 0) { 701 if (map != kernel_map && (caddr_t)va >= vm->vm_maxsaddr) 702 uvm_grow(p, va); 703 704 if (type == T_MMUFLT) { 705#ifdef M68040 706 if (cputype == CPU_68040) 707 (void) writeback(&frame, 1); 708#endif 709 return; 710 } 711 l->l_flag &= ~L_SA_PAGEFAULT; 712 goto out; 713 } 714 if (rv == EACCES) { 715 ksi.ksi_code = SEGV_ACCERR; 716 rv = EFAULT; 717 } else 718 ksi.ksi_code = SEGV_MAPERR; 719 if (type == T_MMUFLT) { 720 if (l->l_addr->u_pcb.pcb_onfault) 721 goto copyfault; 722 printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", 723 map, va, ftype, rv); 724 printf(" type %x, code [mmu,,ssw]: %x\n", 725 type, code); 726 goto dopanic; 727 } 728 l->l_flag &= ~L_SA_PAGEFAULT; 729 ksi.ksi_addr = (void *)v; 730 if (rv == ENOMEM) { 731 printf("UVM: pid %d (%s), uid %d killed: out of swap\n", 732 p->p_pid, p->p_comm, 733 p->p_cred ? 734 kauth_cred_geteuid(p->p_cred) : -1); 735 ksi.ksi_signo = SIGKILL; 736 } else { 737 ksi.ksi_signo = SIGSEGV; 738 } 739 break; 740 } 741 } 742 trapsignal(l, &ksi); 743 if ((type & T_USER) == 0) 744 return; 745out: 746 userret(l, &frame, sticks, v, 1); 747} 748 749#ifdef M68040 750#ifdef DEBUG 751struct writebackstats { 752 int calls; 753 int cpushes; 754 int move16s; 755 int wb1s, wb2s, wb3s; 756 int wbsize[4]; 757} wbstats; 758 759const char *f7sz[] = { "longword", "byte", "word", "line" }; 760const char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 761const char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 762 "M-code", "k-data", "k-code", "RES" }; 763const char wberrstr[] = 764 "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 765#endif 766 767int 768writeback(struct frame *fp, int docachepush) 769{ 770 struct fmt7 *f = &fp->f_fmt7; 771 struct lwp *l = curlwp; 772 struct proc *p = l->l_proc; 773 int err = 0; 774 u_int fa; 775 caddr_t oonfault = l->l_addr->u_pcb.pcb_onfault; 776 paddr_t pa; 777 778#ifdef DEBUG 779 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 780 printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 781 dumpssw(f->f_ssw); 782 } 783 wbstats.calls++; 784#endif 785 /* 786 * Deal with special cases first. 787 */ 788 if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 789 /* 790 * Dcache push fault. 791 * Line-align the address and write out the push data to 792 * the indicated physical address. 793 */ 794#ifdef DEBUG 795 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 796 printf(" pushing %s to PA %x, data %x", 797 f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 798 f->f_fa, f->f_pd0); 799 if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 800 printf("/%x/%x/%x", 801 f->f_pd1, f->f_pd2, f->f_pd3); 802 printf("\n"); 803 } 804 if (f->f_wb1s & SSW4_WBSV) 805 panic("writeback: cache push with WB1S valid"); 806 wbstats.cpushes++; 807#endif 808 /* 809 * XXX there are security problems if we attempt to do a 810 * cache push after a signal handler has been called. 811 */ 812 if (docachepush) { 813 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, 814 trunc_page(f->f_fa), VM_PROT_WRITE, 815 VM_PROT_WRITE|PMAP_WIRED); 816 pmap_update(pmap_kernel()); 817 fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 818 bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 819 (void) pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa); 820 DCFL(pa); 821 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, 822 (vaddr_t)&vmmap[PAGE_SIZE]); 823 pmap_update(pmap_kernel()); 824 } else 825 printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 826 p->p_pid, p->p_comm, kauth_cred_geteuid(p->p_cred)); 827 } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 828 /* 829 * MOVE16 fault. 830 * Line-align the address and write out the push data to 831 * the indicated virtual address. 832 */ 833#ifdef DEBUG 834 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 835 printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 836 f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 837 f->f_pd2, f->f_pd3); 838 if (f->f_wb1s & SSW4_WBSV) 839 panic("writeback: MOVE16 with WB1S valid"); 840 wbstats.move16s++; 841#endif 842 if (KDFAULT(f->f_wb1s)) 843 bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 844 else 845 err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 846 if (err) { 847 fa = f->f_fa & ~0xF; 848#ifdef DEBUG 849 if (mmudebug & MDB_WBFAILED) 850 printf(wberrstr, p->p_pid, p->p_comm, 851 "MOVE16", fp->f_pc, f->f_fa, 852 f->f_fa & ~0xF, f->f_pd0); 853#endif 854 } 855 } else if (f->f_wb1s & SSW4_WBSV) { 856 /* 857 * Writeback #1. 858 * Position the "memory-aligned" data and write it out. 859 */ 860 u_int wb1d = f->f_wb1d; 861 int off; 862 863#ifdef DEBUG 864 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 865 dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 866 wbstats.wb1s++; 867 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 868#endif 869 off = (f->f_wb1a & 3) * 8; 870 switch (f->f_wb1s & SSW4_SZMASK) { 871 case SSW4_SZLW: 872 if (off) 873 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 874 if (KDFAULT(f->f_wb1s)) 875 *(long *)f->f_wb1a = wb1d; 876 else 877 err = suword((caddr_t)f->f_wb1a, wb1d); 878 break; 879 case SSW4_SZB: 880 off = 24 - off; 881 if (off) 882 wb1d >>= off; 883 if (KDFAULT(f->f_wb1s)) 884 *(char *)f->f_wb1a = wb1d; 885 else 886 err = subyte((caddr_t)f->f_wb1a, wb1d); 887 break; 888 case SSW4_SZW: 889 off = (off + 16) % 32; 890 if (off) 891 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 892 if (KDFAULT(f->f_wb1s)) 893 *(short *)f->f_wb1a = wb1d; 894 else 895 err = susword((caddr_t)f->f_wb1a, wb1d); 896 break; 897 } 898 if (err) { 899 fa = f->f_wb1a; 900#ifdef DEBUG 901 if (mmudebug & MDB_WBFAILED) 902 printf(wberrstr, p->p_pid, p->p_comm, 903 "#1", fp->f_pc, f->f_fa, 904 f->f_wb1a, f->f_wb1d); 905#endif 906 } 907 } 908 /* 909 * Deal with the "normal" writebacks. 910 * 911 * XXX writeback2 is known to reflect a LINE size writeback after 912 * a MOVE16 was already dealt with above. Ignore it. 913 */ 914 if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 915 (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 916#ifdef DEBUG 917 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 918 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 919 wbstats.wb2s++; 920 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 921#endif 922 switch (f->f_wb2s & SSW4_SZMASK) { 923 case SSW4_SZLW: 924 if (KDFAULT(f->f_wb2s)) 925 *(long *)f->f_wb2a = f->f_wb2d; 926 else 927 err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 928 break; 929 case SSW4_SZB: 930 if (KDFAULT(f->f_wb2s)) 931 *(char *)f->f_wb2a = f->f_wb2d; 932 else 933 err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 934 break; 935 case SSW4_SZW: 936 if (KDFAULT(f->f_wb2s)) 937 *(short *)f->f_wb2a = f->f_wb2d; 938 else 939 err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 940 break; 941 } 942 if (err) { 943 fa = f->f_wb2a; 944#ifdef DEBUG 945 if (mmudebug & MDB_WBFAILED) { 946 printf(wberrstr, p->p_pid, p->p_comm, 947 "#2", fp->f_pc, f->f_fa, 948 f->f_wb2a, f->f_wb2d); 949 dumpssw(f->f_ssw); 950 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 951 } 952#endif 953 } 954 } 955 if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 956#ifdef DEBUG 957 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 958 dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 959 wbstats.wb3s++; 960 wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 961#endif 962 switch (f->f_wb3s & SSW4_SZMASK) { 963 case SSW4_SZLW: 964 if (KDFAULT(f->f_wb3s)) 965 *(long *)f->f_wb3a = f->f_wb3d; 966 else 967 err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 968 break; 969 case SSW4_SZB: 970 if (KDFAULT(f->f_wb3s)) 971 *(char *)f->f_wb3a = f->f_wb3d; 972 else 973 err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 974 break; 975 case SSW4_SZW: 976 if (KDFAULT(f->f_wb3s)) 977 *(short *)f->f_wb3a = f->f_wb3d; 978 else 979 err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 980 break; 981#ifdef DEBUG 982 case SSW4_SZLN: 983 panic("writeback: wb3s indicates LINE write"); 984#endif 985 } 986 if (err) { 987 fa = f->f_wb3a; 988#ifdef DEBUG 989 if (mmudebug & MDB_WBFAILED) 990 printf(wberrstr, p->p_pid, p->p_comm, 991 "#3", fp->f_pc, f->f_fa, 992 f->f_wb3a, f->f_wb3d); 993#endif 994 } 995 } 996 l->l_addr->u_pcb.pcb_onfault = oonfault; 997 if (err) 998 err = SIGSEGV; 999 return (err); 1000} 1001 1002#ifdef DEBUG 1003void 1004dumpssw(u_short ssw) 1005{ 1006 printf(" SSW: %x: ", ssw); 1007 if (ssw & SSW4_CP) 1008 printf("CP,"); 1009 if (ssw & SSW4_CU) 1010 printf("CU,"); 1011 if (ssw & SSW4_CT) 1012 printf("CT,"); 1013 if (ssw & SSW4_CM) 1014 printf("CM,"); 1015 if (ssw & SSW4_MA) 1016 printf("MA,"); 1017 if (ssw & SSW4_ATC) 1018 printf("ATC,"); 1019 if (ssw & SSW4_LK) 1020 printf("LK,"); 1021 if (ssw & SSW4_RW) 1022 printf("RW,"); 1023 printf(" SZ=%s, TT=%s, TM=%s\n", 1024 f7sz[(ssw & SSW4_SZMASK) >> 5], 1025 f7tt[(ssw & SSW4_TTMASK) >> 3], 1026 f7tm[ssw & SSW4_TMMASK]); 1027} 1028 1029void 1030dumpwb(int num, u_short s, u_int a, u_int d) 1031{ 1032 struct proc *p = curproc; 1033 paddr_t pa; 1034 1035 printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 1036 num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 1037 f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 1038 printf(" PA "); 1039 if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == FALSE) 1040 printf("<invalid address>"); 1041 else 1042 printf("%lx, current value %lx", pa, fuword((caddr_t)a)); 1043 printf("\n"); 1044} 1045#endif 1046#endif 1047 1048/* 1049 * Allocation routines for software interrupts. 1050 */ 1051u_long 1052allocate_sir(void (*proc)(void *), void *arg) 1053{ 1054 int bit; 1055 1056 if( next_sir >= NSIR ) 1057 panic("allocate_sir: none left"); 1058 bit = next_sir++; 1059 sir_routines[bit] = proc; 1060 sir_args[bit] = arg; 1061 return (1 << bit); 1062} 1063 1064void 1065init_sir(void) 1066{ 1067 extern void netintr(void); 1068 1069 sir_routines[0] = (void (*)(void *))netintr; 1070 sir_routines[1] = softclock; 1071 next_sir = 2; 1072} 1073