trap.c revision 219608
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 219608 2011-03-13 13:42:43Z 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(struct trapframe) == 256); 219 220int debugger_on_signal = 0; 221SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW, 222 &debugger_on_signal, 0, ""); 223 224u_int corrected_ecc = 0; 225SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0, 226 "corrected ECC errors"); 227 228/* 229 * SUNW,set-trap-table allows to take over %tba from the PROM, which 230 * will turn off interrupts and handle outstanding ones while doing so, 231 * in a safe way. 232 */ 233void 234sun4u_set_traptable(void *tba_addr) 235{ 236 static struct { 237 cell_t name; 238 cell_t nargs; 239 cell_t nreturns; 240 cell_t tba_addr; 241 } args = { 242 (cell_t)"SUNW,set-trap-table", 243 1, 244 0, 245 }; 246 247 args.tba_addr = (cell_t)tba_addr; 248 ofw_entry(&args); 249} 250 251void 252trap(struct trapframe *tf) 253{ 254 struct thread *td; 255 struct proc *p; 256 int error; 257 int sig; 258 register_t addr; 259 ksiginfo_t ksi; 260 261 td = curthread; 262 263 CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td, 264 trap_msg[tf->tf_type & ~T_KERNEL], 265 (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil)); 266 267 PCPU_INC(cnt.v_trap); 268 269 if ((tf->tf_tstate & TSTATE_PRIV) == 0) { 270 KASSERT(td != NULL, ("trap: curthread NULL")); 271 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 272 273 p = td->td_proc; 274 td->td_pticks = 0; 275 td->td_frame = tf; 276 addr = tf->tf_tpc; 277 if (td->td_ucred != p->p_ucred) 278 cred_update_thread(td); 279 280 switch (tf->tf_type) { 281 case T_DATA_MISS: 282 case T_DATA_PROTECTION: 283 addr = tf->tf_sfar; 284 /* FALLTHROUGH */ 285 case T_INSTRUCTION_MISS: 286 sig = trap_pfault(td, tf); 287 break; 288 case T_FILL: 289 sig = rwindow_load(td, tf, 2); 290 break; 291 case T_FILL_RET: 292 sig = rwindow_load(td, tf, 1); 293 break; 294 case T_SPILL: 295 sig = rwindow_save(td); 296 break; 297 case T_CORRECTED_ECC_ERROR: 298 sig = trap_cecc(); 299 break; 300 default: 301 if (tf->tf_type < 0 || tf->tf_type >= T_MAX) 302 panic("trap: bad trap type %#lx (user)", 303 tf->tf_type); 304 else if (trap_sig[tf->tf_type] == -1) 305 panic("trap: %s (user)", 306 trap_msg[tf->tf_type]); 307 sig = trap_sig[tf->tf_type]; 308 break; 309 } 310 311 if (sig != 0) { 312 /* Translate fault for emulators. */ 313 if (p->p_sysent->sv_transtrap != NULL) { 314 sig = p->p_sysent->sv_transtrap(sig, 315 tf->tf_type); 316 } 317 if (debugger_on_signal && 318 (sig == 4 || sig == 10 || sig == 11)) 319 kdb_enter(KDB_WHY_TRAPSIG, "trapsig"); 320 ksiginfo_init_trap(&ksi); 321 ksi.ksi_signo = sig; 322 ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */ 323 ksi.ksi_addr = (void *)addr; 324 ksi.ksi_trapno = (int)tf->tf_type; 325 trapsignal(td, &ksi); 326 } 327 328 userret(td, tf); 329 mtx_assert(&Giant, MA_NOTOWNED); 330 } else { 331 KASSERT((tf->tf_type & T_KERNEL) != 0, 332 ("trap: kernel trap isn't")); 333 334 if (kdb_active) { 335 kdb_reenter(); 336 return; 337 } 338 339 switch (tf->tf_type & ~T_KERNEL) { 340 case T_BREAKPOINT: 341 case T_KSTACK_FAULT: 342 error = (kdb_trap(tf->tf_type, 0, tf) == 0); 343 TF_DONE(tf); 344 break; 345#ifdef notyet 346 case T_PA_WATCHPOINT: 347 case T_VA_WATCHPOINT: 348 error = db_watch_trap(tf); 349 break; 350#endif 351 case T_DATA_MISS: 352 case T_DATA_PROTECTION: 353 case T_INSTRUCTION_MISS: 354 error = trap_pfault(td, tf); 355 break; 356 case T_DATA_EXCEPTION: 357 case T_MEM_ADDRESS_NOT_ALIGNED: 358 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && 359 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { 360 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 361 tf->tf_tpc <= (u_long)copy_nofault_end) { 362 tf->tf_tpc = (u_long)copy_fault; 363 tf->tf_tnpc = tf->tf_tpc + 4; 364 error = 0; 365 break; 366 } 367 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 368 tf->tf_tpc <= (u_long)fs_nofault_end) { 369 tf->tf_tpc = (u_long)fs_fault; 370 tf->tf_tnpc = tf->tf_tpc + 4; 371 error = 0; 372 break; 373 } 374 } 375 error = 1; 376 break; 377 case T_DATA_ERROR: 378 /* 379 * Handle PCI poke/peek as per UltraSPARC IIi 380 * User's Manual 16.2.1, modulo checking the 381 * TPC as USIII CPUs generate a precise trap 382 * instead of a special deferred one. 383 */ 384 if (tf->tf_tpc > (u_long)fas_nofault_begin && 385 tf->tf_tpc < (u_long)fas_nofault_end) { 386 cache_flush(); 387 cache_enable(PCPU_GET(impl)); 388 tf->tf_tpc = (u_long)fas_fault; 389 tf->tf_tnpc = tf->tf_tpc + 4; 390 error = 0; 391 break; 392 } 393 error = 1; 394 break; 395 case T_CORRECTED_ECC_ERROR: 396 error = trap_cecc(); 397 break; 398 default: 399 error = 1; 400 break; 401 } 402 403 if (error != 0) { 404 tf->tf_type &= ~T_KERNEL; 405 if (tf->tf_type < 0 || tf->tf_type >= T_MAX) 406 panic("trap: bad trap type %#lx (kernel)", 407 tf->tf_type); 408 else if (trap_sig[tf->tf_type] == -1) 409 panic("trap: %s (kernel)", 410 trap_msg[tf->tf_type]); 411 } 412 } 413 CTR1(KTR_TRAP, "trap: td=%p return", td); 414} 415 416static int 417trap_cecc(void) 418{ 419 u_long eee; 420 421 /* 422 * Turn off (non-)correctable error reporting while we're dealing 423 * with the error. 424 */ 425 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG); 426 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN | 427 AA_ESTATE_CEEN)); 428 /* Flush the caches in order ensure no corrupt data got installed. */ 429 cache_flush(); 430 /* Ensure the caches are still turned on (should be). */ 431 cache_enable(PCPU_GET(impl)); 432 /* Clear the error from the AFSR. */ 433 stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); 434 corrected_ecc++; 435 printf("corrected ECC error\n"); 436 /* Turn (non-)correctable error reporting back on. */ 437 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); 438 return (0); 439} 440 441static int 442trap_pfault(struct thread *td, struct trapframe *tf) 443{ 444 struct vmspace *vm; 445 struct proc *p; 446 vm_offset_t va; 447 vm_prot_t prot; 448 vm_map_entry_t entry; 449 u_long ctx; 450 int type; 451 int rv; 452 453 if (td == NULL) 454 return (-1); 455 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL")); 456 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL")); 457 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); 458 459 p = td->td_proc; 460 461 rv = KERN_SUCCESS; 462 ctx = TLB_TAR_CTX(tf->tf_tar); 463 type = tf->tf_type & ~T_KERNEL; 464 va = TLB_TAR_VA(tf->tf_tar); 465 466 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx", 467 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx); 468 469 if (type == T_DATA_PROTECTION) 470 prot = VM_PROT_WRITE; 471 else { 472 if (type == T_DATA_MISS) 473 prot = VM_PROT_READ; 474 else 475 prot = VM_PROT_READ | VM_PROT_EXECUTE; 476 } 477 478 if (ctx != TLB_CTX_KERNEL) { 479 if ((tf->tf_tstate & TSTATE_PRIV) != 0 && 480 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin && 481 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) { 482 tf->tf_tpc = (u_long)fs_fault; 483 tf->tf_tnpc = tf->tf_tpc + 4; 484 return (0); 485 } 486 487 /* 488 * This is a fault on non-kernel virtual memory. 489 */ 490 vm = p->p_vmspace; 491 492 /* 493 * Keep swapout from messing with us during this 494 * critical time. 495 */ 496 PROC_LOCK(p); 497 ++p->p_lock; 498 PROC_UNLOCK(p); 499 500 /* Fault in the user page. */ 501 rv = vm_fault(&vm->vm_map, va, prot, VM_FAULT_NORMAL); 502 503 /* 504 * Now the process can be swapped again. 505 */ 506 PROC_LOCK(p); 507 --p->p_lock; 508 PROC_UNLOCK(p); 509 } else { 510 /* 511 * This is a fault on kernel virtual memory. Attempts to 512 * access kernel memory from user mode cause privileged 513 * action traps, not page fault. 514 */ 515 KASSERT(tf->tf_tstate & TSTATE_PRIV, 516 ("trap_pfault: fault on nucleus context from user mode")); 517 518 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 519 tf->tf_tpc <= (u_long)copy_nofault_end) { 520 vm_map_lock_read(kernel_map); 521 if (vm_map_lookup_entry(kernel_map, va, &entry) && 522 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) { 523 tf->tf_tpc = (u_long)copy_fault; 524 tf->tf_tnpc = tf->tf_tpc + 4; 525 vm_map_unlock_read(kernel_map); 526 return (0); 527 } 528 vm_map_unlock_read(kernel_map); 529 } 530 531 /* 532 * We don't have to worry about process locking or stacks in 533 * the kernel. 534 */ 535 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL); 536 } 537 538 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", 539 td, va, rv); 540 if (rv == KERN_SUCCESS) 541 return (0); 542 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { 543 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 544 tf->tf_tpc <= (u_long)fs_nofault_end) { 545 tf->tf_tpc = (u_long)fs_fault; 546 tf->tf_tnpc = tf->tf_tpc + 4; 547 return (0); 548 } 549 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 550 tf->tf_tpc <= (u_long)copy_nofault_end) { 551 tf->tf_tpc = (u_long)copy_fault; 552 tf->tf_tnpc = tf->tf_tpc + 4; 553 return (0); 554 } 555 } 556 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 557} 558 559/* Maximum number of arguments that can be passed via the out registers. */ 560#define REG_MAXARGS 6 561 562int 563cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 564{ 565 struct trapframe *tf; 566 struct proc *p; 567 register_t *argp; 568 int reg; 569 int regcnt; 570 int error; 571 572 p = td->td_proc; 573 tf = td->td_frame; 574 reg = 0; 575 regcnt = REG_MAXARGS; 576 577 sa->code = tf->tf_global[1]; 578 579 if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 580 sa->code = tf->tf_out[reg++]; 581 regcnt--; 582 } 583 584 if (p->p_sysent->sv_mask) 585 sa->code &= p->p_sysent->sv_mask; 586 if (sa->code >= p->p_sysent->sv_size) 587 sa->callp = &p->p_sysent->sv_table[0]; 588 else 589 sa->callp = &p->p_sysent->sv_table[sa->code]; 590 591 sa->narg = sa->callp->sy_narg; 592 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), 593 ("Too many syscall arguments!")); 594 error = 0; 595 argp = sa->args; 596 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt); 597 if (sa->narg > regcnt) 598 error = copyin((void *)(tf->tf_out[6] + SPOFF + 599 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt], 600 (sa->narg - regcnt) * sizeof(sa->args[0])); 601 if (error == 0) { 602 td->td_retval[0] = 0; 603 td->td_retval[1] = 0; 604 } 605 606 return (error); 607} 608 609/* 610 * Syscall handler 611 * The arguments to the syscall are passed in the out registers by the caller, 612 * and are saved in the trap frame. The syscall number is passed in %g1 (and 613 * also saved in the trap frame). 614 */ 615void 616syscall(struct trapframe *tf) 617{ 618 struct thread *td; 619 struct syscall_args sa; 620 int error; 621 622 td = curthread; 623 td->td_frame = tf; 624 625 KASSERT(td != NULL, ("trap: curthread NULL")); 626 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 627 628 /* 629 * For syscalls, we don't want to retry the faulting instruction 630 * (usually), instead we need to advance one instruction. 631 */ 632 td->td_pcb->pcb_tpc = tf->tf_tpc; 633 TF_DONE(tf); 634 635 error = syscallenter(td, &sa); 636 syscallret(td, error, &sa); 637} 638