trap.c revision 1.43
1/* $NetBSD: trap.c,v 1.43 2003/08/07 16:28:57 agc 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.43 2003/08/07 16:28:57 agc 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 108#ifdef DEBUG 109#include <dev/cons.h> 110#endif 111 112#include <machine/db_machdep.h> 113#include <machine/psl.h> 114#include <machine/trap.h> 115#include <machine/cpu.h> 116#include <machine/reg.h> 117 118#include <m68k/cacheops.h> 119 120#include <uvm/uvm_extern.h> 121 122#ifdef COMPAT_HPUX 123#include <compat/hpux/hpux.h> 124#endif 125 126#ifdef COMPAT_SUNOS 127#include <compat/sunos/sunos_syscall.h> 128extern struct emul emul_sunos; 129#endif 130 131#ifdef KGDB 132#include <sys/kgdb.h> 133#endif 134 135int writeback __P((struct frame *fp, int docachepush)); 136void trap __P((int type, u_int code, u_int v, struct frame frame)); 137 138#ifdef DEBUG 139void dumpssw __P((u_short)); 140void dumpwb __P((int, u_short, u_int, u_int)); 141#endif 142 143static inline void userret __P((struct lwp *l, struct frame *fp, 144 u_quad_t oticks, u_int faultaddr, int fromtrap)); 145 146int astpending; 147 148char *trap_type[] = { 149 "Bus error", 150 "Address error", 151 "Illegal instruction", 152 "Zero divide", 153 "CHK instruction", 154 "TRAPV instruction", 155 "Privilege violation", 156 "Trace trap", 157 "MMU fault", 158 "SSIR trap", 159 "Format error", 160 "68881 exception", 161 "Coprocessor violation", 162 "Async system trap" 163}; 164int trap_types = sizeof trap_type / sizeof trap_type[0]; 165 166/* 167 * Size of various exception stack frames (minus the standard 8 bytes) 168 */ 169short exframesize[] = { 170 FMT0SIZE, /* type 0 - normal (68020/030/040/060) */ 171 FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ 172 FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */ 173 FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */ 174 FMT4SIZE, /* type 4 - access error/fp disabled (68060) */ 175 -1, -1, /* type 5-6 - undefined */ 176 FMT7SIZE, /* type 7 - access error (68040) */ 177 58, /* type 8 - bus fault (68010) */ 178 FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ 179 FMTASIZE, /* type A - short bus fault (68020/030) */ 180 FMTBSIZE, /* type B - long bus fault (68020/030) */ 181 -1, -1, -1, -1 /* type C-F - undefined */ 182}; 183 184#ifdef M68060 185#define KDFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_TM_SV)) 186#define WRFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_RW_W)) 187#else 188#define KDFAULT_060(c) 0 189#define WRFAULT_060(c) 0 190#endif 191 192#ifdef M68040 193#define KDFAULT_040(c) (cputype == CPU_68040 && \ 194 ((c) & SSW4_TMMASK) == SSW4_TMKD) 195#define WRFAULT_040(c) (cputype == CPU_68040 && \ 196 ((c) & SSW4_RW) == 0) 197#else 198#define KDFAULT_040(c) 0 199#define WRFAULT_040(c) 0 200#endif 201 202#if defined(M68030) || defined(M68020) 203#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \ 204 ((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD)) 205#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \ 206 ((c) & (SSW_DF|SSW_RW)) == SSW_DF) 207#else 208#define KDFAULT_OTH(c) 0 209#define WRFAULT_OTH(c) 0 210#endif 211 212#define KDFAULT(c) (KDFAULT_060(c) || KDFAULT_040(c) || KDFAULT_OTH(c)) 213#define WRFAULT(c) (WRFAULT_060(c) || WRFAULT_040(c) || WRFAULT_OTH(c)) 214 215#ifdef DEBUG 216int mmudebug = 0; 217int mmupid = -1; 218#define MDB_FOLLOW 1 219#define MDB_WBFOLLOW 2 220#define MDB_WBFAILED 4 221#define MDB_ISPID(p) ((p) == mmupid) 222#endif 223 224 225#define NSIR 32 226void (*sir_routines[NSIR])(void *); 227void *sir_args[NSIR]; 228int next_sir; 229 230/* 231 * trap and syscall both need the following work done before returning 232 * to user mode. 233 */ 234static inline void 235userret(l, fp, oticks, faultaddr, fromtrap) 236 struct lwp *l; 237 struct frame *fp; 238 u_quad_t oticks; 239 u_int faultaddr; 240 int fromtrap; 241{ 242 struct proc *p = l->l_proc; 243 int sig; 244#ifdef M68040 245 int beenhere = 0; 246 247again: 248#endif 249 /* take pending signals */ 250 while ((sig = CURSIG(l)) != 0) 251 postsig(sig); 252 253 /* Invoke per-process kernel-exit handling, if any */ 254 if (p->p_userret) 255 (p->p_userret)(l, p->p_userret_arg); 256 257 /* Invoke any pending upcalls. */ 258 while (l->l_flag & L_SA_UPCALL) 259 sa_upcall_userret(l); 260 261 /* 262 * If profiling, charge system time to the trapped pc. 263 */ 264 if (p->p_flag & P_PROFIL) { 265 extern int psratio; 266 267 addupc_task(p, fp->f_pc, 268 (int)(p->p_sticks - oticks) * psratio); 269 } 270#ifdef M68040 271 /* 272 * Deal with user mode writebacks (from trap, or from sigreturn). 273 * If any writeback fails, go back and attempt signal delivery. 274 * unless we have already been here and attempted the writeback 275 * (e.g. bad address with user ignoring SIGSEGV). In that case 276 * we just return to the user without successfully completing 277 * the writebacks. Maybe we should just drop the sucker? 278 */ 279 if (cputype == CPU_68040 && fp->f_format == FMT7) { 280 if (beenhere) { 281#ifdef DEBUG 282 if (mmudebug & MDB_WBFAILED) 283 printf(fromtrap ? 284 "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" : 285 "pid %d(%s): writeback aborted in sigreturn, pc=%x\n", 286 p->p_pid, p->p_comm, fp->f_pc, faultaddr); 287#endif 288 } else if ((sig = writeback(fp, fromtrap))) { 289 beenhere = 1; 290 oticks = p->p_sticks; 291 trapsignal(l, sig, faultaddr); 292 goto again; 293 } 294 } 295#endif 296 curcpu()->ci_schedstate.spc_curpriority = l->l_priority = l->l_usrpri; 297} 298 299/* 300 * Used by the common m68k syscall() and child_return() functions. 301 * XXX: Temporary until all m68k ports share common trap()/userret() code. 302 */ 303void machine_userret(struct lwp *, struct frame *, u_quad_t); 304 305void 306machine_userret(l, f, t) 307 struct lwp *l; 308 struct frame *f; 309 u_quad_t t; 310{ 311 312 userret(l, f, t, 0, 0); 313} 314 315/* 316 * Trap is called from locore to handle most types of processor traps, 317 * including events such as simulated software interrupts/AST's. 318 * System calls are broken out for efficiency. 319 */ 320/*ARGSUSED*/ 321void 322trap(type, code, v, frame) 323 int type; 324 unsigned code; 325 unsigned v; 326 struct frame frame; 327{ 328 extern char fubail[], subail[]; 329 struct lwp *l; 330 struct proc *p; 331 int i, s; 332 u_int ucode; 333 u_quad_t sticks = 0 /* XXX initialiser works around compiler bug */; 334 int bit; 335 static int panicing = 0; 336 337 uvmexp.traps++; 338 l = curlwp; 339 ucode = 0; 340 341 /* I have verified that this DOES happen! -gwr */ 342 if (l == NULL) 343 l = &lwp0; 344 p = l->l_proc; 345 346#ifdef DIAGNOSTIC 347 if (l->l_addr == NULL) 348 panic("trap: no pcb"); 349#endif 350 351 if (USERMODE(frame.f_sr)) { 352 type |= T_USER; 353 sticks = p->p_sticks; 354 l->l_md.md_regs = frame.f_regs; 355 } 356 switch (type) { 357 358 default: 359 dopanic: 360 /* 361 * Let the kernel debugger see the trap frame that 362 * caused us to panic. This is a convenience so 363 * one can see registers at the point of failure. 364 */ 365 s = splhigh(); 366 panicing = 1; 367 printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); 368 printf("%s program counter = 0x%x\n", 369 (type & T_USER) ? "user" : "kernel", frame.f_pc); 370#ifdef KGDB 371 /* If connected, step or cont returns 1 */ 372 if (kgdb_trap(type, (db_regs_t *)&frame)) 373 goto kgdb_cont; 374#endif 375#ifdef DDB 376 (void)kdb_trap(type, (db_regs_t *)&frame); 377#endif 378#ifdef KGDB 379 kgdb_cont: 380#endif 381 splx(s); 382 if (panicstr) { 383 printf("trap during panic!\n"); 384#ifdef DEBUG 385 /* XXX should be a machine-dependent hook */ 386 printf("(press a key)\n"); (void)cngetc(); 387#endif 388 } 389 regdump((struct trapframe *)&frame, 128); 390 type &= ~T_USER; 391 if ((u_int)type < trap_types) 392 panic(trap_type[type]); 393 panic("trap"); 394 395 case T_BUSERR: /* kernel bus error */ 396 if (l->l_addr->u_pcb.pcb_onfault == 0) 397 goto dopanic; 398 /* FALLTHROUGH */ 399 400 copyfault: 401 /* 402 * If we have arranged to catch this fault in any of the 403 * copy to/from user space routines, set PC to return to 404 * indicated location and set flag informing buserror code 405 * that it may need to clean up stack frame. 406 */ 407 frame.f_stackadj = exframesize[frame.f_format]; 408 frame.f_format = frame.f_vector = 0; 409 frame.f_pc = (int) l->l_addr->u_pcb.pcb_onfault; 410 return; 411 412 case T_BUSERR|T_USER: /* bus error */ 413 case T_ADDRERR|T_USER: /* address error */ 414 ucode = v; 415 i = SIGBUS; 416 break; 417 418 case T_COPERR: /* kernel coprocessor violation */ 419 case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ 420 case T_FMTERR: /* ...just in case... */ 421 /* 422 * The user has most likely trashed the RTE or FP state info 423 * in the stack frame of a signal handler. 424 */ 425 printf("pid %d: kernel %s exception\n", p->p_pid, 426 type==T_COPERR ? "coprocessor" : "format"); 427 type |= T_USER; 428 SIGACTION(p, SIGILL).sa_handler = SIG_DFL; 429 sigdelset(&p->p_sigctx.ps_sigignore, SIGILL); 430 sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL); 431 sigdelset(&p->p_sigctx.ps_sigmask, SIGILL); 432 i = SIGILL; 433 ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 434 break; 435 436 case T_COPERR|T_USER: /* user coprocessor violation */ 437 /* What is a proper response here? */ 438 ucode = 0; 439 i = SIGFPE; 440 break; 441 442 case T_FPERR|T_USER: /* 68881 exceptions */ 443 /* 444 * We pass along the 68881 status register which locore stashed 445 * in code for us. Note that there is a possibility that the 446 * bit pattern of this register will conflict with one of the 447 * FPE_* codes defined in signal.h. Fortunately for us, the 448 * only such codes we use are all in the range 1-7 and the low 449 * 3 bits of the status register are defined as 0 so there is 450 * no clash. 451 */ 452 ucode = code; 453 i = SIGFPE; 454 break; 455 456#ifdef M68040 457 case T_FPEMULI|T_USER: /* unimplemented FP instuction */ 458 case T_FPEMULD|T_USER: /* unimplemented FP data type */ 459 /* XXX need to FSAVE */ 460 printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", 461 p->p_pid, p->p_comm, 462 frame.f_format == 2 ? "instruction" : "data type", 463 frame.f_pc, frame.f_fmt2.f_iaddr); 464 /* XXX need to FRESTORE */ 465 i = SIGFPE; 466 break; 467#endif 468 469 case T_ILLINST|T_USER: /* illegal instruction fault */ 470#ifdef COMPAT_HPUX 471 if (p->p_emul == &emul_hpux) { 472 ucode = HPUX_ILL_ILLINST_TRAP; 473 i = SIGILL; 474 break; 475 } 476 /* fall through */ 477#endif 478 case T_PRIVINST|T_USER: /* privileged instruction fault */ 479#ifdef COMPAT_HPUX 480 if (p->p_emul == &emul_hpux) 481 ucode = HPUX_ILL_PRIV_TRAP; 482 else 483#endif 484 ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 485 i = SIGILL; 486 break; 487 488 case T_ZERODIV|T_USER: /* Divide by zero */ 489#ifdef COMPAT_HPUX 490 if (p->p_emul == &emul_hpux) 491 ucode = HPUX_FPE_INTDIV_TRAP; 492 else 493#endif 494 ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 495 i = SIGFPE; 496 break; 497 498 case T_CHKINST|T_USER: /* CHK instruction trap */ 499#ifdef COMPAT_HPUX 500 if (p->p_emul == &emul_hpux) { 501 /* handled differently under hp-ux */ 502 i = SIGILL; 503 ucode = HPUX_ILL_CHK_TRAP; 504 break; 505 } 506#endif 507 ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 508 i = 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 i = SIGILL; 516 ucode = HPUX_ILL_TRAPV_TRAP; 517 break; 518 } 519#endif 520 ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 521 i = 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 i = 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 646 if (WRFAULT(code)) 647 ftype = VM_PROT_WRITE; 648 else 649 ftype = VM_PROT_READ; 650 651 va = trunc_page((vaddr_t)v); 652 653 if (map == kernel_map && va == 0) { 654 printf("trap: bad kernel %s access at 0x%x\n", 655 (ftype & VM_PROT_WRITE) ? "read/write" : 656 "read", v); 657 goto dopanic; 658 } 659 660#ifdef DIAGNOSTIC 661 if (interrupt_depth && !panicing) { 662 printf("trap: calling uvm_fault() from interrupt!\n"); 663 goto dopanic; 664 } 665#endif 666 667#ifdef COMPAT_HPUX 668 if (ISHPMMADDR(va)) { 669 int pmap_mapmulti __P((pmap_t, vaddr_t)); 670 vaddr_t bva; 671 672 rv = pmap_mapmulti(map->pmap, va); 673 if (rv != 0) { 674 bva = HPMMBASEADDR(va); 675 rv = uvm_fault(map, bva, 0, ftype); 676 if (rv == 0) 677 (void) pmap_mapmulti(map->pmap, va); 678 } 679 } else 680#endif 681 rv = uvm_fault(map, va, 0, ftype); 682#ifdef DEBUG 683 if (rv && MDB_ISPID(p->p_pid)) 684 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 685 map, va, ftype, rv); 686#endif 687 /* 688 * If this was a stack access we keep track of the maximum 689 * accessed stack size. Also, if vm_fault gets a protection 690 * failure it is due to accessing the stack region outside 691 * the current limit and we need to reflect that as an access 692 * error. 693 */ 694 if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr) 695 && map != kernel_map) { 696 if (rv == 0) { 697 unsigned nss; 698 699 nss = btoc(USRSTACK-(unsigned)va); 700 if (nss > vm->vm_ssize) 701 vm->vm_ssize = nss; 702 } else if (rv == EACCES) 703 rv = EFAULT; 704 } 705 if (rv == 0) { 706 if (type == T_MMUFLT) { 707#ifdef M68040 708 if (cputype == CPU_68040) 709 (void) writeback(&frame, 1); 710#endif 711 return; 712 } 713 goto out; 714 } 715 if (type == T_MMUFLT) { 716 if (l->l_addr->u_pcb.pcb_onfault) 717 goto copyfault; 718 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 719 map, va, ftype, rv); 720 printf(" type %x, code [mmu,,ssw]: %x\n", 721 type, code); 722 goto dopanic; 723 } 724 ucode = v; 725 if (rv == ENOMEM) { 726 printf("UVM: pid %d (%s), uid %d killed: out of swap\n", 727 p->p_pid, p->p_comm, 728 p->p_cred && p->p_ucred ? 729 p->p_ucred->cr_uid : -1); 730 i = SIGKILL; 731 } else { 732 i = SIGSEGV; 733 } 734 break; 735 } 736 } 737 trapsignal(l, i, ucode); 738 if ((type & T_USER) == 0) 739 return; 740out: 741 userret(l, &frame, sticks, v, 1); 742} 743 744#ifdef M68040 745#ifdef DEBUG 746struct writebackstats { 747 int calls; 748 int cpushes; 749 int move16s; 750 int wb1s, wb2s, wb3s; 751 int wbsize[4]; 752} wbstats; 753 754char *f7sz[] = { "longword", "byte", "word", "line" }; 755char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 756char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 757 "M-code", "k-data", "k-code", "RES" }; 758char wberrstr[] = 759 "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 760#endif 761 762int 763writeback(fp, docachepush) 764 struct frame *fp; 765 int docachepush; 766{ 767 struct fmt7 *f = &fp->f_fmt7; 768 struct lwp *l = curlwp; 769 struct proc *p = l->l_proc; 770 int err = 0; 771 u_int fa; 772 caddr_t oonfault = l->l_addr->u_pcb.pcb_onfault; 773 paddr_t pa; 774 775#ifdef DEBUG 776 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 777 printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 778 dumpssw(f->f_ssw); 779 } 780 wbstats.calls++; 781#endif 782 /* 783 * Deal with special cases first. 784 */ 785 if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 786 /* 787 * Dcache push fault. 788 * Line-align the address and write out the push data to 789 * the indicated physical address. 790 */ 791#ifdef DEBUG 792 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 793 printf(" pushing %s to PA %x, data %x", 794 f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 795 f->f_fa, f->f_pd0); 796 if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 797 printf("/%x/%x/%x", 798 f->f_pd1, f->f_pd2, f->f_pd3); 799 printf("\n"); 800 } 801 if (f->f_wb1s & SSW4_WBSV) 802 panic("writeback: cache push with WB1S valid"); 803 wbstats.cpushes++; 804#endif 805 /* 806 * XXX there are security problems if we attempt to do a 807 * cache push after a signal handler has been called. 808 */ 809 if (docachepush) { 810 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, 811 trunc_page(f->f_fa), VM_PROT_WRITE, 812 VM_PROT_WRITE|PMAP_WIRED); 813 pmap_update(pmap_kernel()); 814 fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 815 bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 816 (void) pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa); 817 DCFL(pa); 818 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, 819 (vaddr_t)&vmmap[PAGE_SIZE]); 820 pmap_update(pmap_kernel()); 821 } else 822 printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 823 p->p_pid, p->p_comm, p->p_ucred->cr_uid); 824 } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 825 /* 826 * MOVE16 fault. 827 * Line-align the address and write out the push data to 828 * the indicated virtual address. 829 */ 830#ifdef DEBUG 831 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 832 printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 833 f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 834 f->f_pd2, f->f_pd3); 835 if (f->f_wb1s & SSW4_WBSV) 836 panic("writeback: MOVE16 with WB1S valid"); 837 wbstats.move16s++; 838#endif 839 if (KDFAULT(f->f_wb1s)) 840 bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 841 else 842 err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 843 if (err) { 844 fa = f->f_fa & ~0xF; 845#ifdef DEBUG 846 if (mmudebug & MDB_WBFAILED) 847 printf(wberrstr, p->p_pid, p->p_comm, 848 "MOVE16", fp->f_pc, f->f_fa, 849 f->f_fa & ~0xF, f->f_pd0); 850#endif 851 } 852 } else if (f->f_wb1s & SSW4_WBSV) { 853 /* 854 * Writeback #1. 855 * Position the "memory-aligned" data and write it out. 856 */ 857 u_int wb1d = f->f_wb1d; 858 int off; 859 860#ifdef DEBUG 861 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 862 dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 863 wbstats.wb1s++; 864 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 865#endif 866 off = (f->f_wb1a & 3) * 8; 867 switch (f->f_wb1s & SSW4_SZMASK) { 868 case SSW4_SZLW: 869 if (off) 870 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 871 if (KDFAULT(f->f_wb1s)) 872 *(long *)f->f_wb1a = wb1d; 873 else 874 err = suword((caddr_t)f->f_wb1a, wb1d); 875 break; 876 case SSW4_SZB: 877 off = 24 - off; 878 if (off) 879 wb1d >>= off; 880 if (KDFAULT(f->f_wb1s)) 881 *(char *)f->f_wb1a = wb1d; 882 else 883 err = subyte((caddr_t)f->f_wb1a, wb1d); 884 break; 885 case SSW4_SZW: 886 off = (off + 16) % 32; 887 if (off) 888 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 889 if (KDFAULT(f->f_wb1s)) 890 *(short *)f->f_wb1a = wb1d; 891 else 892 err = susword((caddr_t)f->f_wb1a, wb1d); 893 break; 894 } 895 if (err) { 896 fa = f->f_wb1a; 897#ifdef DEBUG 898 if (mmudebug & MDB_WBFAILED) 899 printf(wberrstr, p->p_pid, p->p_comm, 900 "#1", fp->f_pc, f->f_fa, 901 f->f_wb1a, f->f_wb1d); 902#endif 903 } 904 } 905 /* 906 * Deal with the "normal" writebacks. 907 * 908 * XXX writeback2 is known to reflect a LINE size writeback after 909 * a MOVE16 was already dealt with above. Ignore it. 910 */ 911 if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 912 (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 913#ifdef DEBUG 914 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 915 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 916 wbstats.wb2s++; 917 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 918#endif 919 switch (f->f_wb2s & SSW4_SZMASK) { 920 case SSW4_SZLW: 921 if (KDFAULT(f->f_wb2s)) 922 *(long *)f->f_wb2a = f->f_wb2d; 923 else 924 err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 925 break; 926 case SSW4_SZB: 927 if (KDFAULT(f->f_wb2s)) 928 *(char *)f->f_wb2a = f->f_wb2d; 929 else 930 err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 931 break; 932 case SSW4_SZW: 933 if (KDFAULT(f->f_wb2s)) 934 *(short *)f->f_wb2a = f->f_wb2d; 935 else 936 err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 937 break; 938 } 939 if (err) { 940 fa = f->f_wb2a; 941#ifdef DEBUG 942 if (mmudebug & MDB_WBFAILED) { 943 printf(wberrstr, p->p_pid, p->p_comm, 944 "#2", fp->f_pc, f->f_fa, 945 f->f_wb2a, f->f_wb2d); 946 dumpssw(f->f_ssw); 947 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 948 } 949#endif 950 } 951 } 952 if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 953#ifdef DEBUG 954 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 955 dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 956 wbstats.wb3s++; 957 wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 958#endif 959 switch (f->f_wb3s & SSW4_SZMASK) { 960 case SSW4_SZLW: 961 if (KDFAULT(f->f_wb3s)) 962 *(long *)f->f_wb3a = f->f_wb3d; 963 else 964 err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 965 break; 966 case SSW4_SZB: 967 if (KDFAULT(f->f_wb3s)) 968 *(char *)f->f_wb3a = f->f_wb3d; 969 else 970 err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 971 break; 972 case SSW4_SZW: 973 if (KDFAULT(f->f_wb3s)) 974 *(short *)f->f_wb3a = f->f_wb3d; 975 else 976 err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 977 break; 978#ifdef DEBUG 979 case SSW4_SZLN: 980 panic("writeback: wb3s indicates LINE write"); 981#endif 982 } 983 if (err) { 984 fa = f->f_wb3a; 985#ifdef DEBUG 986 if (mmudebug & MDB_WBFAILED) 987 printf(wberrstr, p->p_pid, p->p_comm, 988 "#3", fp->f_pc, f->f_fa, 989 f->f_wb3a, f->f_wb3d); 990#endif 991 } 992 } 993 l->l_addr->u_pcb.pcb_onfault = oonfault; 994 if (err) 995 err = SIGSEGV; 996 return (err); 997} 998 999#ifdef DEBUG 1000void 1001dumpssw(ssw) 1002 u_short ssw; 1003{ 1004 printf(" SSW: %x: ", ssw); 1005 if (ssw & SSW4_CP) 1006 printf("CP,"); 1007 if (ssw & SSW4_CU) 1008 printf("CU,"); 1009 if (ssw & SSW4_CT) 1010 printf("CT,"); 1011 if (ssw & SSW4_CM) 1012 printf("CM,"); 1013 if (ssw & SSW4_MA) 1014 printf("MA,"); 1015 if (ssw & SSW4_ATC) 1016 printf("ATC,"); 1017 if (ssw & SSW4_LK) 1018 printf("LK,"); 1019 if (ssw & SSW4_RW) 1020 printf("RW,"); 1021 printf(" SZ=%s, TT=%s, TM=%s\n", 1022 f7sz[(ssw & SSW4_SZMASK) >> 5], 1023 f7tt[(ssw & SSW4_TTMASK) >> 3], 1024 f7tm[ssw & SSW4_TMMASK]); 1025} 1026 1027void 1028dumpwb(num, s, a, d) 1029 int num; 1030 u_short s; 1031 u_int a, d; 1032{ 1033 struct proc *p = curproc; 1034 paddr_t pa; 1035 1036 printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 1037 num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 1038 f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 1039 printf(" PA "); 1040 if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == FALSE) 1041 printf("<invalid address>"); 1042 else 1043 printf("%lx, current value %lx", pa, fuword((caddr_t)a)); 1044 printf("\n"); 1045} 1046#endif 1047#endif 1048 1049/* 1050 * Allocation routines for software interrupts. 1051 */ 1052u_long 1053allocate_sir(proc, arg) 1054 void (*proc)(void *); 1055 void *arg; 1056{ 1057 int bit; 1058 1059 if( next_sir >= NSIR ) 1060 panic("allocate_sir: none left"); 1061 bit = next_sir++; 1062 sir_routines[bit] = proc; 1063 sir_args[bit] = arg; 1064 return (1 << bit); 1065} 1066 1067void 1068init_sir() 1069{ 1070 extern void netintr(void); 1071 1072 sir_routines[0] = (void (*)(void *))netintr; 1073 sir_routines[1] = softclock; 1074 next_sir = 2; 1075} 1076