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$");
44 #include <sys/param.h>
46 #include <sys/kernel.h>
48 #include <sys/interrupt.h>
51 #include <sys/mutex.h>
52 #include <sys/systm.h>
54 #include <sys/pioctl.h>
55 #include <sys/ptrace.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>
65 #include <dev/ofw/openfirm.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>
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>
88 void trap(struct trapframe *tf);
89 void syscall(struct trapframe *tf);
91 static int trap_cecc(void);
92 static int trap_pfault(struct thread *td, struct trapframe *tf);
94 extern char copy_fault[];
95 extern char copy_nofault_begin[];
96 extern char copy_nofault_end[];
98 extern char fs_fault[];
99 extern char fs_nofault_begin[];
100 extern char fs_nofault_end[];
101 extern char fs_nofault_intr_begin[];
102 extern char fs_nofault_intr_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(sizeof(trap_msg) / sizeof(*trap_msg) == T_MAX);
219 CTASSERT(sizeof(trap_sig) / sizeof(*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));
270 PCPU_INC(cnt.v_trap);
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 if (td->td_ucred != p->p_ucred)
281 cred_update_thread(td);
283 switch (tf->tf_type) {
285 case T_DATA_PROTECTION:
288 case T_INSTRUCTION_MISS:
289 sig = trap_pfault(td, tf);
292 sig = rwindow_load(td, tf, 2);
295 sig = rwindow_load(td, tf, 1);
298 sig = rwindow_save(td);
300 case T_CORRECTED_ECC_ERROR:
304 if (tf->tf_type > T_MAX)
305 panic("trap: bad trap type %#lx (user)",
307 else if (trap_sig[tf->tf_type] == -1)
308 panic("trap: %s (user)",
309 trap_msg[tf->tf_type]);
310 sig = trap_sig[tf->tf_type];
315 /* Translate fault for emulators. */
316 if (p->p_sysent->sv_transtrap != NULL) {
317 sig = p->p_sysent->sv_transtrap(sig,
320 if (debugger_on_signal &&
321 (sig == 4 || sig == 10 || sig == 11))
322 kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
323 ksiginfo_init_trap(&ksi);
325 ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
326 ksi.ksi_addr = (void *)addr;
327 ksi.ksi_trapno = (int)tf->tf_type;
328 trapsignal(td, &ksi);
333 KASSERT((tf->tf_type & T_KERNEL) != 0,
334 ("trap: kernel trap isn't"));
341 switch (tf->tf_type & ~T_KERNEL) {
344 error = (kdb_trap(tf->tf_type, 0, tf) == 0);
348 case T_PA_WATCHPOINT:
349 case T_VA_WATCHPOINT:
350 error = db_watch_trap(tf);
354 case T_DATA_PROTECTION:
355 case T_INSTRUCTION_MISS:
356 error = trap_pfault(td, tf);
358 case T_DATA_EXCEPTION:
359 case T_MEM_ADDRESS_NOT_ALIGNED:
360 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
361 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
362 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
363 tf->tf_tpc <= (u_long)copy_nofault_end) {
364 tf->tf_tpc = (u_long)copy_fault;
365 tf->tf_tnpc = tf->tf_tpc + 4;
369 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
370 tf->tf_tpc <= (u_long)fs_nofault_end) {
371 tf->tf_tpc = (u_long)fs_fault;
372 tf->tf_tnpc = tf->tf_tpc + 4;
381 * Handle PCI poke/peek as per UltraSPARC IIi
382 * User's Manual 16.2.1, modulo checking the
383 * TPC as USIII CPUs generate a precise trap
384 * instead of a special deferred one.
386 if (tf->tf_tpc > (u_long)fas_nofault_begin &&
387 tf->tf_tpc < (u_long)fas_nofault_end) {
389 cache_enable(PCPU_GET(impl));
390 tf->tf_tpc = (u_long)fas_fault;
391 tf->tf_tnpc = tf->tf_tpc + 4;
397 case T_CORRECTED_ECC_ERROR:
406 tf->tf_type &= ~T_KERNEL;
407 if (tf->tf_type > T_MAX)
408 panic("trap: bad trap type %#lx (kernel)",
410 panic("trap: %s (kernel)", trap_msg[tf->tf_type]);
413 CTR1(KTR_TRAP, "trap: td=%p return", td);
422 * Turn off (non-)correctable error reporting while we're dealing
425 eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
426 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
428 /* Flush the caches in order ensure no corrupt data got installed. */
430 /* Ensure the caches are still turned on (should be). */
431 cache_enable(PCPU_GET(impl));
432 /* Clear the error from the AFSR. */
433 stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
435 printf("corrected ECC error\n");
436 /* Turn (non-)correctable error reporting back on. */
437 stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
442 trap_pfault(struct thread *td, struct trapframe *tf)
448 vm_map_entry_t entry;
455 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
456 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
457 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
462 ctx = TLB_TAR_CTX(tf->tf_tar);
463 type = tf->tf_type & ~T_KERNEL;
464 va = TLB_TAR_VA(tf->tf_tar);
466 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
467 td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
469 if (type == T_DATA_PROTECTION)
470 prot = VM_PROT_WRITE;
472 if (type == T_DATA_MISS)
475 prot = VM_PROT_READ | VM_PROT_EXECUTE;
478 if (ctx != TLB_CTX_KERNEL) {
479 if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
480 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
481 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
482 tf->tf_tpc = (u_long)fs_fault;
483 tf->tf_tnpc = tf->tf_tpc + 4;
488 * This is a fault on non-kernel virtual memory.
493 * Keep swapout from messing with us during this
500 /* Fault in the user page. */
501 rv = vm_fault(&vm->vm_map, va, prot, VM_FAULT_NORMAL);
504 * Now the process can be swapped again.
511 * This is a fault on kernel virtual memory. Attempts to
512 * access kernel memory from user mode cause privileged
513 * action traps, not page fault.
515 KASSERT(tf->tf_tstate & TSTATE_PRIV,
516 ("trap_pfault: fault on nucleus context from user mode"));
518 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
519 tf->tf_tpc <= (u_long)copy_nofault_end) {
520 vm_map_lock_read(kernel_map);
521 if (vm_map_lookup_entry(kernel_map, va, &entry) &&
522 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
523 tf->tf_tpc = (u_long)copy_fault;
524 tf->tf_tnpc = tf->tf_tpc + 4;
525 vm_map_unlock_read(kernel_map);
528 vm_map_unlock_read(kernel_map);
532 * We don't have to worry about process locking or stacks in
535 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
538 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
540 if (rv == KERN_SUCCESS)
542 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
543 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
544 tf->tf_tpc <= (u_long)fs_nofault_end) {
545 tf->tf_tpc = (u_long)fs_fault;
546 tf->tf_tnpc = tf->tf_tpc + 4;
549 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
550 tf->tf_tpc <= (u_long)copy_nofault_end) {
551 tf->tf_tpc = (u_long)copy_fault;
552 tf->tf_tnpc = tf->tf_tpc + 4;
556 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
559 /* Maximum number of arguments that can be passed via the out registers. */
560 #define REG_MAXARGS 6
563 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
565 struct trapframe *tf;
575 regcnt = REG_MAXARGS;
577 sa->code = tf->tf_global[1];
579 if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
580 sa->code = tf->tf_out[reg++];
584 if (p->p_sysent->sv_mask)
585 sa->code &= p->p_sysent->sv_mask;
586 if (sa->code >= p->p_sysent->sv_size)
587 sa->callp = &p->p_sysent->sv_table[0];
589 sa->callp = &p->p_sysent->sv_table[sa->code];
591 sa->narg = sa->callp->sy_narg;
592 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
593 ("Too many syscall arguments!"));
596 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
597 if (sa->narg > regcnt)
598 error = copyin((void *)(tf->tf_out[6] + SPOFF +
599 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
600 (sa->narg - regcnt) * sizeof(sa->args[0]));
602 td->td_retval[0] = 0;
603 td->td_retval[1] = 0;
609 #include "../../kern/subr_syscall.c"
613 * The arguments to the syscall are passed in the out registers by the caller,
614 * and are saved in the trap frame. The syscall number is passed in %g1 (and
615 * also saved in the trap frame).
618 syscall(struct trapframe *tf)
621 struct syscall_args sa;
627 KASSERT(td != NULL, ("trap: curthread NULL"));
628 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
631 * For syscalls, we don't want to retry the faulting instruction
632 * (usually), instead we need to advance one instruction.
634 td->td_pcb->pcb_tpc = tf->tf_tpc;
637 error = syscallenter(td, &sa);
638 syscallret(td, error, &sa);