trap.c revision 302408
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: stable/11/sys/sparc64/sparc64/trap.c 298352 2016-04-20 15:45:55Z pfg $"); 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(nitems(trap_msg) == T_MAX); 219CTASSERT(nitems(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_cowgen != p->p_cowgen) 281 thread_cow_update(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 } else { 333 KASSERT((tf->tf_type & T_KERNEL) != 0, 334 ("trap: kernel trap isn't")); 335 336 if (kdb_active) { 337 kdb_reenter(); 338 return; 339 } 340 341 switch (tf->tf_type & ~T_KERNEL) { 342 case T_BREAKPOINT: 343 case T_KSTACK_FAULT: 344 error = (kdb_trap(tf->tf_type, 0, tf) == 0); 345 TF_DONE(tf); 346 break; 347#ifdef notyet 348 case T_PA_WATCHPOINT: 349 case T_VA_WATCHPOINT: 350 error = db_watch_trap(tf); 351 break; 352#endif 353 case T_DATA_MISS: 354 case T_DATA_PROTECTION: 355 case T_INSTRUCTION_MISS: 356 error = trap_pfault(td, tf); 357 break; 358 case T_DATA_EXCEPTION: 359 case T_MEM_ADDRESS_NOT_ALIGNED: 360 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && 361 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { 362 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 363 tf->tf_tpc <= (u_long)copy_nofault_end) { 364 tf->tf_tpc = (u_long)copy_fault; 365 tf->tf_tnpc = tf->tf_tpc + 4; 366 error = 0; 367 break; 368 } 369 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 370 tf->tf_tpc <= (u_long)fs_nofault_end) { 371 tf->tf_tpc = (u_long)fs_fault; 372 tf->tf_tnpc = tf->tf_tpc + 4; 373 error = 0; 374 break; 375 } 376 } 377 error = 1; 378 break; 379 case T_DATA_ERROR: 380 /* 381 * Handle PCI poke/peek as per UltraSPARC IIi 382 * User's Manual 16.2.1, modulo checking the 383 * TPC as USIII CPUs generate a precise trap 384 * instead of a special deferred one. 385 */ 386 if (tf->tf_tpc > (u_long)fas_nofault_begin && 387 tf->tf_tpc < (u_long)fas_nofault_end) { 388 cache_flush(); 389 cache_enable(PCPU_GET(impl)); 390 tf->tf_tpc = (u_long)fas_fault; 391 tf->tf_tnpc = tf->tf_tpc + 4; 392 error = 0; 393 break; 394 } 395 error = 1; 396 break; 397 case T_CORRECTED_ECC_ERROR: 398 error = trap_cecc(); 399 break; 400 default: 401 error = 1; 402 break; 403 } 404 405 if (error != 0) { 406 tf->tf_type &= ~T_KERNEL; 407 if (tf->tf_type > T_MAX) 408 panic("trap: bad trap type %#lx (kernel)", 409 tf->tf_type); 410 panic("trap: %s (kernel)", 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 vm_map_t map; 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 /* This is a fault on non-kernel virtual memory. */ 488 map = &p->p_vmspace->vm_map; 489 } else { 490 /* 491 * This is a fault on kernel virtual memory. Attempts to 492 * access kernel memory from user mode cause privileged 493 * action traps, not page fault. 494 */ 495 KASSERT(tf->tf_tstate & TSTATE_PRIV, 496 ("trap_pfault: fault on nucleus context from user mode")); 497 498 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 499 tf->tf_tpc <= (u_long)copy_nofault_end) { 500 vm_map_lock_read(kernel_map); 501 if (vm_map_lookup_entry(kernel_map, va, &entry) && 502 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) { 503 tf->tf_tpc = (u_long)copy_fault; 504 tf->tf_tnpc = tf->tf_tpc + 4; 505 vm_map_unlock_read(kernel_map); 506 return (0); 507 } 508 vm_map_unlock_read(kernel_map); 509 } 510 map = kernel_map; 511 } 512 513 /* Fault in the page. */ 514 rv = vm_fault(map, va, prot, VM_FAULT_NORMAL); 515 516 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", 517 td, va, rv); 518 if (rv == KERN_SUCCESS) 519 return (0); 520 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { 521 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 522 tf->tf_tpc <= (u_long)fs_nofault_end) { 523 tf->tf_tpc = (u_long)fs_fault; 524 tf->tf_tnpc = tf->tf_tpc + 4; 525 return (0); 526 } 527 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 528 tf->tf_tpc <= (u_long)copy_nofault_end) { 529 tf->tf_tpc = (u_long)copy_fault; 530 tf->tf_tnpc = tf->tf_tpc + 4; 531 return (0); 532 } 533 } 534 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 535} 536 537/* Maximum number of arguments that can be passed via the out registers. */ 538#define REG_MAXARGS 6 539 540int 541cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 542{ 543 struct trapframe *tf; 544 struct proc *p; 545 register_t *argp; 546 int reg; 547 int regcnt; 548 int error; 549 550 p = td->td_proc; 551 tf = td->td_frame; 552 reg = 0; 553 regcnt = REG_MAXARGS; 554 555 sa->code = tf->tf_global[1]; 556 557 if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 558 sa->code = tf->tf_out[reg++]; 559 regcnt--; 560 } 561 562 if (p->p_sysent->sv_mask) 563 sa->code &= p->p_sysent->sv_mask; 564 if (sa->code >= p->p_sysent->sv_size) 565 sa->callp = &p->p_sysent->sv_table[0]; 566 else 567 sa->callp = &p->p_sysent->sv_table[sa->code]; 568 569 sa->narg = sa->callp->sy_narg; 570 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), 571 ("Too many syscall arguments!")); 572 error = 0; 573 argp = sa->args; 574 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt); 575 if (sa->narg > regcnt) 576 error = copyin((void *)(tf->tf_out[6] + SPOFF + 577 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt], 578 (sa->narg - regcnt) * sizeof(sa->args[0])); 579 if (error == 0) { 580 td->td_retval[0] = 0; 581 td->td_retval[1] = 0; 582 } 583 584 return (error); 585} 586 587#include "../../kern/subr_syscall.c" 588 589/* 590 * Syscall handler 591 * The arguments to the syscall are passed in the out registers by the caller, 592 * and are saved in the trap frame. The syscall number is passed in %g1 (and 593 * also saved in the trap frame). 594 */ 595void 596syscall(struct trapframe *tf) 597{ 598 struct thread *td; 599 struct syscall_args sa; 600 int error; 601 602 td = curthread; 603 td->td_frame = tf; 604 605 KASSERT(td != NULL, ("trap: curthread NULL")); 606 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 607 608 /* 609 * For syscalls, we don't want to retry the faulting instruction 610 * (usually), instead we need to advance one instruction. 611 */ 612 td->td_pcb->pcb_tpc = tf->tf_tpc; 613 TF_DONE(tf); 614 615 error = syscallenter(td, &sa); 616 syscallret(td, error, &sa); 617} 618