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 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91
39 * from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD$");
47 #include "opt_ktrace.h"
49 #include <sys/param.h>
51 #include <sys/kernel.h>
53 #include <sys/interrupt.h>
56 #include <sys/mutex.h>
57 #include <sys/systm.h>
59 #include <sys/pioctl.h>
60 #include <sys/ptrace.h>
63 #include <sys/signalvar.h>
64 #include <sys/syscall.h>
65 #include <sys/sysctl.h>
66 #include <sys/sysent.h>
67 #include <sys/vmmeter.h>
70 #include <sys/ktrace.h>
72 #include <security/audit/audit.h>
74 #include <dev/ofw/openfirm.h>
78 #include <vm/vm_extern.h>
79 #include <vm/vm_param.h>
80 #include <vm/vm_kern.h>
81 #include <vm/vm_map.h>
82 #include <vm/vm_page.h>
84 #include <machine/cpu.h>
85 #include <machine/frame.h>
86 #include <machine/intr_machdep.h>
87 #include <machine/ofw_machdep.h>
88 #include <machine/pcb.h>
89 #include <machine/smp.h>
90 #include <machine/trap.h>
91 #include <machine/tstate.h>
92 #include <machine/tte.h>
93 #include <machine/tlb.h>
94 #include <machine/tsb.h>
95 #include <machine/watch.h>
97 void trap(struct trapframe *tf);
98 void syscall(struct trapframe *tf);
100 static int trap_cecc(void);
101 static int trap_pfault(struct thread *td, struct trapframe *tf);
103 extern char copy_fault[];
104 extern char copy_nofault_begin[];
105 extern char copy_nofault_end[];
107 extern char fs_fault[];
108 extern char fs_nofault_begin[];
109 extern char fs_nofault_end[];
110 extern char fs_nofault_intr_begin[];
111 extern char fs_nofault_intr_end[];
113 extern char fas_fault[];
114 extern char fas_nofault_begin[];
115 extern char fas_nofault_end[];
117 const char *const trap_msg[] = {
119 "instruction access exception",
120 "instruction access error",
121 "instruction access protection",
122 "illtrap instruction",
123 "illegal instruction",
125 "floating point disabled",
126 "floating point exception ieee 754",
127 "floating point exception other",
130 "data access exception",
132 "data access protection",
133 "memory address not aligned",
136 "trap instruction 16",
137 "trap instruction 17",
138 "trap instruction 18",
139 "trap instruction 19",
140 "trap instruction 20",
141 "trap instruction 21",
142 "trap instruction 22",
143 "trap instruction 23",
144 "trap instruction 24",
145 "trap instruction 25",
146 "trap instruction 26",
147 "trap instruction 27",
148 "trap instruction 28",
149 "trap instruction 29",
150 "trap instruction 30",
151 "trap instruction 31",
152 "fast instruction access mmu miss",
153 "fast data access mmu miss",
155 "physical address watchpoint",
156 "virtual address watchpoint",
157 "corrected ecc error",
167 "restore physical watchpoint",
168 "restore virtual watchpoint",
169 "kernel stack fault",
172 static const int trap_sig[] = {
173 SIGILL, /* reserved */
174 SIGILL, /* instruction access exception */
175 SIGILL, /* instruction access error */
176 SIGILL, /* instruction access protection */
177 SIGILL, /* illtrap instruction */
178 SIGILL, /* illegal instruction */
179 SIGBUS, /* privileged opcode */
180 SIGFPE, /* floating point disabled */
181 SIGFPE, /* floating point exception ieee 754 */
182 SIGFPE, /* floating point exception other */
183 SIGEMT, /* tag overflow */
184 SIGFPE, /* division by zero */
185 SIGILL, /* data access exception */
186 SIGILL, /* data access error */
187 SIGBUS, /* data access protection */
188 SIGBUS, /* memory address not aligned */
189 SIGBUS, /* privileged action */
190 SIGBUS, /* async data error */
191 SIGILL, /* trap instruction 16 */
192 SIGILL, /* trap instruction 17 */
193 SIGILL, /* trap instruction 18 */
194 SIGILL, /* trap instruction 19 */
195 SIGILL, /* trap instruction 20 */
196 SIGILL, /* trap instruction 21 */
197 SIGILL, /* trap instruction 22 */
198 SIGILL, /* trap instruction 23 */
199 SIGILL, /* trap instruction 24 */
200 SIGILL, /* trap instruction 25 */
201 SIGILL, /* trap instruction 26 */
202 SIGILL, /* trap instruction 27 */
203 SIGILL, /* trap instruction 28 */
204 SIGILL, /* trap instruction 29 */
205 SIGILL, /* trap instruction 30 */
206 SIGILL, /* trap instruction 31 */
207 SIGSEGV, /* fast instruction access mmu miss */
208 SIGSEGV, /* fast data access mmu miss */
210 -1, /* physical address watchpoint */
211 -1, /* virtual address watchpoint */
212 -1, /* corrected ecc error */
216 SIGTRAP, /* breakpoint */
217 SIGILL, /* clean window */
218 SIGILL, /* range check */
219 SIGILL, /* fix alignment */
220 SIGILL, /* integer overflow */
221 SIGSYS, /* syscall */
222 -1, /* restore physical watchpoint */
223 -1, /* restore virtual watchpoint */
224 -1, /* kernel stack fault */
227 CTASSERT(sizeof(struct trapframe) == 256);
229 int debugger_on_signal = 0;
230 SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
231 &debugger_on_signal, 0, "");
233 u_int corrected_ecc = 0;
234 SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
235 "corrected ECC errors");
238 * SUNW,set-trap-table allows to take over %tba from the PROM, which
239 * will turn off interrupts and handle outstanding ones while doing so,
243 sun4u_set_traptable(void *tba_addr)
251 (cell_t)"SUNW,set-trap-table",
256 args.tba_addr = (cell_t)tba_addr;
261 trap(struct trapframe *tf)
272 CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td,
273 trap_msg[tf->tf_type & ~T_KERNEL],
274 (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil));
276 PCPU_INC(cnt.v_trap);
278 if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
279 KASSERT(td != NULL, ("trap: curthread NULL"));
280 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
286 if (td->td_ucred != p->p_ucred)
287 cred_update_thread(td);
289 switch (tf->tf_type) {
291 case T_DATA_PROTECTION:
294 case T_INSTRUCTION_MISS:
295 sig = trap_pfault(td, tf);
298 sig = rwindow_load(td, tf, 2);
301 sig = rwindow_load(td, tf, 1);
304 sig = rwindow_save(td);
306 case T_CORRECTED_ECC_ERROR:
310 if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
311 panic("trap: bad trap type %#lx (user)",
313 else if (trap_sig[tf->tf_type] == -1)
314 panic("trap: %s (user)",
315 trap_msg[tf->tf_type]);
316 sig = trap_sig[tf->tf_type];
321 /* Translate fault for emulators. */
322 if (p->p_sysent->sv_transtrap != NULL) {
323 sig = p->p_sysent->sv_transtrap(sig,
326 if (debugger_on_signal &&
327 (sig == 4 || sig == 10 || sig == 11))
328 kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
329 ksiginfo_init_trap(&ksi);
331 ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
332 ksi.ksi_addr = (void *)addr;
333 ksi.ksi_trapno = (int)tf->tf_type;
334 trapsignal(td, &ksi);
338 mtx_assert(&Giant, MA_NOTOWNED);
340 KASSERT((tf->tf_type & T_KERNEL) != 0,
341 ("trap: kernel trap isn't"));
348 switch (tf->tf_type & ~T_KERNEL) {
351 error = (kdb_trap(tf->tf_type, 0, tf) == 0);
355 case T_PA_WATCHPOINT:
356 case T_VA_WATCHPOINT:
357 error = db_watch_trap(tf);
361 case T_DATA_PROTECTION:
362 case T_INSTRUCTION_MISS:
363 error = trap_pfault(td, tf);
365 case T_DATA_EXCEPTION:
366 case T_MEM_ADDRESS_NOT_ALIGNED:
367 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
368 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
369 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
370 tf->tf_tpc <= (u_long)copy_nofault_end) {
371 tf->tf_tpc = (u_long)copy_fault;
372 tf->tf_tnpc = tf->tf_tpc + 4;
376 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
377 tf->tf_tpc <= (u_long)fs_nofault_end) {
378 tf->tf_tpc = (u_long)fs_fault;
379 tf->tf_tnpc = tf->tf_tpc + 4;
388 * Handle PCI poke/peek as per UltraSPARC IIi
389 * User's Manual 16.2.1, modulo checking the
390 * TPC as USIII CPUs generate a precise trap
391 * instead of a special deferred one.
393 if (tf->tf_tpc > (u_long)fas_nofault_begin &&
394 tf->tf_tpc < (u_long)fas_nofault_end) {
396 cache_enable(PCPU_GET(impl));
397 tf->tf_tpc = (u_long)fas_fault;
398 tf->tf_tnpc = tf->tf_tpc + 4;
404 case T_CORRECTED_ECC_ERROR:
413 tf->tf_type &= ~T_KERNEL;
414 if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
415 panic("trap: bad trap type %#lx (kernel)",
417 else if (trap_sig[tf->tf_type] == -1)
418 panic("trap: %s (kernel)",
419 trap_msg[tf->tf_type]);
422 CTR1(KTR_TRAP, "trap: td=%p return", td);
431 * Turn off (non-)correctable error reporting while we're dealing
434 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
435 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
437 /* Flush the caches in order ensure no corrupt data got installed. */
439 /* Ensure the caches are still turned on (should be). */
440 cache_enable(PCPU_GET(impl));
441 /* Clear the the error from the AFSR. */
442 stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
444 printf("corrected ECC error\n");
445 /* Turn (non-)correctable error reporting back on. */
446 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
451 trap_pfault(struct thread *td, struct trapframe *tf)
457 vm_map_entry_t entry;
465 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
466 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
467 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
472 ctx = TLB_TAR_CTX(tf->tf_tar);
473 type = tf->tf_type & ~T_KERNEL;
474 va = TLB_TAR_VA(tf->tf_tar);
476 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
477 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
479 if (type == T_DATA_PROTECTION) {
480 prot = VM_PROT_WRITE;
481 flags = VM_FAULT_DIRTY;
483 if (type == T_DATA_MISS)
486 prot = VM_PROT_READ | VM_PROT_EXECUTE;
487 flags = VM_FAULT_NORMAL;
490 if (ctx != TLB_CTX_KERNEL) {
491 if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
492 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
493 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
494 tf->tf_tpc = (u_long)fs_fault;
495 tf->tf_tnpc = tf->tf_tpc + 4;
500 * This is a fault on non-kernel virtual memory.
505 * Keep swapout from messing with us during this
512 /* Fault in the user page. */
513 rv = vm_fault(&vm->vm_map, va, prot, flags);
516 * Now the process can be swapped again.
523 * This is a fault on kernel virtual memory. Attempts to
524 * access kernel memory from user mode cause privileged
525 * action traps, not page fault.
527 KASSERT(tf->tf_tstate & TSTATE_PRIV,
528 ("trap_pfault: fault on nucleus context from user mode"));
530 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
531 tf->tf_tpc <= (u_long)copy_nofault_end) {
532 vm_map_lock_read(kernel_map);
533 if (vm_map_lookup_entry(kernel_map, va, &entry) &&
534 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
535 tf->tf_tpc = (u_long)copy_fault;
536 tf->tf_tnpc = tf->tf_tpc + 4;
537 vm_map_unlock_read(kernel_map);
540 vm_map_unlock_read(kernel_map);
544 * We don't have to worry about process locking or stacks in
547 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
550 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
552 if (rv == KERN_SUCCESS)
554 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
555 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
556 tf->tf_tpc <= (u_long)fs_nofault_end) {
557 tf->tf_tpc = (u_long)fs_fault;
558 tf->tf_tnpc = tf->tf_tpc + 4;
561 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
562 tf->tf_tpc <= (u_long)copy_nofault_end) {
563 tf->tf_tpc = (u_long)copy_fault;
564 tf->tf_tnpc = tf->tf_tpc + 4;
568 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
571 /* Maximum number of arguments that can be passed via the out registers. */
572 #define REG_MAXARGS 6
575 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
577 struct trapframe *tf;
587 regcnt = REG_MAXARGS;
589 sa->code = tf->tf_global[1];
591 if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
592 sa->code = tf->tf_out[reg++];
596 if (p->p_sysent->sv_mask)
597 sa->code &= p->p_sysent->sv_mask;
598 if (sa->code >= p->p_sysent->sv_size)
599 sa->callp = &p->p_sysent->sv_table[0];
601 sa->callp = &p->p_sysent->sv_table[sa->code];
603 sa->narg = sa->callp->sy_narg;
604 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
605 ("Too many syscall arguments!"));
608 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
609 if (sa->narg > regcnt)
610 error = copyin((void *)(tf->tf_out[6] + SPOFF +
611 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
612 (sa->narg - regcnt) * sizeof(sa->args[0]));
614 td->td_retval[0] = 0;
615 td->td_retval[1] = 0;
623 * The arguments to the syscall are passed in the out registers by the caller,
624 * and are saved in the trap frame. The syscall number is passed in %g1 (and
625 * also saved in the trap frame).
628 syscall(struct trapframe *tf)
631 struct syscall_args sa;
637 KASSERT(td != NULL, ("trap: curthread NULL"));
638 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
641 * For syscalls, we don't want to retry the faulting instruction
642 * (usually), instead we need to advance one instruction.
644 td->td_pcb->pcb_tpc = tf->tf_tpc;
647 error = syscallenter(td, &sa);
648 syscallret(td, error, &sa);