trap.c revision 111883
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 111883 2003-03-04 21:03:05Z jhb $ 41 */ 42 43#include "opt_ddb.h" 44#include "opt_ktr.h" 45#include "opt_ktrace.h" 46 47#include <sys/param.h> 48#include <sys/kernel.h> 49#include <sys/bus.h> 50#include <sys/interrupt.h> 51#include <sys/ktr.h> 52#include <sys/lock.h> 53#include <sys/mutex.h> 54#include <sys/systm.h> 55#include <sys/pioctl.h> 56#include <sys/proc.h> 57#include <sys/smp.h> 58#include <sys/syscall.h> 59#include <sys/sysctl.h> 60#include <sys/sysent.h> 61#include <sys/user.h> 62#include <sys/vmmeter.h> 63#ifdef KTRACE 64#include <sys/uio.h> 65#include <sys/ktrace.h> 66#endif 67 68#include <vm/vm.h> 69#include <vm/pmap.h> 70#include <vm/vm_extern.h> 71#include <vm/vm_param.h> 72#include <vm/vm_kern.h> 73#include <vm/vm_map.h> 74#include <vm/vm_page.h> 75 76#include <machine/clock.h> 77#include <machine/cpu.h> 78#include <machine/frame.h> 79#include <machine/intr_machdep.h> 80#include <machine/pcb.h> 81#include <machine/smp.h> 82#include <machine/trap.h> 83#include <machine/tstate.h> 84#include <machine/tte.h> 85#include <machine/tlb.h> 86#include <machine/tsb.h> 87#include <machine/watch.h> 88 89void trap(struct trapframe *tf); 90void syscall(struct trapframe *tf); 91 92static int trap_pfault(struct thread *td, struct trapframe *tf); 93 94extern char copy_fault[]; 95extern char copy_nofault_begin[]; 96extern char copy_nofault_end[]; 97 98extern char fs_fault[]; 99extern char fs_nofault_begin[]; 100extern char fs_nofault_end[]; 101extern char fs_nofault_intr_begin[]; 102extern char fs_nofault_intr_end[]; 103 104extern char *syscallnames[]; 105 106const char *trap_msg[] = { 107 "reserved", 108 "instruction access exception", 109 "instruction access error", 110 "instruction access protection", 111 "illtrap instruction", 112 "illegal instruction", 113 "privileged opcode", 114 "floating point disabled", 115 "floating point exception ieee 754", 116 "floating point exception other", 117 "tag overflow", 118 "division by zero", 119 "data access exception", 120 "data access error", 121 "data access protection", 122 "memory address not aligned", 123 "privileged action", 124 "async data error", 125 "trap instruction 16", 126 "trap instruction 17", 127 "trap instruction 18", 128 "trap instruction 19", 129 "trap instruction 20", 130 "trap instruction 21", 131 "trap instruction 22", 132 "trap instruction 23", 133 "trap instruction 24", 134 "trap instruction 25", 135 "trap instruction 26", 136 "trap instruction 27", 137 "trap instruction 28", 138 "trap instruction 29", 139 "trap instruction 30", 140 "trap instruction 31", 141 "interrupt", 142 "physical address watchpoint", 143 "virtual address watchpoint", 144 "corrected ecc error", 145 "fast instruction access mmu miss", 146 "fast data access mmu miss", 147 "spill", 148 "fill", 149 "fill", 150 "breakpoint", 151 "clean window", 152 "range check", 153 "fix alignment", 154 "integer overflow", 155 "syscall", 156 "restore physical watchpoint", 157 "restore virtual watchpoint", 158 "kernel stack fault", 159}; 160 161const int trap_sig[] = { 162 SIGILL, /* reserved */ 163 SIGILL, /* instruction access exception */ 164 SIGILL, /* instruction access error */ 165 SIGILL, /* instruction access protection */ 166 SIGILL, /* illtrap instruction */ 167 SIGILL, /* illegal instruction */ 168 SIGBUS, /* privileged opcode */ 169 SIGFPE, /* floating point disabled */ 170 SIGFPE, /* floating point exception ieee 754 */ 171 SIGFPE, /* floating point exception other */ 172 SIGEMT, /* tag overflow */ 173 SIGFPE, /* division by zero */ 174 SIGILL, /* data access exception */ 175 SIGILL, /* data access error */ 176 SIGBUS, /* data access protection */ 177 SIGBUS, /* memory address not aligned */ 178 SIGBUS, /* privileged action */ 179 SIGBUS, /* async data error */ 180 SIGILL, /* trap instruction 16 */ 181 SIGILL, /* trap instruction 17 */ 182 SIGILL, /* trap instruction 18 */ 183 SIGILL, /* trap instruction 19 */ 184 SIGILL, /* trap instruction 20 */ 185 SIGILL, /* trap instruction 21 */ 186 SIGILL, /* trap instruction 22 */ 187 SIGILL, /* trap instruction 23 */ 188 SIGILL, /* trap instruction 24 */ 189 SIGILL, /* trap instruction 25 */ 190 SIGILL, /* trap instruction 26 */ 191 SIGILL, /* trap instruction 27 */ 192 SIGILL, /* trap instruction 28 */ 193 SIGILL, /* trap instruction 29 */ 194 SIGILL, /* trap instruction 30 */ 195 SIGILL, /* trap instruction 31 */ 196 -1, /* interrupt */ 197 -1, /* physical address watchpoint */ 198 -1, /* virtual address watchpoint */ 199 -1, /* corrected ecc error */ 200 SIGSEGV, /* fast instruction access mmu miss */ 201 SIGSEGV, /* fast data access mmu miss */ 202 SIGILL, /* spill */ 203 SIGILL, /* fill */ 204 SIGILL, /* fill */ 205 SIGTRAP, /* breakpoint */ 206 SIGILL, /* clean window */ 207 SIGILL, /* range check */ 208 SIGILL, /* fix alignment */ 209 SIGILL, /* integer overflow */ 210 SIGSYS, /* syscall */ 211 -1, /* restore physical watchpoint */ 212 -1, /* restore virtual watchpoint */ 213 -1, /* kernel stack fault */ 214}; 215 216CTASSERT(sizeof(struct trapframe) == 256); 217 218int debugger_on_signal = 0; 219SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW, 220 &debugger_on_signal, 0, ""); 221 222void 223trap(struct trapframe *tf) 224{ 225 struct thread *td; 226 struct proc *p; 227 u_int sticks; 228 int error; 229 int sig; 230 231 td = PCPU_GET(curthread); 232 233 CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td, 234 trap_msg[tf->tf_type & ~T_KERNEL], 235 (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil)); 236 237 atomic_add_int(&cnt.v_trap, 1); 238 239 if ((tf->tf_tstate & TSTATE_PRIV) == 0) { 240 KASSERT(td != NULL, ("trap: curthread NULL")); 241 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 242 243 p = td->td_proc; 244 sticks = td->td_sticks; 245 td->td_frame = tf; 246 if (td->td_ucred != p->p_ucred) 247 cred_update_thread(td); 248 if ((p->p_flag & P_WEXIT) && (p->p_singlethread != td)) { 249 PROC_LOCK(p); 250 mtx_lock_spin(&sched_lock); 251 thread_exit(); 252 /* NOTREACHED */ 253 } 254 255 switch (tf->tf_type) { 256 case T_DATA_MISS: 257 case T_DATA_PROTECTION: 258 case T_INSTRUCTION_MISS: 259 sig = trap_pfault(td, tf); 260 break; 261 case T_FILL: 262 sig = rwindow_load(td, tf, 2); 263 break; 264 case T_FILL_RET: 265 sig = rwindow_load(td, tf, 1); 266 break; 267 case T_SPILL: 268 sig = rwindow_save(td); 269 break; 270 default: 271 if (tf->tf_type < 0 || tf->tf_type >= T_MAX || 272 trap_sig[tf->tf_type] == -1) 273 panic("trap: bad trap type"); 274 sig = trap_sig[tf->tf_type]; 275 break; 276 } 277 278 if (sig != 0) { 279 /* Translate fault for emulators. */ 280 if (p->p_sysent->sv_transtrap != NULL) { 281 sig = p->p_sysent->sv_transtrap(sig, 282 tf->tf_type); 283 } 284 if (debugger_on_signal && 285 (sig == 4 || sig == 10 || sig == 11)) 286 Debugger("trapsig"); 287 trapsignal(p, sig, tf->tf_type); 288 } 289 290 userret(td, tf, sticks); 291 mtx_assert(&Giant, MA_NOTOWNED); 292#ifdef DIAGNOSTIC 293 cred_free_thread(td); 294#endif 295 } else { 296 KASSERT((tf->tf_type & T_KERNEL) != 0, 297 ("trap: kernel trap isn't")); 298 299 switch (tf->tf_type & ~T_KERNEL) { 300#ifdef DDB 301 case T_BREAKPOINT: 302 case T_KSTACK_FAULT: 303 error = (kdb_trap(tf) == 0); 304 break; 305#ifdef notyet 306 case T_PA_WATCHPOINT: 307 case T_VA_WATCHPOINT: 308 error = db_watch_trap(tf); 309 break; 310#endif 311#endif 312 case T_DATA_MISS: 313 case T_DATA_PROTECTION: 314 case T_INSTRUCTION_MISS: 315 error = trap_pfault(td, tf); 316 break; 317 case T_DATA_EXCEPTION: 318 case T_MEM_ADDRESS_NOT_ALIGNED: 319 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && 320 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { 321 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 322 tf->tf_tpc <= (u_long)copy_nofault_end) { 323 tf->tf_tpc = (u_long)copy_fault; 324 tf->tf_tnpc = tf->tf_tpc + 4; 325 error = 0; 326 break; 327 } 328 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 329 tf->tf_tpc <= (u_long)fs_nofault_end) { 330 tf->tf_tpc = (u_long)fs_fault; 331 tf->tf_tnpc = tf->tf_tpc + 4; 332 error = 0; 333 break; 334 } 335 } 336 error = 1; 337 break; 338 default: 339 error = 1; 340 break; 341 } 342 343 if (error != 0) 344 panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]); 345 } 346 CTR1(KTR_TRAP, "trap: td=%p return", td); 347} 348 349static int 350trap_pfault(struct thread *td, struct trapframe *tf) 351{ 352 struct vmspace *vm; 353 struct pcb *pcb; 354 struct proc *p; 355 vm_offset_t va; 356 vm_prot_t prot; 357 u_long ctx; 358 int flags; 359 int type; 360 int rv; 361 362 if (td == NULL) 363 return (-1); 364 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL")); 365 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL")); 366 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); 367 368 p = td->td_proc; 369 370 rv = KERN_SUCCESS; 371 ctx = TLB_TAR_CTX(tf->tf_tar); 372 pcb = td->td_pcb; 373 type = tf->tf_type & ~T_KERNEL; 374 va = TLB_TAR_VA(tf->tf_tar); 375 376 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx", 377 td, p->p_vmspace->vm_pmap.pm_context[PCPU_GET(cpuid)], va, ctx); 378 379 if (type == T_DATA_PROTECTION) { 380 prot = VM_PROT_WRITE; 381 flags = VM_FAULT_DIRTY; 382 } else { 383 if (type == T_DATA_MISS) 384 prot = VM_PROT_READ; 385 else 386 prot = VM_PROT_READ | VM_PROT_EXECUTE; 387 flags = VM_FAULT_NORMAL; 388 } 389 390 if (ctx != TLB_CTX_KERNEL) { 391 if ((tf->tf_tstate & TSTATE_PRIV) != 0 && 392 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin && 393 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) { 394 tf->tf_tpc = (u_long)fs_fault; 395 tf->tf_tnpc = tf->tf_tpc + 4; 396 return (0); 397 } 398 399 /* 400 * This is a fault on non-kernel virtual memory. 401 */ 402 vm = p->p_vmspace; 403 404 /* 405 * Keep swapout from messing with us during this 406 * critical time. 407 */ 408 PROC_LOCK(p); 409 ++p->p_lock; 410 PROC_UNLOCK(p); 411 412 /* Fault in the user page. */ 413 rv = vm_fault(&vm->vm_map, va, prot, flags); 414 415 /* 416 * Now the process can be swapped again. 417 */ 418 PROC_LOCK(p); 419 --p->p_lock; 420 PROC_UNLOCK(p); 421 } else { 422 /* 423 * This is a fault on kernel virtual memory. Attempts to 424 * access kernel memory from user mode cause privileged 425 * action traps, not page fault. 426 */ 427 KASSERT(tf->tf_tstate & TSTATE_PRIV, 428 ("trap_pfault: fault on nucleus context from user mode")); 429 430 /* 431 * Don't have to worry about process locking or stacks in the 432 * kernel. 433 */ 434 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL); 435 } 436 437 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", 438 td, va, rv); 439 if (rv == KERN_SUCCESS) 440 return (0); 441 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { 442 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 443 tf->tf_tpc <= (u_long)fs_nofault_end) { 444 tf->tf_tpc = (u_long)fs_fault; 445 tf->tf_tnpc = tf->tf_tpc + 4; 446 return (0); 447 } 448 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 449 tf->tf_tpc <= (u_long)copy_nofault_end) { 450 tf->tf_tpc = (u_long)copy_fault; 451 tf->tf_tnpc = tf->tf_tpc + 4; 452 return (0); 453 } 454 } 455 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 456} 457 458/* Maximum number of arguments that can be passed via the out registers. */ 459#define REG_MAXARGS 6 460 461/* 462 * Syscall handler. The arguments to the syscall are passed in the o registers 463 * by the caller, and are saved in the trap frame. The syscall number is passed 464 * in %g1 (and also saved in the trap frame). 465 */ 466void 467syscall(struct trapframe *tf) 468{ 469 struct sysent *callp; 470 struct thread *td; 471 register_t args[8]; 472 register_t *argp; 473 struct proc *p; 474 u_int sticks; 475 u_long code; 476 u_long tpc; 477 int reg; 478 int regcnt; 479 int narg; 480 int error; 481 482 td = PCPU_GET(curthread); 483 KASSERT(td != NULL, ("trap: curthread NULL")); 484 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 485 486 p = td->td_proc; 487 488 atomic_add_int(&cnt.v_syscall, 1); 489 490 narg = 0; 491 error = 0; 492 reg = 0; 493 regcnt = REG_MAXARGS; 494 495 sticks = td->td_sticks; 496 td->td_frame = tf; 497 if (td->td_ucred != p->p_ucred) 498 cred_update_thread(td); 499 if (p->p_flag & P_THREADED) 500 thread_user_enter(p, td); 501 code = tf->tf_global[1]; 502 503 /* 504 * For syscalls, we don't want to retry the faulting instruction 505 * (usually), instead we need to advance one instruction. 506 */ 507 tpc = tf->tf_tpc; 508 TF_DONE(tf); 509 510 if (p->p_sysent->sv_prepsyscall) { 511 /* 512 * The prep code is MP aware. 513 */ 514#if 0 515 (*p->p_sysent->sv_prepsyscall)(tf, args, &code, ¶ms); 516#endif 517 } else if (code == SYS_syscall || code == SYS___syscall) { 518 code = tf->tf_out[reg++]; 519 regcnt--; 520 } 521 522 if (p->p_sysent->sv_mask) 523 code &= p->p_sysent->sv_mask; 524 525 if (code >= p->p_sysent->sv_size) 526 callp = &p->p_sysent->sv_table[0]; 527 else 528 callp = &p->p_sysent->sv_table[code]; 529 530 narg = callp->sy_narg & SYF_ARGMASK; 531 532 if (narg <= regcnt) { 533 argp = &tf->tf_out[reg]; 534 error = 0; 535 } else { 536 KASSERT(narg <= sizeof(args) / sizeof(args[0]), 537 ("Too many syscall arguments!")); 538 argp = args; 539 bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt); 540 error = copyin((void *)(tf->tf_out[6] + SPOFF + 541 offsetof(struct frame, fr_pad[6])), 542 &args[regcnt], (narg - regcnt) * sizeof(args[0])); 543 } 544 545 CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td, 546 syscallnames[code], argp[0], argp[1], argp[2]); 547 548 /* 549 * Try to run the syscall without the MP lock if the syscall 550 * is MP safe. 551 */ 552 if ((callp->sy_narg & SYF_MPSAFE) == 0) 553 mtx_lock(&Giant); 554 555#ifdef KTRACE 556 if (KTRPOINT(td, KTR_SYSCALL)) 557 ktrsyscall(code, narg, argp); 558#endif 559 if (error == 0) { 560 td->td_retval[0] = 0; 561 td->td_retval[1] = 0; 562 563 STOPEVENT(p, S_SCE, narg); /* MP aware */ 564 565 error = (*callp->sy_call)(td, argp); 566 567 CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p, 568 error, syscallnames[code], td->td_retval[0], 569 td->td_retval[1]); 570 } 571 572 /* 573 * MP SAFE (we may or may not have the MP lock at this point) 574 */ 575 switch (error) { 576 case 0: 577 tf->tf_out[0] = td->td_retval[0]; 578 tf->tf_out[1] = td->td_retval[1]; 579 tf->tf_tstate &= ~TSTATE_XCC_C; 580 break; 581 582 case ERESTART: 583 /* 584 * Undo the tpc advancement we have done above, we want to 585 * reexecute the system call. 586 */ 587 tf->tf_tpc = tpc; 588 tf->tf_tnpc -= 4; 589 break; 590 591 case EJUSTRETURN: 592 break; 593 594 default: 595 if (p->p_sysent->sv_errsize) { 596 if (error >= p->p_sysent->sv_errsize) 597 error = -1; /* XXX */ 598 else 599 error = p->p_sysent->sv_errtbl[error]; 600 } 601 tf->tf_out[0] = error; 602 tf->tf_tstate |= TSTATE_XCC_C; 603 break; 604 } 605 606 /* 607 * Release Giant if we had to get it. Don't use mtx_owned(), 608 * we want to catch broken syscalls. 609 */ 610 if ((callp->sy_narg & SYF_MPSAFE) == 0) 611 mtx_unlock(&Giant); 612 613 /* 614 * Handle reschedule and other end-of-syscall issues 615 */ 616 userret(td, tf, sticks); 617 618#ifdef KTRACE 619 if (KTRPOINT(td, KTR_SYSRET)) 620 ktrsysret(code, error, td->td_retval[0]); 621#endif 622 /* 623 * This works because errno is findable through the 624 * register set. If we ever support an emulation where this 625 * is not the case, this code will need to be revisited. 626 */ 627 STOPEVENT(p, S_SCX, code); 628 629#ifdef DIAGNOSTIC 630 cred_free_thread(td); 631#endif 632 WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", 633 syscallnames[code]); 634 mtx_assert(&sched_lock, MA_NOTOWNED); 635 mtx_assert(&Giant, MA_NOTOWNED); 636} 637