trap.c revision 233748
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 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 35 * from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19 36 */ 37 38#include <sys/cdefs.h> 39__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/trap.c 233748 2012-03-31 14:03:16Z marius $"); 40 41#include "opt_ddb.h" 42#include "opt_ktr.h" 43 44#include <sys/param.h> 45#include <sys/kdb.h> 46#include <sys/kernel.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/pcpu.h> 54#include <sys/pioctl.h> 55#include <sys/ptrace.h> 56#include <sys/proc.h> 57#include <sys/smp.h> 58#include <sys/signalvar.h> 59#include <sys/syscall.h> 60#include <sys/sysctl.h> 61#include <sys/sysent.h> 62#include <sys/vmmeter.h> 63#include <security/audit/audit.h> 64 65#include <dev/ofw/openfirm.h> 66 67#include <vm/vm.h> 68#include <vm/pmap.h> 69#include <vm/vm_extern.h> 70#include <vm/vm_param.h> 71#include <vm/vm_kern.h> 72#include <vm/vm_map.h> 73#include <vm/vm_page.h> 74 75#include <machine/cpu.h> 76#include <machine/frame.h> 77#include <machine/intr_machdep.h> 78#include <machine/ofw_machdep.h> 79#include <machine/pcb.h> 80#include <machine/smp.h> 81#include <machine/trap.h> 82#include <machine/tstate.h> 83#include <machine/tte.h> 84#include <machine/tlb.h> 85#include <machine/tsb.h> 86#include <machine/watch.h> 87 88void trap(struct trapframe *tf); 89void syscall(struct trapframe *tf); 90 91static int trap_cecc(void); 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 fas_fault[]; 105extern char fas_nofault_begin[]; 106extern char fas_nofault_end[]; 107 108const char *const trap_msg[] = { 109 "reserved", 110 "instruction access exception", 111 "instruction access error", 112 "instruction access protection", 113 "illtrap instruction", 114 "illegal instruction", 115 "privileged opcode", 116 "floating point disabled", 117 "floating point exception ieee 754", 118 "floating point exception other", 119 "tag overflow", 120 "division by zero", 121 "data access exception", 122 "data access error", 123 "data access protection", 124 "memory address not aligned", 125 "privileged action", 126 "async data error", 127 "trap instruction 16", 128 "trap instruction 17", 129 "trap instruction 18", 130 "trap instruction 19", 131 "trap instruction 20", 132 "trap instruction 21", 133 "trap instruction 22", 134 "trap instruction 23", 135 "trap instruction 24", 136 "trap instruction 25", 137 "trap instruction 26", 138 "trap instruction 27", 139 "trap instruction 28", 140 "trap instruction 29", 141 "trap instruction 30", 142 "trap instruction 31", 143 "fast instruction access mmu miss", 144 "fast data access mmu miss", 145 "interrupt", 146 "physical address watchpoint", 147 "virtual address watchpoint", 148 "corrected ecc error", 149 "spill", 150 "fill", 151 "fill", 152 "breakpoint", 153 "clean window", 154 "range check", 155 "fix alignment", 156 "integer overflow", 157 "syscall", 158 "restore physical watchpoint", 159 "restore virtual watchpoint", 160 "kernel stack fault", 161}; 162 163static const int trap_sig[] = { 164 SIGILL, /* reserved */ 165 SIGILL, /* instruction access exception */ 166 SIGILL, /* instruction access error */ 167 SIGILL, /* instruction access protection */ 168 SIGILL, /* illtrap instruction */ 169 SIGILL, /* illegal instruction */ 170 SIGBUS, /* privileged opcode */ 171 SIGFPE, /* floating point disabled */ 172 SIGFPE, /* floating point exception ieee 754 */ 173 SIGFPE, /* floating point exception other */ 174 SIGEMT, /* tag overflow */ 175 SIGFPE, /* division by zero */ 176 SIGILL, /* data access exception */ 177 SIGILL, /* data access error */ 178 SIGBUS, /* data access protection */ 179 SIGBUS, /* memory address not aligned */ 180 SIGBUS, /* privileged action */ 181 SIGBUS, /* async data error */ 182 SIGILL, /* trap instruction 16 */ 183 SIGILL, /* trap instruction 17 */ 184 SIGILL, /* trap instruction 18 */ 185 SIGILL, /* trap instruction 19 */ 186 SIGILL, /* trap instruction 20 */ 187 SIGILL, /* trap instruction 21 */ 188 SIGILL, /* trap instruction 22 */ 189 SIGILL, /* trap instruction 23 */ 190 SIGILL, /* trap instruction 24 */ 191 SIGILL, /* trap instruction 25 */ 192 SIGILL, /* trap instruction 26 */ 193 SIGILL, /* trap instruction 27 */ 194 SIGILL, /* trap instruction 28 */ 195 SIGILL, /* trap instruction 29 */ 196 SIGILL, /* trap instruction 30 */ 197 SIGILL, /* trap instruction 31 */ 198 SIGSEGV, /* fast instruction access mmu miss */ 199 SIGSEGV, /* fast data access mmu miss */ 200 -1, /* interrupt */ 201 -1, /* physical address watchpoint */ 202 -1, /* virtual address watchpoint */ 203 -1, /* corrected ecc error */ 204 SIGILL, /* spill */ 205 SIGILL, /* fill */ 206 SIGILL, /* fill */ 207 SIGTRAP, /* breakpoint */ 208 SIGILL, /* clean window */ 209 SIGILL, /* range check */ 210 SIGILL, /* fix alignment */ 211 SIGILL, /* integer overflow */ 212 SIGSYS, /* syscall */ 213 -1, /* restore physical watchpoint */ 214 -1, /* restore virtual watchpoint */ 215 -1, /* kernel stack fault */ 216}; 217 218CTASSERT(sizeof(trap_msg) / sizeof(*trap_msg) == T_MAX); 219CTASSERT(sizeof(trap_sig) / sizeof(*trap_sig) == T_MAX); 220 221CTASSERT(sizeof(struct trapframe) == 256); 222 223int debugger_on_signal = 0; 224SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW, 225 &debugger_on_signal, 0, ""); 226 227u_int corrected_ecc = 0; 228SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0, 229 "corrected ECC errors"); 230 231/* 232 * SUNW,set-trap-table allows to take over %tba from the PROM, which 233 * will turn off interrupts and handle outstanding ones while doing so, 234 * in a safe way. 235 */ 236void 237sun4u_set_traptable(void *tba_addr) 238{ 239 static struct { 240 cell_t name; 241 cell_t nargs; 242 cell_t nreturns; 243 cell_t tba_addr; 244 } args = { 245 (cell_t)"SUNW,set-trap-table", 246 1, 247 0, 248 }; 249 250 args.tba_addr = (cell_t)tba_addr; 251 ofw_entry(&args); 252} 253 254void 255trap(struct trapframe *tf) 256{ 257 struct thread *td; 258 struct proc *p; 259 int error; 260 int sig; 261 register_t addr; 262 ksiginfo_t ksi; 263 264 td = curthread; 265 266 CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td, 267 trap_msg[tf->tf_type & ~T_KERNEL], 268 (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil)); 269 270 PCPU_INC(cnt.v_trap); 271 272 if ((tf->tf_tstate & TSTATE_PRIV) == 0) { 273 KASSERT(td != NULL, ("trap: curthread NULL")); 274 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 275 276 p = td->td_proc; 277 td->td_pticks = 0; 278 td->td_frame = tf; 279 addr = tf->tf_tpc; 280 if (td->td_ucred != p->p_ucred) 281 cred_update_thread(td); 282 283 switch (tf->tf_type) { 284 case T_DATA_MISS: 285 case T_DATA_PROTECTION: 286 addr = tf->tf_sfar; 287 /* FALLTHROUGH */ 288 case T_INSTRUCTION_MISS: 289 sig = trap_pfault(td, tf); 290 break; 291 case T_FILL: 292 sig = rwindow_load(td, tf, 2); 293 break; 294 case T_FILL_RET: 295 sig = rwindow_load(td, tf, 1); 296 break; 297 case T_SPILL: 298 sig = rwindow_save(td); 299 break; 300 case T_CORRECTED_ECC_ERROR: 301 sig = trap_cecc(); 302 break; 303 default: 304 if (tf->tf_type > T_MAX) 305 panic("trap: bad trap type %#lx (user)", 306 tf->tf_type); 307 else if (trap_sig[tf->tf_type] == -1) 308 panic("trap: %s (user)", 309 trap_msg[tf->tf_type]); 310 sig = trap_sig[tf->tf_type]; 311 break; 312 } 313 314 if (sig != 0) { 315 /* Translate fault for emulators. */ 316 if (p->p_sysent->sv_transtrap != NULL) { 317 sig = p->p_sysent->sv_transtrap(sig, 318 tf->tf_type); 319 } 320 if (debugger_on_signal && 321 (sig == 4 || sig == 10 || sig == 11)) 322 kdb_enter(KDB_WHY_TRAPSIG, "trapsig"); 323 ksiginfo_init_trap(&ksi); 324 ksi.ksi_signo = sig; 325 ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */ 326 ksi.ksi_addr = (void *)addr; 327 ksi.ksi_trapno = (int)tf->tf_type; 328 trapsignal(td, &ksi); 329 } 330 331 userret(td, tf); 332 mtx_assert(&Giant, MA_NOTOWNED); 333 } else { 334 KASSERT((tf->tf_type & T_KERNEL) != 0, 335 ("trap: kernel trap isn't")); 336 337 if (kdb_active) { 338 kdb_reenter(); 339 return; 340 } 341 342 switch (tf->tf_type & ~T_KERNEL) { 343 case T_BREAKPOINT: 344 case T_KSTACK_FAULT: 345 error = (kdb_trap(tf->tf_type, 0, tf) == 0); 346 TF_DONE(tf); 347 break; 348#ifdef notyet 349 case T_PA_WATCHPOINT: 350 case T_VA_WATCHPOINT: 351 error = db_watch_trap(tf); 352 break; 353#endif 354 case T_DATA_MISS: 355 case T_DATA_PROTECTION: 356 case T_INSTRUCTION_MISS: 357 error = trap_pfault(td, tf); 358 break; 359 case T_DATA_EXCEPTION: 360 case T_MEM_ADDRESS_NOT_ALIGNED: 361 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && 362 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { 363 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 364 tf->tf_tpc <= (u_long)copy_nofault_end) { 365 tf->tf_tpc = (u_long)copy_fault; 366 tf->tf_tnpc = tf->tf_tpc + 4; 367 error = 0; 368 break; 369 } 370 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 371 tf->tf_tpc <= (u_long)fs_nofault_end) { 372 tf->tf_tpc = (u_long)fs_fault; 373 tf->tf_tnpc = tf->tf_tpc + 4; 374 error = 0; 375 break; 376 } 377 } 378 error = 1; 379 break; 380 case T_DATA_ERROR: 381 /* 382 * Handle PCI poke/peek as per UltraSPARC IIi 383 * User's Manual 16.2.1, modulo checking the 384 * TPC as USIII CPUs generate a precise trap 385 * instead of a special deferred one. 386 */ 387 if (tf->tf_tpc > (u_long)fas_nofault_begin && 388 tf->tf_tpc < (u_long)fas_nofault_end) { 389 cache_flush(); 390 cache_enable(PCPU_GET(impl)); 391 tf->tf_tpc = (u_long)fas_fault; 392 tf->tf_tnpc = tf->tf_tpc + 4; 393 error = 0; 394 break; 395 } 396 error = 1; 397 break; 398 case T_CORRECTED_ECC_ERROR: 399 error = trap_cecc(); 400 break; 401 default: 402 error = 1; 403 break; 404 } 405 406 if (error != 0) { 407 tf->tf_type &= ~T_KERNEL; 408 if (tf->tf_type > T_MAX) 409 panic("trap: bad trap type %#lx (kernel)", 410 tf->tf_type); 411 panic("trap: %s (kernel)", trap_msg[tf->tf_type]); 412 } 413 } 414 CTR1(KTR_TRAP, "trap: td=%p return", td); 415} 416 417static int 418trap_cecc(void) 419{ 420 u_long eee; 421 422 /* 423 * Turn off (non-)correctable error reporting while we're dealing 424 * with the error. 425 */ 426 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG); 427 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN | 428 AA_ESTATE_CEEN)); 429 /* Flush the caches in order ensure no corrupt data got installed. */ 430 cache_flush(); 431 /* Ensure the caches are still turned on (should be). */ 432 cache_enable(PCPU_GET(impl)); 433 /* Clear the error from the AFSR. */ 434 stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); 435 corrected_ecc++; 436 printf("corrected ECC error\n"); 437 /* Turn (non-)correctable error reporting back on. */ 438 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); 439 return (0); 440} 441 442static int 443trap_pfault(struct thread *td, struct trapframe *tf) 444{ 445 struct vmspace *vm; 446 struct proc *p; 447 vm_offset_t va; 448 vm_prot_t prot; 449 vm_map_entry_t entry; 450 u_long ctx; 451 int type; 452 int rv; 453 454 if (td == NULL) 455 return (-1); 456 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL")); 457 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL")); 458 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); 459 460 p = td->td_proc; 461 462 rv = KERN_SUCCESS; 463 ctx = TLB_TAR_CTX(tf->tf_tar); 464 type = tf->tf_type & ~T_KERNEL; 465 va = TLB_TAR_VA(tf->tf_tar); 466 467 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx", 468 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx); 469 470 if (type == T_DATA_PROTECTION) 471 prot = VM_PROT_WRITE; 472 else { 473 if (type == T_DATA_MISS) 474 prot = VM_PROT_READ; 475 else 476 prot = VM_PROT_READ | VM_PROT_EXECUTE; 477 } 478 479 if (ctx != TLB_CTX_KERNEL) { 480 if ((tf->tf_tstate & TSTATE_PRIV) != 0 && 481 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin && 482 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) { 483 tf->tf_tpc = (u_long)fs_fault; 484 tf->tf_tnpc = tf->tf_tpc + 4; 485 return (0); 486 } 487 488 /* 489 * This is a fault on non-kernel virtual memory. 490 */ 491 vm = p->p_vmspace; 492 493 /* 494 * Keep swapout from messing with us during this 495 * critical time. 496 */ 497 PROC_LOCK(p); 498 ++p->p_lock; 499 PROC_UNLOCK(p); 500 501 /* Fault in the user page. */ 502 rv = vm_fault(&vm->vm_map, va, prot, VM_FAULT_NORMAL); 503 504 /* 505 * Now the process can be swapped again. 506 */ 507 PROC_LOCK(p); 508 --p->p_lock; 509 PROC_UNLOCK(p); 510 } else { 511 /* 512 * This is a fault on kernel virtual memory. Attempts to 513 * access kernel memory from user mode cause privileged 514 * action traps, not page fault. 515 */ 516 KASSERT(tf->tf_tstate & TSTATE_PRIV, 517 ("trap_pfault: fault on nucleus context from user mode")); 518 519 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 520 tf->tf_tpc <= (u_long)copy_nofault_end) { 521 vm_map_lock_read(kernel_map); 522 if (vm_map_lookup_entry(kernel_map, va, &entry) && 523 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) { 524 tf->tf_tpc = (u_long)copy_fault; 525 tf->tf_tnpc = tf->tf_tpc + 4; 526 vm_map_unlock_read(kernel_map); 527 return (0); 528 } 529 vm_map_unlock_read(kernel_map); 530 } 531 532 /* 533 * We don't have to worry about process locking or stacks in 534 * the kernel. 535 */ 536 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL); 537 } 538 539 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", 540 td, va, rv); 541 if (rv == KERN_SUCCESS) 542 return (0); 543 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { 544 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 545 tf->tf_tpc <= (u_long)fs_nofault_end) { 546 tf->tf_tpc = (u_long)fs_fault; 547 tf->tf_tnpc = tf->tf_tpc + 4; 548 return (0); 549 } 550 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 551 tf->tf_tpc <= (u_long)copy_nofault_end) { 552 tf->tf_tpc = (u_long)copy_fault; 553 tf->tf_tnpc = tf->tf_tpc + 4; 554 return (0); 555 } 556 } 557 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 558} 559 560/* Maximum number of arguments that can be passed via the out registers. */ 561#define REG_MAXARGS 6 562 563int 564cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 565{ 566 struct trapframe *tf; 567 struct proc *p; 568 register_t *argp; 569 int reg; 570 int regcnt; 571 int error; 572 573 p = td->td_proc; 574 tf = td->td_frame; 575 reg = 0; 576 regcnt = REG_MAXARGS; 577 578 sa->code = tf->tf_global[1]; 579 580 if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 581 sa->code = tf->tf_out[reg++]; 582 regcnt--; 583 } 584 585 if (p->p_sysent->sv_mask) 586 sa->code &= p->p_sysent->sv_mask; 587 if (sa->code >= p->p_sysent->sv_size) 588 sa->callp = &p->p_sysent->sv_table[0]; 589 else 590 sa->callp = &p->p_sysent->sv_table[sa->code]; 591 592 sa->narg = sa->callp->sy_narg; 593 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), 594 ("Too many syscall arguments!")); 595 error = 0; 596 argp = sa->args; 597 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt); 598 if (sa->narg > regcnt) 599 error = copyin((void *)(tf->tf_out[6] + SPOFF + 600 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt], 601 (sa->narg - regcnt) * sizeof(sa->args[0])); 602 if (error == 0) { 603 td->td_retval[0] = 0; 604 td->td_retval[1] = 0; 605 } 606 607 return (error); 608} 609 610#include "../../kern/subr_syscall.c" 611 612/* 613 * Syscall handler 614 * The arguments to the syscall are passed in the out registers by the caller, 615 * and are saved in the trap frame. The syscall number is passed in %g1 (and 616 * also saved in the trap frame). 617 */ 618void 619syscall(struct trapframe *tf) 620{ 621 struct thread *td; 622 struct syscall_args sa; 623 int error; 624 625 td = curthread; 626 td->td_frame = tf; 627 628 KASSERT(td != NULL, ("trap: curthread NULL")); 629 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 630 631 /* 632 * For syscalls, we don't want to retry the faulting instruction 633 * (usually), instead we need to advance one instruction. 634 */ 635 td->td_pcb->pcb_tpc = tf->tf_tpc; 636 TF_DONE(tf); 637 638 error = syscallenter(td, &sa); 639 syscallret(td, error, &sa); 640} 641