trap.c revision 1.44
1/* $NetBSD: trap.c,v 1.44 2003/09/17 23:17:45 cl 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.44 2003/09/17 23:17:45 cl 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 if (l->l_flag & L_SA) { 646 KDASSERT(p != NULL && p->p_sa != NULL); 647 p->p_sa->sa_vp_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 && !panicing) { 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 __P((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, 0, ftype); 682 if (rv == 0) 683 (void) pmap_mapmulti(map->pmap, va); 684 } 685 } else 686#endif 687 rv = uvm_fault(map, va, 0, ftype); 688#ifdef DEBUG 689 if (rv && MDB_ISPID(p->p_pid)) 690 printf("uvm_fault(%p, 0x%lx, 0, 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 ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr) 701 && map != kernel_map) { 702 if (rv == 0) { 703 unsigned nss; 704 705 nss = btoc(USRSTACK-(unsigned)va); 706 if (nss > vm->vm_ssize) 707 vm->vm_ssize = nss; 708 } else if (rv == EACCES) 709 rv = EFAULT; 710 } 711 if (rv == 0) { 712 if (type == T_MMUFLT) { 713#ifdef M68040 714 if (cputype == CPU_68040) 715 (void) writeback(&frame, 1); 716#endif 717 return; 718 } 719 l->l_flag &= ~L_SA_PAGEFAULT; 720 goto out; 721 } 722 if (type == T_MMUFLT) { 723 if (l->l_addr->u_pcb.pcb_onfault) 724 goto copyfault; 725 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 726 map, va, ftype, rv); 727 printf(" type %x, code [mmu,,ssw]: %x\n", 728 type, code); 729 goto dopanic; 730 } 731 l->l_flag &= ~L_SA_PAGEFAULT; 732 ucode = v; 733 if (rv == ENOMEM) { 734 printf("UVM: pid %d (%s), uid %d killed: out of swap\n", 735 p->p_pid, p->p_comm, 736 p->p_cred && p->p_ucred ? 737 p->p_ucred->cr_uid : -1); 738 i = SIGKILL; 739 } else { 740 i = SIGSEGV; 741 } 742 break; 743 } 744 } 745 trapsignal(l, i, ucode); 746 if ((type & T_USER) == 0) 747 return; 748out: 749 userret(l, &frame, sticks, v, 1); 750} 751 752#ifdef M68040 753#ifdef DEBUG 754struct writebackstats { 755 int calls; 756 int cpushes; 757 int move16s; 758 int wb1s, wb2s, wb3s; 759 int wbsize[4]; 760} wbstats; 761 762char *f7sz[] = { "longword", "byte", "word", "line" }; 763char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 764char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 765 "M-code", "k-data", "k-code", "RES" }; 766char wberrstr[] = 767 "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 768#endif 769 770int 771writeback(fp, docachepush) 772 struct frame *fp; 773 int docachepush; 774{ 775 struct fmt7 *f = &fp->f_fmt7; 776 struct lwp *l = curlwp; 777 struct proc *p = l->l_proc; 778 int err = 0; 779 u_int fa; 780 caddr_t oonfault = l->l_addr->u_pcb.pcb_onfault; 781 paddr_t pa; 782 783#ifdef DEBUG 784 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 785 printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 786 dumpssw(f->f_ssw); 787 } 788 wbstats.calls++; 789#endif 790 /* 791 * Deal with special cases first. 792 */ 793 if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 794 /* 795 * Dcache push fault. 796 * Line-align the address and write out the push data to 797 * the indicated physical address. 798 */ 799#ifdef DEBUG 800 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 801 printf(" pushing %s to PA %x, data %x", 802 f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 803 f->f_fa, f->f_pd0); 804 if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 805 printf("/%x/%x/%x", 806 f->f_pd1, f->f_pd2, f->f_pd3); 807 printf("\n"); 808 } 809 if (f->f_wb1s & SSW4_WBSV) 810 panic("writeback: cache push with WB1S valid"); 811 wbstats.cpushes++; 812#endif 813 /* 814 * XXX there are security problems if we attempt to do a 815 * cache push after a signal handler has been called. 816 */ 817 if (docachepush) { 818 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, 819 trunc_page(f->f_fa), VM_PROT_WRITE, 820 VM_PROT_WRITE|PMAP_WIRED); 821 pmap_update(pmap_kernel()); 822 fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 823 bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 824 (void) pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa); 825 DCFL(pa); 826 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, 827 (vaddr_t)&vmmap[PAGE_SIZE]); 828 pmap_update(pmap_kernel()); 829 } else 830 printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 831 p->p_pid, p->p_comm, p->p_ucred->cr_uid); 832 } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 833 /* 834 * MOVE16 fault. 835 * Line-align the address and write out the push data to 836 * the indicated virtual address. 837 */ 838#ifdef DEBUG 839 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 840 printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 841 f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 842 f->f_pd2, f->f_pd3); 843 if (f->f_wb1s & SSW4_WBSV) 844 panic("writeback: MOVE16 with WB1S valid"); 845 wbstats.move16s++; 846#endif 847 if (KDFAULT(f->f_wb1s)) 848 bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 849 else 850 err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 851 if (err) { 852 fa = f->f_fa & ~0xF; 853#ifdef DEBUG 854 if (mmudebug & MDB_WBFAILED) 855 printf(wberrstr, p->p_pid, p->p_comm, 856 "MOVE16", fp->f_pc, f->f_fa, 857 f->f_fa & ~0xF, f->f_pd0); 858#endif 859 } 860 } else if (f->f_wb1s & SSW4_WBSV) { 861 /* 862 * Writeback #1. 863 * Position the "memory-aligned" data and write it out. 864 */ 865 u_int wb1d = f->f_wb1d; 866 int off; 867 868#ifdef DEBUG 869 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 870 dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 871 wbstats.wb1s++; 872 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 873#endif 874 off = (f->f_wb1a & 3) * 8; 875 switch (f->f_wb1s & SSW4_SZMASK) { 876 case SSW4_SZLW: 877 if (off) 878 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 879 if (KDFAULT(f->f_wb1s)) 880 *(long *)f->f_wb1a = wb1d; 881 else 882 err = suword((caddr_t)f->f_wb1a, wb1d); 883 break; 884 case SSW4_SZB: 885 off = 24 - off; 886 if (off) 887 wb1d >>= off; 888 if (KDFAULT(f->f_wb1s)) 889 *(char *)f->f_wb1a = wb1d; 890 else 891 err = subyte((caddr_t)f->f_wb1a, wb1d); 892 break; 893 case SSW4_SZW: 894 off = (off + 16) % 32; 895 if (off) 896 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 897 if (KDFAULT(f->f_wb1s)) 898 *(short *)f->f_wb1a = wb1d; 899 else 900 err = susword((caddr_t)f->f_wb1a, wb1d); 901 break; 902 } 903 if (err) { 904 fa = f->f_wb1a; 905#ifdef DEBUG 906 if (mmudebug & MDB_WBFAILED) 907 printf(wberrstr, p->p_pid, p->p_comm, 908 "#1", fp->f_pc, f->f_fa, 909 f->f_wb1a, f->f_wb1d); 910#endif 911 } 912 } 913 /* 914 * Deal with the "normal" writebacks. 915 * 916 * XXX writeback2 is known to reflect a LINE size writeback after 917 * a MOVE16 was already dealt with above. Ignore it. 918 */ 919 if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 920 (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 921#ifdef DEBUG 922 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 923 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 924 wbstats.wb2s++; 925 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 926#endif 927 switch (f->f_wb2s & SSW4_SZMASK) { 928 case SSW4_SZLW: 929 if (KDFAULT(f->f_wb2s)) 930 *(long *)f->f_wb2a = f->f_wb2d; 931 else 932 err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 933 break; 934 case SSW4_SZB: 935 if (KDFAULT(f->f_wb2s)) 936 *(char *)f->f_wb2a = f->f_wb2d; 937 else 938 err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 939 break; 940 case SSW4_SZW: 941 if (KDFAULT(f->f_wb2s)) 942 *(short *)f->f_wb2a = f->f_wb2d; 943 else 944 err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 945 break; 946 } 947 if (err) { 948 fa = f->f_wb2a; 949#ifdef DEBUG 950 if (mmudebug & MDB_WBFAILED) { 951 printf(wberrstr, p->p_pid, p->p_comm, 952 "#2", fp->f_pc, f->f_fa, 953 f->f_wb2a, f->f_wb2d); 954 dumpssw(f->f_ssw); 955 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 956 } 957#endif 958 } 959 } 960 if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 961#ifdef DEBUG 962 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 963 dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 964 wbstats.wb3s++; 965 wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 966#endif 967 switch (f->f_wb3s & SSW4_SZMASK) { 968 case SSW4_SZLW: 969 if (KDFAULT(f->f_wb3s)) 970 *(long *)f->f_wb3a = f->f_wb3d; 971 else 972 err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 973 break; 974 case SSW4_SZB: 975 if (KDFAULT(f->f_wb3s)) 976 *(char *)f->f_wb3a = f->f_wb3d; 977 else 978 err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 979 break; 980 case SSW4_SZW: 981 if (KDFAULT(f->f_wb3s)) 982 *(short *)f->f_wb3a = f->f_wb3d; 983 else 984 err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 985 break; 986#ifdef DEBUG 987 case SSW4_SZLN: 988 panic("writeback: wb3s indicates LINE write"); 989#endif 990 } 991 if (err) { 992 fa = f->f_wb3a; 993#ifdef DEBUG 994 if (mmudebug & MDB_WBFAILED) 995 printf(wberrstr, p->p_pid, p->p_comm, 996 "#3", fp->f_pc, f->f_fa, 997 f->f_wb3a, f->f_wb3d); 998#endif 999 } 1000 } 1001 l->l_addr->u_pcb.pcb_onfault = oonfault; 1002 if (err) 1003 err = SIGSEGV; 1004 return (err); 1005} 1006 1007#ifdef DEBUG 1008void 1009dumpssw(ssw) 1010 u_short ssw; 1011{ 1012 printf(" SSW: %x: ", ssw); 1013 if (ssw & SSW4_CP) 1014 printf("CP,"); 1015 if (ssw & SSW4_CU) 1016 printf("CU,"); 1017 if (ssw & SSW4_CT) 1018 printf("CT,"); 1019 if (ssw & SSW4_CM) 1020 printf("CM,"); 1021 if (ssw & SSW4_MA) 1022 printf("MA,"); 1023 if (ssw & SSW4_ATC) 1024 printf("ATC,"); 1025 if (ssw & SSW4_LK) 1026 printf("LK,"); 1027 if (ssw & SSW4_RW) 1028 printf("RW,"); 1029 printf(" SZ=%s, TT=%s, TM=%s\n", 1030 f7sz[(ssw & SSW4_SZMASK) >> 5], 1031 f7tt[(ssw & SSW4_TTMASK) >> 3], 1032 f7tm[ssw & SSW4_TMMASK]); 1033} 1034 1035void 1036dumpwb(num, s, a, d) 1037 int num; 1038 u_short s; 1039 u_int a, d; 1040{ 1041 struct proc *p = curproc; 1042 paddr_t pa; 1043 1044 printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 1045 num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 1046 f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 1047 printf(" PA "); 1048 if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == FALSE) 1049 printf("<invalid address>"); 1050 else 1051 printf("%lx, current value %lx", pa, fuword((caddr_t)a)); 1052 printf("\n"); 1053} 1054#endif 1055#endif 1056 1057/* 1058 * Allocation routines for software interrupts. 1059 */ 1060u_long 1061allocate_sir(proc, arg) 1062 void (*proc)(void *); 1063 void *arg; 1064{ 1065 int bit; 1066 1067 if( next_sir >= NSIR ) 1068 panic("allocate_sir: none left"); 1069 bit = next_sir++; 1070 sir_routines[bit] = proc; 1071 sir_args[bit] = arg; 1072 return (1 << bit); 1073} 1074 1075void 1076init_sir() 1077{ 1078 extern void netintr(void); 1079 1080 sir_routines[0] = (void (*)(void *))netintr; 1081 sir_routines[1] = softclock; 1082 next_sir = 2; 1083} 1084