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[];
103 extern char fs_nofault_intr_begin[];
104 extern char fs_nofault_intr_end[];
106 extern char fas_fault[];
107 extern char fas_nofault_begin[];
108 extern char fas_nofault_end[];
110 const char *const trap_msg[] = {
112 "instruction access exception",
113 "instruction access error",
114 "instruction access protection",
115 "illtrap instruction",
116 "illegal instruction",
118 "floating point disabled",
119 "floating point exception ieee 754",
120 "floating point exception other",
123 "data access exception",
125 "data access protection",
126 "memory address not aligned",
129 "trap instruction 16",
130 "trap instruction 17",
131 "trap instruction 18",
132 "trap instruction 19",
133 "trap instruction 20",
134 "trap instruction 21",
135 "trap instruction 22",
136 "trap instruction 23",
137 "trap instruction 24",
138 "trap instruction 25",
139 "trap instruction 26",
140 "trap instruction 27",
141 "trap instruction 28",
142 "trap instruction 29",
143 "trap instruction 30",
144 "trap instruction 31",
145 "fast instruction access mmu miss",
146 "fast data access mmu miss",
148 "physical address watchpoint",
149 "virtual address watchpoint",
150 "corrected ecc error",
160 "restore physical watchpoint",
161 "restore virtual watchpoint",
162 "kernel stack fault",
165 static const int trap_sig[] = {
166 SIGILL, /* reserved */
167 SIGILL, /* instruction access exception */
168 SIGILL, /* instruction access error */
169 SIGILL, /* instruction access protection */
170 SIGILL, /* illtrap instruction */
171 SIGILL, /* illegal instruction */
172 SIGBUS, /* privileged opcode */
173 SIGFPE, /* floating point disabled */
174 SIGFPE, /* floating point exception ieee 754 */
175 SIGFPE, /* floating point exception other */
176 SIGEMT, /* tag overflow */
177 SIGFPE, /* division by zero */
178 SIGILL, /* data access exception */
179 SIGILL, /* data access error */
180 SIGBUS, /* data access protection */
181 SIGBUS, /* memory address not aligned */
182 SIGBUS, /* privileged action */
183 SIGBUS, /* async data error */
184 SIGILL, /* trap instruction 16 */
185 SIGILL, /* trap instruction 17 */
186 SIGILL, /* trap instruction 18 */
187 SIGILL, /* trap instruction 19 */
188 SIGILL, /* trap instruction 20 */
189 SIGILL, /* trap instruction 21 */
190 SIGILL, /* trap instruction 22 */
191 SIGILL, /* trap instruction 23 */
192 SIGILL, /* trap instruction 24 */
193 SIGILL, /* trap instruction 25 */
194 SIGILL, /* trap instruction 26 */
195 SIGILL, /* trap instruction 27 */
196 SIGILL, /* trap instruction 28 */
197 SIGILL, /* trap instruction 29 */
198 SIGILL, /* trap instruction 30 */
199 SIGILL, /* trap instruction 31 */
200 SIGSEGV, /* fast instruction access mmu miss */
201 SIGSEGV, /* fast data access mmu miss */
203 -1, /* physical address watchpoint */
204 -1, /* virtual address watchpoint */
205 -1, /* corrected ecc error */
209 SIGTRAP, /* breakpoint */
210 SIGILL, /* clean window */
211 SIGILL, /* range check */
212 SIGILL, /* fix alignment */
213 SIGILL, /* integer overflow */
214 SIGSYS, /* syscall */
215 -1, /* restore physical watchpoint */
216 -1, /* restore virtual watchpoint */
217 -1, /* kernel stack fault */
220 CTASSERT(nitems(trap_msg) == T_MAX);
221 CTASSERT(nitems(trap_sig) == T_MAX);
223 CTASSERT(sizeof(struct trapframe) == 256);
225 int debugger_on_signal = 0;
226 SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
227 &debugger_on_signal, 0, "");
229 u_int corrected_ecc = 0;
230 SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
231 "corrected ECC errors");
234 * SUNW,set-trap-table allows to take over %tba from the PROM, which
235 * will turn off interrupts and handle outstanding ones while doing so,
239 sun4u_set_traptable(void *tba_addr)
247 (cell_t)"SUNW,set-trap-table",
252 args.tba_addr = (cell_t)tba_addr;
257 trap(struct trapframe *tf)
268 CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td,
269 trap_msg[tf->tf_type & ~T_KERNEL],
270 (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil));
274 if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
275 KASSERT(td != NULL, ("trap: curthread NULL"));
276 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
282 if (td->td_cowgen != p->p_cowgen)
283 thread_cow_update(td);
285 switch (tf->tf_type) {
287 case T_DATA_PROTECTION:
290 case T_INSTRUCTION_MISS:
291 sig = trap_pfault(td, tf);
294 sig = rwindow_load(td, tf, 2);
297 sig = rwindow_load(td, tf, 1);
300 sig = rwindow_save(td);
302 case T_CORRECTED_ECC_ERROR:
306 if (tf->tf_type > T_MAX)
307 panic("trap: bad trap type %#lx (user)",
309 else if (trap_sig[tf->tf_type] == -1)
310 panic("trap: %s (user)",
311 trap_msg[tf->tf_type]);
312 sig = trap_sig[tf->tf_type];
317 /* Translate fault for emulators. */
318 if (p->p_sysent->sv_transtrap != NULL) {
319 sig = p->p_sysent->sv_transtrap(sig,
322 if (debugger_on_signal &&
323 (sig == 4 || sig == 10 || sig == 11))
324 kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
325 ksiginfo_init_trap(&ksi);
327 ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
328 ksi.ksi_addr = (void *)addr;
329 ksi.ksi_trapno = (int)tf->tf_type;
330 trapsignal(td, &ksi);
335 KASSERT((tf->tf_type & T_KERNEL) != 0,
336 ("trap: kernel trap isn't"));
343 switch (tf->tf_type & ~T_KERNEL) {
346 error = (kdb_trap(tf->tf_type, 0, tf) == 0);
350 case T_PA_WATCHPOINT:
351 case T_VA_WATCHPOINT:
352 error = db_watch_trap(tf);
356 case T_DATA_PROTECTION:
357 case T_INSTRUCTION_MISS:
358 error = trap_pfault(td, tf);
360 case T_DATA_EXCEPTION:
361 case T_MEM_ADDRESS_NOT_ALIGNED:
362 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
363 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
364 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
365 tf->tf_tpc <= (u_long)copy_nofault_end) {
366 tf->tf_tpc = (u_long)copy_fault;
367 tf->tf_tnpc = tf->tf_tpc + 4;
371 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
372 tf->tf_tpc <= (u_long)fs_nofault_end) {
373 tf->tf_tpc = (u_long)fs_fault;
374 tf->tf_tnpc = tf->tf_tpc + 4;
383 * Handle PCI poke/peek as per UltraSPARC IIi
384 * User's Manual 16.2.1, modulo checking the
385 * TPC as USIII CPUs generate a precise trap
386 * instead of a special deferred one.
388 if (tf->tf_tpc > (u_long)fas_nofault_begin &&
389 tf->tf_tpc < (u_long)fas_nofault_end) {
391 cache_enable(PCPU_GET(impl));
392 tf->tf_tpc = (u_long)fas_fault;
393 tf->tf_tnpc = tf->tf_tpc + 4;
399 case T_CORRECTED_ECC_ERROR:
408 tf->tf_type &= ~T_KERNEL;
409 if (tf->tf_type > T_MAX)
410 panic("trap: bad trap type %#lx (kernel)",
412 panic("trap: %s (kernel)", trap_msg[tf->tf_type]);
415 CTR1(KTR_TRAP, "trap: td=%p return", td);
424 * Turn off (non-)correctable error reporting while we're dealing
427 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
428 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
430 /* Flush the caches in order ensure no corrupt data got installed. */
432 /* Ensure the caches are still turned on (should be). */
433 cache_enable(PCPU_GET(impl));
434 /* Clear the error from the AFSR. */
435 stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
437 printf("corrected ECC error\n");
438 /* Turn (non-)correctable error reporting back on. */
439 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
444 trap_pfault(struct thread *td, struct trapframe *tf)
450 vm_map_entry_t entry;
457 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
458 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
459 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
464 ctx = TLB_TAR_CTX(tf->tf_tar);
465 type = tf->tf_type & ~T_KERNEL;
466 va = TLB_TAR_VA(tf->tf_tar);
468 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
469 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
471 if (type == T_DATA_PROTECTION)
472 prot = VM_PROT_WRITE;
474 if (type == T_DATA_MISS)
477 prot = VM_PROT_READ | VM_PROT_EXECUTE;
480 if (ctx != TLB_CTX_KERNEL) {
481 if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
482 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
483 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
484 tf->tf_tpc = (u_long)fs_fault;
485 tf->tf_tnpc = tf->tf_tpc + 4;
489 /* This is a fault on non-kernel virtual memory. */
490 map = &p->p_vmspace->vm_map;
493 * This is a fault on kernel virtual memory. Attempts to
494 * access kernel memory from user mode cause privileged
495 * action traps, not page fault.
497 KASSERT(tf->tf_tstate & TSTATE_PRIV,
498 ("trap_pfault: fault on nucleus context from user mode"));
500 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
501 tf->tf_tpc <= (u_long)copy_nofault_end) {
502 vm_map_lock_read(kernel_map);
503 if (vm_map_lookup_entry(kernel_map, va, &entry) &&
504 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
505 tf->tf_tpc = (u_long)copy_fault;
506 tf->tf_tnpc = tf->tf_tpc + 4;
507 vm_map_unlock_read(kernel_map);
510 vm_map_unlock_read(kernel_map);
515 /* Fault in the page. */
516 rv = vm_fault(map, va, prot, VM_FAULT_NORMAL);
518 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
520 if (rv == KERN_SUCCESS)
522 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
523 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
524 tf->tf_tpc <= (u_long)fs_nofault_end) {
525 tf->tf_tpc = (u_long)fs_fault;
526 tf->tf_tnpc = tf->tf_tpc + 4;
529 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
530 tf->tf_tpc <= (u_long)copy_nofault_end) {
531 tf->tf_tpc = (u_long)copy_fault;
532 tf->tf_tnpc = tf->tf_tpc + 4;
536 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
539 /* Maximum number of arguments that can be passed via the out registers. */
540 #define REG_MAXARGS 6
543 cpu_fetch_syscall_args(struct thread *td)
545 struct trapframe *tf;
548 struct syscall_args *sa;
557 regcnt = REG_MAXARGS;
559 sa->code = tf->tf_global[1];
561 if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
562 sa->code = tf->tf_out[reg++];
566 if (p->p_sysent->sv_mask)
567 sa->code &= p->p_sysent->sv_mask;
568 if (sa->code >= p->p_sysent->sv_size)
569 sa->callp = &p->p_sysent->sv_table[0];
571 sa->callp = &p->p_sysent->sv_table[sa->code];
573 sa->narg = sa->callp->sy_narg;
574 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
575 ("Too many syscall arguments!"));
578 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
579 if (sa->narg > regcnt)
580 error = copyin((void *)(tf->tf_out[6] + SPOFF +
581 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
582 (sa->narg - regcnt) * sizeof(sa->args[0]));
584 td->td_retval[0] = 0;
585 td->td_retval[1] = 0;
591 #include "../../kern/subr_syscall.c"
595 * The arguments to the syscall are passed in the out registers by the caller,
596 * and are saved in the trap frame. The syscall number is passed in %g1 (and
597 * also saved in the trap frame).
600 syscall(struct trapframe *tf)
608 KASSERT(td != NULL, ("trap: curthread NULL"));
609 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
612 * For syscalls, we don't want to retry the faulting instruction
613 * (usually), instead we need to advance one instruction.
615 td->td_pcb->pcb_tpc = tf->tf_tpc;
618 error = syscallenter(td);
619 syscallret(td, error);