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.
7 * This code is derived from software contributed to Berkeley by
8 * the University of Utah, and William Jolitz.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
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
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
43 #include "opt_ktrace.h"
45 #include <sys/param.h>
47 #include <sys/kernel.h>
49 #include <sys/interrupt.h>
52 #include <sys/mutex.h>
53 #include <sys/systm.h>
55 #include <sys/pioctl.h>
56 #include <sys/ptrace.h>
59 #include <sys/signalvar.h>
60 #include <sys/syscall.h>
61 #include <sys/sysctl.h>
62 #include <sys/sysent.h>
63 #include <sys/vmmeter.h>
66 #include <sys/ktrace.h>
68 #include <security/audit/audit.h>
70 #include <dev/ofw/openfirm.h>
74 #include <vm/vm_extern.h>
75 #include <vm/vm_param.h>
76 #include <vm/vm_kern.h>
77 #include <vm/vm_map.h>
78 #include <vm/vm_page.h>
80 #include <machine/cpu.h>
81 #include <machine/frame.h>
82 #include <machine/intr_machdep.h>
83 #include <machine/ofw_machdep.h>
84 #include <machine/pcb.h>
85 #include <machine/smp.h>
86 #include <machine/trap.h>
87 #include <machine/tstate.h>
88 #include <machine/tte.h>
89 #include <machine/tlb.h>
90 #include <machine/tsb.h>
91 #include <machine/watch.h>
93 void trap(struct trapframe *tf);
94 void syscall(struct trapframe *tf);
96 static int trap_cecc(void);
97 static int trap_pfault(struct thread *td, struct trapframe *tf);
99 extern char copy_fault[];
100 extern char copy_nofault_begin[];
101 extern char copy_nofault_end[];
103 extern char fs_fault[];
104 extern char fs_nofault_begin[];
105 extern char fs_nofault_end[];
106 extern char fs_nofault_intr_begin[];
107 extern char fs_nofault_intr_end[];
109 extern char fas_fault[];
110 extern char fas_nofault_begin[];
111 extern char fas_nofault_end[];
113 const char *const trap_msg[] = {
115 "instruction access exception",
116 "instruction access error",
117 "instruction access protection",
118 "illtrap instruction",
119 "illegal instruction",
121 "floating point disabled",
122 "floating point exception ieee 754",
123 "floating point exception other",
126 "data access exception",
128 "data access protection",
129 "memory address not aligned",
132 "trap instruction 16",
133 "trap instruction 17",
134 "trap instruction 18",
135 "trap instruction 19",
136 "trap instruction 20",
137 "trap instruction 21",
138 "trap instruction 22",
139 "trap instruction 23",
140 "trap instruction 24",
141 "trap instruction 25",
142 "trap instruction 26",
143 "trap instruction 27",
144 "trap instruction 28",
145 "trap instruction 29",
146 "trap instruction 30",
147 "trap instruction 31",
148 "fast instruction access mmu miss",
149 "fast data access mmu miss",
151 "physical address watchpoint",
152 "virtual address watchpoint",
153 "corrected ecc error",
163 "restore physical watchpoint",
164 "restore virtual watchpoint",
165 "kernel stack fault",
168 static const int trap_sig[] = {
169 SIGILL, /* reserved */
170 SIGILL, /* instruction access exception */
171 SIGILL, /* instruction access error */
172 SIGILL, /* instruction access protection */
173 SIGILL, /* illtrap instruction */
174 SIGILL, /* illegal instruction */
175 SIGBUS, /* privileged opcode */
176 SIGFPE, /* floating point disabled */
177 SIGFPE, /* floating point exception ieee 754 */
178 SIGFPE, /* floating point exception other */
179 SIGEMT, /* tag overflow */
180 SIGFPE, /* division by zero */
181 SIGILL, /* data access exception */
182 SIGILL, /* data access error */
183 SIGBUS, /* data access protection */
184 SIGBUS, /* memory address not aligned */
185 SIGBUS, /* privileged action */
186 SIGBUS, /* async data error */
187 SIGILL, /* trap instruction 16 */
188 SIGILL, /* trap instruction 17 */
189 SIGILL, /* trap instruction 18 */
190 SIGILL, /* trap instruction 19 */
191 SIGILL, /* trap instruction 20 */
192 SIGILL, /* trap instruction 21 */
193 SIGILL, /* trap instruction 22 */
194 SIGILL, /* trap instruction 23 */
195 SIGILL, /* trap instruction 24 */
196 SIGILL, /* trap instruction 25 */
197 SIGILL, /* trap instruction 26 */
198 SIGILL, /* trap instruction 27 */
199 SIGILL, /* trap instruction 28 */
200 SIGILL, /* trap instruction 29 */
201 SIGILL, /* trap instruction 30 */
202 SIGILL, /* trap instruction 31 */
203 SIGSEGV, /* fast instruction access mmu miss */
204 SIGSEGV, /* fast data access mmu miss */
206 -1, /* physical address watchpoint */
207 -1, /* virtual address watchpoint */
208 -1, /* corrected ecc error */
212 SIGTRAP, /* breakpoint */
213 SIGILL, /* clean window */
214 SIGILL, /* range check */
215 SIGILL, /* fix alignment */
216 SIGILL, /* integer overflow */
217 SIGSYS, /* syscall */
218 -1, /* restore physical watchpoint */
219 -1, /* restore virtual watchpoint */
220 -1, /* kernel stack fault */
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));
272 PCPU_INC(cnt.v_trap);
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_ucred != p->p_ucred)
283 cred_update_thread(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 < 0 || 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);
334 mtx_assert(&Giant, MA_NOTOWNED);
336 KASSERT((tf->tf_type & T_KERNEL) != 0,
337 ("trap: kernel trap isn't"));
344 switch (tf->tf_type & ~T_KERNEL) {
347 error = (kdb_trap(tf->tf_type, 0, tf) == 0);
351 case T_PA_WATCHPOINT:
352 case T_VA_WATCHPOINT:
353 error = db_watch_trap(tf);
357 case T_DATA_PROTECTION:
358 case T_INSTRUCTION_MISS:
359 error = trap_pfault(td, tf);
361 case T_DATA_EXCEPTION:
362 case T_MEM_ADDRESS_NOT_ALIGNED:
363 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
364 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
365 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
366 tf->tf_tpc <= (u_long)copy_nofault_end) {
367 tf->tf_tpc = (u_long)copy_fault;
368 tf->tf_tnpc = tf->tf_tpc + 4;
372 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
373 tf->tf_tpc <= (u_long)fs_nofault_end) {
374 tf->tf_tpc = (u_long)fs_fault;
375 tf->tf_tnpc = tf->tf_tpc + 4;
384 * Handle PCI poke/peek as per UltraSPARC IIi
385 * User's Manual 16.2.1, modulo checking the
386 * TPC as USIII CPUs generate a precise trap
387 * instead of a special deferred one.
389 if (tf->tf_tpc > (u_long)fas_nofault_begin &&
390 tf->tf_tpc < (u_long)fas_nofault_end) {
392 cache_enable(PCPU_GET(impl));
393 tf->tf_tpc = (u_long)fas_fault;
394 tf->tf_tnpc = tf->tf_tpc + 4;
400 case T_CORRECTED_ECC_ERROR:
409 tf->tf_type &= ~T_KERNEL;
410 if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
411 panic("trap: bad trap type %#lx (kernel)",
413 else if (trap_sig[tf->tf_type] == -1)
414 panic("trap: %s (kernel)",
415 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;
461 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
462 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
463 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
468 ctx = TLB_TAR_CTX(tf->tf_tar);
469 type = tf->tf_type & ~T_KERNEL;
470 va = TLB_TAR_VA(tf->tf_tar);
472 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
473 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
475 if (type == T_DATA_PROTECTION) {
476 prot = VM_PROT_WRITE;
477 flags = VM_FAULT_DIRTY;
479 if (type == T_DATA_MISS)
482 prot = VM_PROT_READ | VM_PROT_EXECUTE;
483 flags = VM_FAULT_NORMAL;
486 if (ctx != TLB_CTX_KERNEL) {
487 if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
488 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
489 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
490 tf->tf_tpc = (u_long)fs_fault;
491 tf->tf_tnpc = tf->tf_tpc + 4;
496 * This is a fault on non-kernel virtual memory.
501 * Keep swapout from messing with us during this
508 /* Fault in the user page. */
509 rv = vm_fault(&vm->vm_map, va, prot, flags);
512 * Now the process can be swapped again.
519 * This is a fault on kernel virtual memory. Attempts to
520 * access kernel memory from user mode cause privileged
521 * action traps, not page fault.
523 KASSERT(tf->tf_tstate & TSTATE_PRIV,
524 ("trap_pfault: fault on nucleus context from user mode"));
526 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
527 tf->tf_tpc <= (u_long)copy_nofault_end) {
528 vm_map_lock_read(kernel_map);
529 if (vm_map_lookup_entry(kernel_map, va, &entry) &&
530 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
531 tf->tf_tpc = (u_long)copy_fault;
532 tf->tf_tnpc = tf->tf_tpc + 4;
533 vm_map_unlock_read(kernel_map);
536 vm_map_unlock_read(kernel_map);
540 * We don't have to worry about process locking or stacks in
543 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
546 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
548 if (rv == KERN_SUCCESS)
550 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
551 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
552 tf->tf_tpc <= (u_long)fs_nofault_end) {
553 tf->tf_tpc = (u_long)fs_fault;
554 tf->tf_tnpc = tf->tf_tpc + 4;
557 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
558 tf->tf_tpc <= (u_long)copy_nofault_end) {
559 tf->tf_tpc = (u_long)copy_fault;
560 tf->tf_tnpc = tf->tf_tpc + 4;
564 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
567 /* Maximum number of arguments that can be passed via the out registers. */
568 #define REG_MAXARGS 6
571 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
573 struct trapframe *tf;
583 regcnt = REG_MAXARGS;
585 sa->code = tf->tf_global[1];
587 if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
588 sa->code = tf->tf_out[reg++];
592 if (p->p_sysent->sv_mask)
593 sa->code &= p->p_sysent->sv_mask;
594 if (sa->code >= p->p_sysent->sv_size)
595 sa->callp = &p->p_sysent->sv_table[0];
597 sa->callp = &p->p_sysent->sv_table[sa->code];
599 sa->narg = sa->callp->sy_narg;
600 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
601 ("Too many syscall arguments!"));
604 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
605 if (sa->narg > regcnt)
606 error = copyin((void *)(tf->tf_out[6] + SPOFF +
607 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
608 (sa->narg - regcnt) * sizeof(sa->args[0]));
610 td->td_retval[0] = 0;
611 td->td_retval[1] = 0;
619 * The arguments to the syscall are passed in the out registers by the caller,
620 * and are saved in the trap frame. The syscall number is passed in %g1 (and
621 * also saved in the trap frame).
624 syscall(struct trapframe *tf)
627 struct syscall_args sa;
633 KASSERT(td != NULL, ("trap: curthread NULL"));
634 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
637 * For syscalls, we don't want to retry the faulting instruction
638 * (usually), instead we need to advance one instruction.
640 td->td_pcb->pcb_tpc = tf->tf_tpc;
643 error = syscallenter(td, &sa);
644 syscallret(td, error, &sa);