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 337061 2018-08-01 20:38:01Z jhb $"); 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, ucode; 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 ucode = (int)tf->tf_type; /* XXX not POSIX */ 281 if (td->td_cowgen != p->p_cowgen) 282 thread_cow_update(td); 283 284 switch (tf->tf_type) { 285 case T_DATA_MISS: 286 case T_DATA_PROTECTION: 287 addr = tf->tf_sfar; 288 /* FALLTHROUGH */ 289 case T_INSTRUCTION_MISS: 290 sig = trap_pfault(td, tf); 291 break; 292 case T_FILL: 293 sig = rwindow_load(td, tf, 2); 294 break; 295 case T_FILL_RET: 296 sig = rwindow_load(td, tf, 1); 297 break; 298 case T_SPILL: 299 sig = rwindow_save(td); 300 break; 301 case T_CORRECTED_ECC_ERROR: 302 sig = trap_cecc(); 303 break; 304 case T_BREAKPOINT: 305 sig = SIGTRAP; 306 ucode = TRAP_BRKPT; 307 break; 308 default: 309 if (tf->tf_type > T_MAX) 310 panic("trap: bad trap type %#lx (user)", 311 tf->tf_type); 312 else if (trap_sig[tf->tf_type] == -1) 313 panic("trap: %s (user)", 314 trap_msg[tf->tf_type]); 315 sig = trap_sig[tf->tf_type]; 316 break; 317 } 318 319 if (sig != 0) { 320 /* Translate fault for emulators. */ 321 if (p->p_sysent->sv_transtrap != NULL) { 322 sig = p->p_sysent->sv_transtrap(sig, 323 tf->tf_type); 324 } 325 if (debugger_on_signal && 326 (sig == 4 || sig == 10 || sig == 11)) 327 kdb_enter(KDB_WHY_TRAPSIG, "trapsig"); 328 ksiginfo_init_trap(&ksi); 329 ksi.ksi_signo = sig; 330 ksi.ksi_code = ucode; 331 ksi.ksi_addr = (void *)addr; 332 ksi.ksi_trapno = (int)tf->tf_type; 333 trapsignal(td, &ksi); 334 } 335 336 userret(td, tf); 337 } else { 338 KASSERT((tf->tf_type & T_KERNEL) != 0, 339 ("trap: kernel trap isn't")); 340 341 if (kdb_active) { 342 kdb_reenter(); 343 return; 344 } 345 346 switch (tf->tf_type & ~T_KERNEL) { 347 case T_BREAKPOINT: 348 case T_KSTACK_FAULT: 349 error = (kdb_trap(tf->tf_type, 0, tf) == 0); 350 TF_DONE(tf); 351 break; 352#ifdef notyet 353 case T_PA_WATCHPOINT: 354 case T_VA_WATCHPOINT: 355 error = db_watch_trap(tf); 356 break; 357#endif 358 case T_DATA_MISS: 359 case T_DATA_PROTECTION: 360 case T_INSTRUCTION_MISS: 361 error = trap_pfault(td, tf); 362 break; 363 case T_DATA_EXCEPTION: 364 case T_MEM_ADDRESS_NOT_ALIGNED: 365 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && 366 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { 367 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 368 tf->tf_tpc <= (u_long)copy_nofault_end) { 369 tf->tf_tpc = (u_long)copy_fault; 370 tf->tf_tnpc = tf->tf_tpc + 4; 371 error = 0; 372 break; 373 } 374 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 375 tf->tf_tpc <= (u_long)fs_nofault_end) { 376 tf->tf_tpc = (u_long)fs_fault; 377 tf->tf_tnpc = tf->tf_tpc + 4; 378 error = 0; 379 break; 380 } 381 } 382 error = 1; 383 break; 384 case T_DATA_ERROR: 385 /* 386 * Handle PCI poke/peek as per UltraSPARC IIi 387 * User's Manual 16.2.1, modulo checking the 388 * TPC as USIII CPUs generate a precise trap 389 * instead of a special deferred one. 390 */ 391 if (tf->tf_tpc > (u_long)fas_nofault_begin && 392 tf->tf_tpc < (u_long)fas_nofault_end) { 393 cache_flush(); 394 cache_enable(PCPU_GET(impl)); 395 tf->tf_tpc = (u_long)fas_fault; 396 tf->tf_tnpc = tf->tf_tpc + 4; 397 error = 0; 398 break; 399 } 400 error = 1; 401 break; 402 case T_CORRECTED_ECC_ERROR: 403 error = trap_cecc(); 404 break; 405 default: 406 error = 1; 407 break; 408 } 409 410 if (error != 0) { 411 tf->tf_type &= ~T_KERNEL; 412 if (tf->tf_type > T_MAX) 413 panic("trap: bad trap type %#lx (kernel)", 414 tf->tf_type); 415 panic("trap: %s (kernel)", trap_msg[tf->tf_type]); 416 } 417 } 418 CTR1(KTR_TRAP, "trap: td=%p return", td); 419} 420 421static int 422trap_cecc(void) 423{ 424 u_long eee; 425 426 /* 427 * Turn off (non-)correctable error reporting while we're dealing 428 * with the error. 429 */ 430 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG); 431 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN | 432 AA_ESTATE_CEEN)); 433 /* Flush the caches in order ensure no corrupt data got installed. */ 434 cache_flush(); 435 /* Ensure the caches are still turned on (should be). */ 436 cache_enable(PCPU_GET(impl)); 437 /* Clear the error from the AFSR. */ 438 stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); 439 corrected_ecc++; 440 printf("corrected ECC error\n"); 441 /* Turn (non-)correctable error reporting back on. */ 442 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); 443 return (0); 444} 445 446static int 447trap_pfault(struct thread *td, struct trapframe *tf) 448{ 449 vm_map_t map; 450 struct proc *p; 451 vm_offset_t va; 452 vm_prot_t prot; 453 vm_map_entry_t entry; 454 u_long ctx; 455 int type; 456 int rv; 457 458 if (td == NULL) 459 return (-1); 460 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL")); 461 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL")); 462 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); 463 464 p = td->td_proc; 465 466 rv = KERN_SUCCESS; 467 ctx = TLB_TAR_CTX(tf->tf_tar); 468 type = tf->tf_type & ~T_KERNEL; 469 va = TLB_TAR_VA(tf->tf_tar); 470 471 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx", 472 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx); 473 474 if (type == T_DATA_PROTECTION) 475 prot = VM_PROT_WRITE; 476 else { 477 if (type == T_DATA_MISS) 478 prot = VM_PROT_READ; 479 else 480 prot = VM_PROT_READ | VM_PROT_EXECUTE; 481 } 482 483 if (ctx != TLB_CTX_KERNEL) { 484 if ((tf->tf_tstate & TSTATE_PRIV) != 0 && 485 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin && 486 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) { 487 tf->tf_tpc = (u_long)fs_fault; 488 tf->tf_tnpc = tf->tf_tpc + 4; 489 return (0); 490 } 491 492 /* This is a fault on non-kernel virtual memory. */ 493 map = &p->p_vmspace->vm_map; 494 } else { 495 /* 496 * This is a fault on kernel virtual memory. Attempts to 497 * access kernel memory from user mode cause privileged 498 * action traps, not page fault. 499 */ 500 KASSERT(tf->tf_tstate & TSTATE_PRIV, 501 ("trap_pfault: fault on nucleus context from user mode")); 502 503 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 504 tf->tf_tpc <= (u_long)copy_nofault_end) { 505 vm_map_lock_read(kernel_map); 506 if (vm_map_lookup_entry(kernel_map, va, &entry) && 507 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) { 508 tf->tf_tpc = (u_long)copy_fault; 509 tf->tf_tnpc = tf->tf_tpc + 4; 510 vm_map_unlock_read(kernel_map); 511 return (0); 512 } 513 vm_map_unlock_read(kernel_map); 514 } 515 map = kernel_map; 516 } 517 518 /* Fault in the page. */ 519 rv = vm_fault(map, va, prot, VM_FAULT_NORMAL); 520 521 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", 522 td, va, rv); 523 if (rv == KERN_SUCCESS) 524 return (0); 525 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { 526 if (tf->tf_tpc >= (u_long)fs_nofault_begin && 527 tf->tf_tpc <= (u_long)fs_nofault_end) { 528 tf->tf_tpc = (u_long)fs_fault; 529 tf->tf_tnpc = tf->tf_tpc + 4; 530 return (0); 531 } 532 if (tf->tf_tpc >= (u_long)copy_nofault_begin && 533 tf->tf_tpc <= (u_long)copy_nofault_end) { 534 tf->tf_tpc = (u_long)copy_fault; 535 tf->tf_tnpc = tf->tf_tpc + 4; 536 return (0); 537 } 538 } 539 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 540} 541 542/* Maximum number of arguments that can be passed via the out registers. */ 543#define REG_MAXARGS 6 544 545int 546cpu_fetch_syscall_args(struct thread *td) 547{ 548 struct trapframe *tf; 549 struct proc *p; 550 register_t *argp; 551 struct syscall_args *sa; 552 int reg; 553 int regcnt; 554 int error; 555 556 p = td->td_proc; 557 tf = td->td_frame; 558 sa = &td->td_sa; 559 reg = 0; 560 regcnt = REG_MAXARGS; 561 562 sa->code = tf->tf_global[1]; 563 564 if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 565 sa->code = tf->tf_out[reg++]; 566 regcnt--; 567 } 568 569 if (p->p_sysent->sv_mask) 570 sa->code &= p->p_sysent->sv_mask; 571 if (sa->code >= p->p_sysent->sv_size) 572 sa->callp = &p->p_sysent->sv_table[0]; 573 else 574 sa->callp = &p->p_sysent->sv_table[sa->code]; 575 576 sa->narg = sa->callp->sy_narg; 577 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), 578 ("Too many syscall arguments!")); 579 error = 0; 580 argp = sa->args; 581 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt); 582 if (sa->narg > regcnt) 583 error = copyin((void *)(tf->tf_out[6] + SPOFF + 584 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt], 585 (sa->narg - regcnt) * sizeof(sa->args[0])); 586 if (error == 0) { 587 td->td_retval[0] = 0; 588 td->td_retval[1] = 0; 589 } 590 591 return (error); 592} 593 594#include "../../kern/subr_syscall.c" 595 596/* 597 * Syscall handler 598 * The arguments to the syscall are passed in the out registers by the caller, 599 * and are saved in the trap frame. The syscall number is passed in %g1 (and 600 * also saved in the trap frame). 601 */ 602void 603syscall(struct trapframe *tf) 604{ 605 struct thread *td; 606 int error; 607 608 td = curthread; 609 td->td_frame = tf; 610 611 KASSERT(td != NULL, ("trap: curthread NULL")); 612 KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 613 614 /* 615 * For syscalls, we don't want to retry the faulting instruction 616 * (usually), instead we need to advance one instruction. 617 */ 618 td->td_pcb->pcb_tpc = tf->tf_tpc; 619 TF_DONE(tf); 620 621 error = syscallenter(td); 622 syscallret(td, error); 623} 624