trap.c revision 84849
1/*- 2 * Copyright (c) 2001, Jake Burkholder 3 * Copyright (C) 1994, David Greenman 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the University of Utah, and William Jolitz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 39 * from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19 40 * $FreeBSD: head/sys/sparc64/sparc64/trap.c 84849 2001-10-12 16:06:41Z tmm $ 41 */ 42 43#include "opt_ddb.h" 44#include "opt_ktr.h" 45 46#include <sys/param.h> 47#include <sys/bus.h> 48#include <sys/interrupt.h> 49#include <sys/ktr.h> 50#include <sys/lock.h> 51#include <sys/mutex.h> 52#include <sys/systm.h> 53#include <sys/pioctl.h> 54#include <sys/proc.h> 55#include <sys/syscall.h> 56#include <sys/sysent.h> 57#include <sys/user.h> 58#include <sys/vmmeter.h> 59 60#include <vm/vm.h> 61#include <vm/pmap.h> 62#include <vm/vm_extern.h> 63#include <vm/vm_param.h> 64#include <vm/vm_kern.h> 65#include <vm/vm_map.h> 66#include <vm/vm_page.h> 67 68#include <machine/clock.h> 69#include <machine/frame.h> 70#include <machine/intr_machdep.h> 71#include <machine/pcb.h> 72#include <machine/pv.h> 73#include <machine/trap.h> 74#include <machine/tstate.h> 75#include <machine/tte.h> 76#include <machine/tlb.h> 77#include <machine/tsb.h> 78#include <machine/watch.h> 79 80void trap(struct trapframe *tf); 81int trap_mmu_fault(struct thread *td, struct trapframe *tf); 82void syscall(struct trapframe *tf); 83 84u_long trap_mask = 0xffffffffffffffffL & ~(1 << T_INTR); 85 86extern char fsbail[]; 87 88extern char *syscallnames[]; 89 90const char *trap_msg[] = { 91 "reserved", 92 "power on reset", 93 "watchdog reset", 94 "externally initiated reset", 95 "software initiated reset", 96 "red state exception", 97 "instruction access exception", 98 "instruction access error", 99 "illegal instruction", 100 "privileged opcode", 101 "floating point disabled", 102 "floating point exception ieee 754", 103 "floating point exception other", 104 "tag overflow", 105 "division by zero", 106 "data access exception", 107 "data access error", 108 "memory address not aligned", 109 "lddf memory address not aligned", 110 "stdf memory address not aligned", 111 "privileged action", 112 "interrupt vector", 113 "physical address watchpoint", 114 "virtual address watchpoint", 115 "corrected ecc error", 116 "fast instruction access mmu miss", 117 "fast data access mmu miss", 118 "fast data access protection", 119 "spill", 120 "fill", 121 "fill", 122 "breakpoint", 123 "syscall", 124 "trap instruction", 125}; 126 127void 128trap(struct trapframe *tf) 129{ 130 struct thread *td; 131 struct proc *p; 132 u_int sticks; 133 int error; 134 int ucode; 135 int mask; 136 int type; 137 int sig; 138 139 KASSERT(PCPU_GET(curthread) != NULL, ("trap: curthread NULL")); 140 KASSERT(PCPU_GET(curthread)->td_kse != NULL, ("trap: curkse NULL")); 141 KASSERT(PCPU_GET(curthread)->td_proc != NULL, ("trap: curproc NULL")); 142 143 atomic_add_int(&cnt.v_trap, 1); 144 145 td = PCPU_GET(curthread); 146 p = td->td_proc; 147 148 error = 0; 149 type = tf->tf_type; 150 ucode = type; /* XXX */ 151 sticks = 0; 152 153 CTR5(KTR_TRAP, "trap: %s type=%s (%s) ws=%#lx ow=%#lx", 154 p->p_comm, trap_msg[type & ~T_KERNEL], 155 ((type & T_KERNEL) ? "kernel" : "user"), 156 rdpr(wstate), rdpr(otherwin)); 157 158 if ((type & T_KERNEL) == 0) { 159 sticks = td->td_kse->ke_sticks; 160 td->td_frame = tf; 161 } 162 163 switch (type) { 164 165 /* 166 * User Mode Traps 167 */ 168 case T_ALIGN: 169 case T_ALIGN_LDDF: 170 case T_ALIGN_STDF: 171 sig = SIGBUS; 172 goto trapsig; 173 case T_BREAKPOINT: 174 sig = SIGTRAP; 175 goto trapsig; 176 case T_DIVIDE: 177 sig = SIGFPE; 178 goto trapsig; 179 case T_FP_DISABLED: 180 if (fp_enable_thread(td)) 181 goto user; 182 /* Fallthrough. */ 183 case T_FP_IEEE: 184 case T_FP_OTHER: 185 sig = SIGFPE; 186 goto trapsig; 187 case T_DATA_ERROR: 188 case T_DATA_EXCPTN: 189 case T_INSN_ERROR: 190 case T_INSN_EXCPTN: 191 sig = SIGILL; /* XXX */ 192 goto trapsig; 193 case T_DMMU_MISS: 194 case T_DMMU_PROT: 195 case T_IMMU_MISS: 196 error = trap_mmu_fault(td, tf); 197 if (error == 0) 198 goto user; 199 sig = error; 200 goto trapsig; 201 case T_FILL: 202 if (rwindow_load(td, tf, 2)) { 203 PROC_LOCK(p); 204 sigexit(td, SIGILL); 205 /* Not reached. */ 206 } 207 goto out; 208 case T_FILL_RET: 209 if (rwindow_load(td, tf, 1)) { 210 PROC_LOCK(p); 211 sigexit(td, SIGILL); 212 /* Not reached. */ 213 } 214 goto out; 215 case T_INSN_ILLEGAL: 216 sig = SIGILL; 217 goto trapsig; 218 case T_PRIV_ACTION: 219 case T_PRIV_OPCODE: 220 sig = SIGBUS; 221 goto trapsig; 222 case T_SOFT: 223 sig = SIGILL; 224 goto trapsig; 225 case T_SPILL: 226 if (rwindow_save(td)) { 227 PROC_LOCK(p); 228 sigexit(td, SIGILL); 229 /* Not reached. */ 230 } 231 goto out; 232 case T_TAG_OVFLW: 233 sig = SIGEMT; 234 goto trapsig; 235 236 /* 237 * Kernel Mode Traps 238 */ 239#ifdef DDB 240 case T_BREAKPOINT | T_KERNEL: 241 if (kdb_trap(tf) != 0) 242 goto out; 243 break; 244#endif 245 case T_DMMU_MISS | T_KERNEL: 246 case T_DMMU_PROT | T_KERNEL: 247 error = trap_mmu_fault(td, tf); 248 if (error == 0) 249 goto out; 250 break; 251 case T_WATCH_VIRT | T_KERNEL: 252 /* 253 * At the moment, just print the information from the trap, 254 * remove the watchpoint, use evil magic to execute the 255 * instruction (we temporarily save the instruction at 256 * %tnpc, write a trap instruction, resume, and reset the 257 * watch point when the trap arrives). 258 * To make sure that no interrupt gets in between and creates 259 * a potentially large window where the watchpoint is inactive, 260 * disable interrupts temporarily. 261 * This is obviously fragile and evilish. 262 */ 263 printf("Virtual watchpoint triggered, tpc=0x%lx, tnpc=0x%lx\n", 264 tf->tf_tpc, tf->tf_tnpc); 265 PCPU_SET(wp_pstate, (tf->tf_tstate & TSTATE_PSTATE_MASK) >> 266 TSTATE_PSTATE_SHIFT); 267 tf->tf_tstate &= ~TSTATE_IE; 268 wrpr(pstate, rdpr(pstate), PSTATE_IE); 269 PCPU_SET(wp_insn, *((u_int *)tf->tf_tnpc)); 270 *((u_int *)tf->tf_tnpc) = 0x91d03002; /* ta %xcc, 2 */ 271 flush(tf->tf_tnpc); 272 PCPU_SET(wp_va, watch_virt_get(&mask)); 273 PCPU_SET(wp_mask, mask); 274 watch_virt_clear(); 275 goto out; 276 case T_RESTOREWP | T_KERNEL: 277 /* 278 * Undo the tweaks tone for T_WATCH, reset the watch point and 279 * contunue execution. 280 * Note that here, we run with interrupts enabled, so there 281 * is a small chance that we will be interrupted before we 282 * could reset the watch point. 283 */ 284 tf->tf_tstate = (tf->tf_tstate & ~TSTATE_PSTATE_MASK) | 285 PCPU_GET(wp_pstate) << TSTATE_PSTATE_SHIFT; 286 watch_virt_set_mask(PCPU_GET(wp_va), PCPU_GET(wp_mask)); 287 *(u_int *)tf->tf_tpc = PCPU_GET(wp_insn); 288 flush(tf->tf_tpc); 289 goto out; 290 default: 291 break; 292 } 293 panic("trap: %s", trap_msg[type & ~T_KERNEL]); 294 295trapsig: 296 /* Translate fault for emulators. */ 297 if (p->p_sysent->sv_transtrap != NULL) 298 sig = (p->p_sysent->sv_transtrap)(sig, type); 299 trapsignal(p, sig, ucode); 300user: 301 userret(td, tf, sticks); 302out: 303 CTR1(KTR_TRAP, "trap: td=%p return", td); 304 return; 305} 306 307int 308trap_mmu_fault(struct thread *td, struct trapframe *tf) 309{ 310 struct mmuframe *mf; 311 struct vmspace *vm; 312 struct stte *stp; 313 struct pcb *pcb; 314 struct tte tte; 315 struct proc *p; 316 vm_offset_t va; 317 vm_prot_t prot; 318 u_long ctx; 319 pmap_t pm; 320 int flags; 321 int type; 322 int rv; 323 324 p = td->td_proc; 325 KASSERT(td->td_pcb != NULL, ("trap_dmmu_miss: pcb NULL")); 326 KASSERT(p->p_vmspace != NULL, ("trap_dmmu_miss: vmspace NULL")); 327 328 rv = KERN_SUCCESS; 329 mf = (struct mmuframe *)tf->tf_arg; 330 ctx = TLB_TAR_CTX(mf->mf_tar); 331 pcb = td->td_pcb; 332 type = tf->tf_type & ~T_KERNEL; 333 va = TLB_TAR_VA(mf->mf_tar); 334 stp = NULL; 335 336 CTR4(KTR_TRAP, "trap_mmu_fault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx", 337 td, p->p_vmspace->vm_pmap.pm_context, va, ctx); 338 339 if (type == T_DMMU_PROT) { 340 prot = VM_PROT_WRITE; 341 flags = VM_FAULT_DIRTY; 342 } else { 343 if (type == T_DMMU_MISS) 344 prot = VM_PROT_READ; 345 else 346 prot = VM_PROT_READ | VM_PROT_EXECUTE; 347 flags = VM_FAULT_NORMAL; 348 } 349 350 if (ctx == TLB_CTX_KERNEL) { 351 mtx_lock(&Giant); 352 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL); 353 mtx_unlock(&Giant); 354 if (rv == KERN_SUCCESS) { 355 stp = tsb_kvtostte(va); 356 tte = stp->st_tte; 357 if (type == T_IMMU_MISS) 358 tlb_store(TLB_DTLB | TLB_ITLB, va, ctx, tte); 359 else 360 tlb_store(TLB_DTLB, va, ctx, tte); 361 } 362 } else if (tf->tf_type & T_KERNEL && 363 (td->td_intr_nesting_level != 0 || pcb->pcb_onfault == NULL || 364 pcb->pcb_onfault == fsbail)) { 365 rv = KERN_FAILURE; 366 } else { 367 mtx_lock(&Giant); 368 vm = p->p_vmspace; 369 pm = &vm->vm_pmap; 370 stp = tsb_stte_lookup(pm, va); 371 if (stp == NULL || type == T_DMMU_PROT) { 372 /* 373 * Keep the process from being swapped out at this 374 * critical time. 375 */ 376 PROC_LOCK(p); 377 ++p->p_lock; 378 PROC_UNLOCK(p); 379 380 /* 381 * Grow the stack if necessary. vm_map_growstack only 382 * fails if the va falls into a growable stack region 383 * and the stack growth fails. If it succeeds, or the 384 * va was not within a growable stack region, fault in 385 * the user page. 386 */ 387 if (vm_map_growstack(p, va) != KERN_SUCCESS) 388 rv = KERN_FAILURE; 389 else 390 rv = vm_fault(&vm->vm_map, va, prot, flags); 391 392 /* 393 * Now the process can be swapped again. 394 */ 395 PROC_LOCK(p); 396 --p->p_lock; 397 PROC_UNLOCK(p); 398 } else { 399 stp = tsb_stte_promote(pm, va, stp); 400 stp->st_tte.tte_data |= TD_REF; 401 switch (type) { 402 case T_IMMU_MISS: 403 if ((stp->st_tte.tte_data & TD_EXEC) == 0) { 404 rv = KERN_FAILURE; 405 break; 406 } 407 tlb_store(TLB_DTLB | TLB_ITLB, va, ctx, 408 stp->st_tte); 409 break; 410 case T_DMMU_PROT: 411 if ((stp->st_tte.tte_data & TD_SW) == 0) { 412 rv = KERN_FAILURE; 413 break; 414 } 415 /* Fallthrough. */ 416 case T_DMMU_MISS: 417 tlb_store(TLB_DTLB, va, ctx, stp->st_tte); 418 break; 419 } 420 } 421 mtx_unlock(&Giant); 422 } 423 CTR3(KTR_TRAP, "trap_mmu_fault: return p=%p va=%#lx rv=%d", p, va, rv); 424 if (rv == KERN_SUCCESS) 425 return (0); 426 if (tf->tf_type & T_KERNEL) { 427 if (pcb->pcb_onfault != NULL && ctx != TLB_CTX_KERNEL) { 428 tf->tf_tpc = (u_long)pcb->pcb_onfault; 429 tf->tf_tnpc = tf->tf_tpc + 4; 430 return (0); 431 } 432 } 433 return (rv == KERN_PROTECTION_FAILURE ? SIGBUS : SIGSEGV); 434} 435 436/* Maximum number of arguments that can be passed via the out registers. */ 437#define REG_MAXARGS 6 438 439/* 440 * Syscall handler. The arguments to the syscall are passed in the o registers 441 * by the caller, and are saved in the trap frame. The syscall number is passed 442 * in %g1 (and also saved in the trap frame). 443 */ 444void 445syscall(struct trapframe *tf) 446{ 447 struct sysent *callp; 448 struct thread *td; 449 register_t args[8]; 450 register_t *argp; 451 struct proc *p; 452 u_int sticks; 453 u_long code; 454 u_long tpc; 455 int reg; 456 int regcnt; 457 int narg; 458 int error; 459 460 KASSERT(PCPU_GET(curthread) != NULL, ("trap: curthread NULL")); 461 KASSERT(PCPU_GET(curthread)->td_kse != NULL, ("trap: curkse NULL")); 462 KASSERT(PCPU_GET(curthread)->td_proc != NULL, ("trap: curproc NULL")); 463 464 atomic_add_int(&cnt.v_syscall, 1); 465 466 td = PCPU_GET(curthread); 467 p = td->td_proc; 468 469 narg = 0; 470 error = 0; 471 reg = 0; 472 regcnt = REG_MAXARGS; 473 474 sticks = td->td_kse->ke_sticks; 475 td->td_frame = tf; 476 code = tf->tf_global[1]; 477 478 /* 479 * For syscalls, we don't want to retry the faulting instruction 480 * (usually), instead we need to advance one instruction. 481 */ 482 tpc = tf->tf_tpc; 483 tf->tf_tpc = tf->tf_tnpc; 484 tf->tf_tnpc += 4; 485 486 if (p->p_sysent->sv_prepsyscall) { 487 /* 488 * The prep code is MP aware. 489 */ 490#if 0 491 (*p->p_sysent->sv_prepsyscall)(tf, args, &code, ¶ms); 492#endif 493 } else if (code == SYS_syscall || code == SYS___syscall) { 494 code = tf->tf_out[reg++]; 495 regcnt--; 496 } 497 498 if (p->p_sysent->sv_mask) 499 code &= p->p_sysent->sv_mask; 500 501 if (code >= p->p_sysent->sv_size) 502 callp = &p->p_sysent->sv_table[0]; 503 else 504 callp = &p->p_sysent->sv_table[code]; 505 506 narg = callp->sy_narg & SYF_ARGMASK; 507 508 if (narg <= regcnt) 509 argp = &tf->tf_out[reg]; 510 else { 511 KASSERT(narg <= sizeof(args) / sizeof(args[0]), 512 ("Too many syscall arguments!")); 513 argp = args; 514 bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt); 515 error = copyin((void *)(tf->tf_out[6] + SPOFF + 516 offsetof(struct frame, f_pad[6])), 517 &args[reg + regcnt], (narg - regcnt) * sizeof(args[0])); 518 if (error != 0) 519 goto bad; 520 } 521 522 CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td, 523 syscallnames[code], argp[0], argp[1], argp[2]); 524 525 /* 526 * Try to run the syscall without the MP lock if the syscall 527 * is MP safe. 528 */ 529 if ((callp->sy_narg & SYF_MPSAFE) == 0) 530 mtx_lock(&Giant); 531 532#ifdef KTRACE 533 /* 534 * We have to obtain the MP lock no matter what if 535 * we are ktracing 536 */ 537 if (KTRPOINT(p, KTR_SYSCALL)) { 538 ktrsyscall(p->p_tracep, code, narg, args); 539 } 540#endif 541 td->td_retval[0] = 0; 542 td->td_retval[1] = tf->tf_out[1]; 543 544 STOPEVENT(p, S_SCE, narg); /* MP aware */ 545 546 error = (*callp->sy_call)(td, argp); 547 548 CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p, 549 error, syscallnames[code], td->td_retval[0], td->td_retval[1]); 550 551 /* 552 * MP SAFE (we may or may not have the MP lock at this point) 553 */ 554 switch (error) { 555 case 0: 556 tf->tf_out[0] = td->td_retval[0]; 557 tf->tf_out[1] = td->td_retval[1]; 558 tf->tf_tstate &= ~TSTATE_XCC_C; 559 break; 560 561 case ERESTART: 562 /* 563 * Undo the tpc advancement we have done above, we want to 564 * reexecute the system call. 565 */ 566 tf->tf_tpc = tpc; 567 tf->tf_tnpc -= 4; 568 break; 569 570 case EJUSTRETURN: 571 break; 572 573 default: 574bad: 575 if (p->p_sysent->sv_errsize) { 576 if (error >= p->p_sysent->sv_errsize) 577 error = -1; /* XXX */ 578 else 579 error = p->p_sysent->sv_errtbl[error]; 580 } 581 tf->tf_out[0] = error; 582 tf->tf_tstate |= TSTATE_XCC_C; 583 break; 584 } 585 586 /* 587 * Handle reschedule and other end-of-syscall issues 588 */ 589 userret(td, tf, sticks); 590 591#ifdef KTRACE 592 if (KTRPOINT(p, KTR_SYSRET)) { 593 ktrsysret(p->p_tracep, code, error, td->td_retval[0]); 594 } 595#endif 596 597 /* 598 * Release Giant if we had to get it. Don't use mtx_owned(), 599 * we want to catch broken syscalls. 600 */ 601 if ((callp->sy_narg & SYF_MPSAFE) == 0) 602 mtx_unlock(&Giant); 603 604 /* 605 * This works because errno is findable through the 606 * register set. If we ever support an emulation where this 607 * is not the case, this code will need to be revisited. 608 */ 609 STOPEVENT(p, S_SCX, code); 610 611#ifdef WITNESS 612 if (witness_list(td)) { 613 panic("system call %s returning with mutex(s) held\n", 614 syscallnames[code]); 615 } 616#endif 617 mtx_assert(&sched_lock, MA_NOTOWNED); 618 mtx_assert(&Giant, MA_NOTOWNED); 619} 620