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. 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(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 if (td->td_cowgen != p->p_cowgen)
281 thread_cow_update(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;
487 /* This is a fault on non-kernel virtual memory. */
488 map = &p->p_vmspace->vm_map;
491 * This is a fault on kernel virtual memory. Attempts to
492 * access kernel memory from user mode cause privileged
493 * action traps, not page fault.
495 KASSERT(tf->tf_tstate & TSTATE_PRIV,
496 ("trap_pfault: fault on nucleus context from user mode"));
498 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
499 tf->tf_tpc <= (u_long)copy_nofault_end) {
500 vm_map_lock_read(kernel_map);
501 if (vm_map_lookup_entry(kernel_map, va, &entry) &&
502 (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
503 tf->tf_tpc = (u_long)copy_fault;
504 tf->tf_tnpc = tf->tf_tpc + 4;
505 vm_map_unlock_read(kernel_map);
508 vm_map_unlock_read(kernel_map);
513 /* Fault in the page. */
514 rv = vm_fault(map, va, prot, VM_FAULT_NORMAL);
516 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
518 if (rv == KERN_SUCCESS)
520 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
521 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
522 tf->tf_tpc <= (u_long)fs_nofault_end) {
523 tf->tf_tpc = (u_long)fs_fault;
524 tf->tf_tnpc = tf->tf_tpc + 4;
527 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
528 tf->tf_tpc <= (u_long)copy_nofault_end) {
529 tf->tf_tpc = (u_long)copy_fault;
530 tf->tf_tnpc = tf->tf_tpc + 4;
534 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
537 /* Maximum number of arguments that can be passed via the out registers. */
538 #define REG_MAXARGS 6
541 cpu_fetch_syscall_args(struct thread *td)
543 struct trapframe *tf;
546 struct syscall_args *sa;
555 regcnt = REG_MAXARGS;
557 sa->code = tf->tf_global[1];
559 if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
560 sa->code = tf->tf_out[reg++];
564 if (p->p_sysent->sv_mask)
565 sa->code &= p->p_sysent->sv_mask;
566 if (sa->code >= p->p_sysent->sv_size)
567 sa->callp = &p->p_sysent->sv_table[0];
569 sa->callp = &p->p_sysent->sv_table[sa->code];
571 sa->narg = sa->callp->sy_narg;
572 KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
573 ("Too many syscall arguments!"));
576 bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
577 if (sa->narg > regcnt)
578 error = copyin((void *)(tf->tf_out[6] + SPOFF +
579 offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
580 (sa->narg - regcnt) * sizeof(sa->args[0]));
582 td->td_retval[0] = 0;
583 td->td_retval[1] = 0;
589 #include "../../kern/subr_syscall.c"
593 * The arguments to the syscall are passed in the out registers by the caller,
594 * and are saved in the trap frame. The syscall number is passed in %g1 (and
595 * also saved in the trap frame).
598 syscall(struct trapframe *tf)
606 KASSERT(td != NULL, ("trap: curthread NULL"));
607 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
610 * For syscalls, we don't want to retry the faulting instruction
611 * (usually), instead we need to advance one instruction.
613 td->td_pcb->pcb_tpc = tf->tf_tpc;
616 error = syscallenter(td);
617 syscallret(td, error);