2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2001, Jake Burkholder
5 * Copyright (C) 1994, David Greenman
6 * Copyright (c) 1990, 1993
7 * The Regents of the University of California. All rights reserved.
9 * This code is derived from software contributed to Berkeley by
10 * the University of Utah, and William Jolitz.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91
37 * from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
46 #include <sys/param.h>
48 #include <sys/kernel.h>
50 #include <sys/interrupt.h>
53 #include <sys/mutex.h>
54 #include <sys/systm.h>
56 #include <sys/pioctl.h>
57 #include <sys/ptrace.h>
60 #include <sys/signalvar.h>
61 #include <sys/syscall.h>
62 #include <sys/sysctl.h>
63 #include <sys/sysent.h>
64 #include <sys/vmmeter.h>
65 #include <security/audit/audit.h>
67 #include <dev/ofw/openfirm.h>
71 #include <vm/vm_extern.h>
72 #include <vm/vm_param.h>
73 #include <vm/vm_kern.h>
74 #include <vm/vm_map.h>
75 #include <vm/vm_page.h>
77 #include <machine/cpu.h>
78 #include <machine/frame.h>
79 #include <machine/intr_machdep.h>
80 #include <machine/ofw_machdep.h>
81 #include <machine/pcb.h>
82 #include <machine/smp.h>
83 #include <machine/trap.h>
84 #include <machine/tstate.h>
85 #include <machine/tte.h>
86 #include <machine/tlb.h>
87 #include <machine/tsb.h>
88 #include <machine/watch.h>
90 void trap(struct trapframe *tf);
91 void syscall(struct trapframe *tf);
93 static int trap_cecc(void);
94 static int trap_pfault(struct thread *td, struct trapframe *tf);
96 extern char copy_fault[];
97 extern char copy_nofault_begin[];
98 extern char copy_nofault_end[];
100 extern char fs_fault[];
101 extern char fs_nofault_begin[];
102 extern char fs_nofault_end[];
104 extern char fas_fault[];
105 extern char fas_nofault_begin[];
106 extern char fas_nofault_end[];
108 const char *const trap_msg[] = {
110 "instruction access exception",
111 "instruction access error",
112 "instruction access protection",
113 "illtrap instruction",
114 "illegal instruction",
116 "floating point disabled",
117 "floating point exception ieee 754",
118 "floating point exception other",
121 "data access exception",
123 "data access protection",
124 "memory address not aligned",
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",
146 "physical address watchpoint",
147 "virtual address watchpoint",
148 "corrected ecc error",
158 "restore physical watchpoint",
159 "restore virtual watchpoint",
160 "kernel stack fault",
163 static 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 */
201 -1, /* physical address watchpoint */
202 -1, /* virtual address watchpoint */
203 -1, /* corrected ecc error */
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 */
218 CTASSERT(nitems(trap_msg) == T_MAX);
219 CTASSERT(nitems(trap_sig) == T_MAX);
221 CTASSERT(sizeof(struct trapframe) == 256);
223 int debugger_on_signal = 0;
224 SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
225 &debugger_on_signal, 0, "");
227 u_int corrected_ecc = 0;
228 SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
229 "corrected ECC errors");
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,
237 sun4u_set_traptable(void *tba_addr)
245 (cell_t)"SUNW,set-trap-table",
250 args.tba_addr = (cell_t)tba_addr;
255 trap(struct trapframe *tf)
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));
272 if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
273 KASSERT(td != NULL, ("trap: curthread NULL"));
274 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
280 ucode = (int)tf->tf_type; /* XXX not POSIX */
281 if (td->td_cowgen != p->p_cowgen)
282 thread_cow_update(td);
284 switch (tf->tf_type) {
286 case T_DATA_PROTECTION:
289 case T_INSTRUCTION_MISS:
290 sig = trap_pfault(td, tf);
293 sig = rwindow_load(td, tf, 2);
296 sig = rwindow_load(td, tf, 1);
299 sig = rwindow_save(td);
301 case T_CORRECTED_ECC_ERROR:
309 if (tf->tf_type > T_MAX)
310 panic("trap: bad trap type %#lx (user)",
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];
320 /* Translate fault for emulators. */
321 if (p->p_sysent->sv_transtrap != NULL) {
322 sig = p->p_sysent->sv_transtrap(sig,
325 if (debugger_on_signal &&
326 (sig == 4 || sig == 10 || sig == 11))
327 kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
328 ksiginfo_init_trap(&ksi);
330 ksi.ksi_code = ucode;
331 ksi.ksi_addr = (void *)addr;
332 ksi.ksi_trapno = (int)tf->tf_type;
333 trapsignal(td, &ksi);
338 KASSERT((tf->tf_type & T_KERNEL) != 0,
339 ("trap: kernel trap isn't"));
346 switch (tf->tf_type & ~T_KERNEL) {
349 error = (kdb_trap(tf->tf_type, 0, tf) == 0);
353 case T_PA_WATCHPOINT:
354 case T_VA_WATCHPOINT:
355 error = db_watch_trap(tf);
359 case T_DATA_PROTECTION:
360 case T_INSTRUCTION_MISS:
361 error = trap_pfault(td, tf);
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;
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;
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.
391 if (tf->tf_tpc > (u_long)fas_nofault_begin &&
392 tf->tf_tpc < (u_long)fas_nofault_end) {
394 cache_enable(PCPU_GET(impl));
395 tf->tf_tpc = (u_long)fas_fault;
396 tf->tf_tnpc = tf->tf_tpc + 4;
402 case T_CORRECTED_ECC_ERROR:
411 tf->tf_type &= ~T_KERNEL;
412 if (tf->tf_type > T_MAX)
413 panic("trap: bad trap type %#lx (kernel)",
415 panic("trap: %s (kernel)", trap_msg[tf->tf_type]);
418 CTR1(KTR_TRAP, "trap: td=%p return", td);
427 * Turn off (non-)correctable error reporting while we're dealing
430 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
431 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
433 /* Flush the caches in order ensure no corrupt data got installed. */
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));
440 printf("corrected ECC error\n");
441 /* Turn (non-)correctable error reporting back on. */
442 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
447 trap_pfault(struct thread *td, struct trapframe *tf)
453 vm_map_entry_t entry;
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"));
467 ctx = TLB_TAR_CTX(tf->tf_tar);
468 type = tf->tf_type & ~T_KERNEL;
469 va = TLB_TAR_VA(tf->tf_tar);
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);
474 if (type == T_DATA_PROTECTION)
475 prot = VM_PROT_WRITE;
477 if (type == T_DATA_MISS)
480 prot = VM_PROT_READ | VM_PROT_EXECUTE;
483 if (ctx != TLB_CTX_KERNEL) {
484 /* This is a fault on non-kernel virtual memory. */
485 map = &p->p_vmspace->vm_map;
488 * This is a fault on kernel virtual memory. Attempts to
489 * access kernel memory from user mode cause privileged
490 * action traps, not page fault.
492 KASSERT(tf->tf_tstate & TSTATE_PRIV,
493 ("trap_pfault: fault on nucleus context from user mode"));
495 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
496 tf->tf_tpc <= (u_long)copy_nofault_end) {
497 vm_map_lock_read(kernel_map);
498 if (vm_map_lookup_entry(kernel_map, va, &entry) &&
499 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
500 tf->tf_tpc = (u_long)copy_fault;
501 tf->tf_tnpc = tf->tf_tpc + 4;
502 vm_map_unlock_read(kernel_map);
505 vm_map_unlock_read(kernel_map);
510 /* Fault in the page. */
511 rv = vm_fault(map, va, prot, VM_FAULT_NORMAL);
513 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
515 if (rv == KERN_SUCCESS)
517 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
518 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
519 tf->tf_tpc <= (u_long)fs_nofault_end) {
520 tf->tf_tpc = (u_long)fs_fault;
521 tf->tf_tnpc = tf->tf_tpc + 4;
524 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
525 tf->tf_tpc <= (u_long)copy_nofault_end) {
526 tf->tf_tpc = (u_long)copy_fault;
527 tf->tf_tnpc = tf->tf_tpc + 4;
531 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
534 /* Maximum number of arguments that can be passed via the out registers. */
535 #define REG_MAXARGS 6
538 cpu_fetch_syscall_args(struct thread *td)
540 struct trapframe *tf;
543 struct syscall_args *sa;
552 regcnt = REG_MAXARGS;
554 sa->code = tf->tf_global[1];
556 if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
557 sa->code = tf->tf_out[reg++];
561 if (p->p_sysent->sv_mask)
562 sa->code &= p->p_sysent->sv_mask;
563 if (sa->code >= p->p_sysent->sv_size)
564 sa->callp = &p->p_sysent->sv_table[0];
566 sa->callp = &p->p_sysent->sv_table[sa->code];
568 sa->narg = sa->callp->sy_narg;
569 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
570 ("Too many syscall arguments!"));
573 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
574 if (sa->narg > regcnt)
575 error = copyin((void *)(tf->tf_out[6] + SPOFF +
576 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
577 (sa->narg - regcnt) * sizeof(sa->args[0]));
579 td->td_retval[0] = 0;
580 td->td_retval[1] = 0;
586 #include "../../kern/subr_syscall.c"
590 * The arguments to the syscall are passed in the out registers by the caller,
591 * and are saved in the trap frame. The syscall number is passed in %g1 (and
592 * also saved in the trap frame).
595 syscall(struct trapframe *tf)
603 KASSERT(td != NULL, ("trap: curthread NULL"));
604 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
607 * For syscalls, we don't want to retry the faulting instruction
608 * (usually), instead we need to advance one instruction.
610 td->td_pcb->pcb_tpc = tf->tf_tpc;
613 error = syscallenter(td);
614 syscallret(td, error);