trap.c revision 233748
1/*-
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.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the University of Utah, and William Jolitz.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
21 *
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
32 * SUCH DAMAGE.
33 *
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
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/trap.c 233748 2012-03-31 14:03:16Z marius $");
40
41#include "opt_ddb.h"
42#include "opt_ktr.h"
43
44#include <sys/param.h>
45#include <sys/kdb.h>
46#include <sys/kernel.h>
47#include <sys/bus.h>
48#include <sys/interrupt.h>
49#include <sys/ktr.h>
50#include <sys/lock.h>
51#include <sys/mutex.h>
52#include <sys/systm.h>
53#include <sys/pcpu.h>
54#include <sys/pioctl.h>
55#include <sys/ptrace.h>
56#include <sys/proc.h>
57#include <sys/smp.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>
64
65#include <dev/ofw/openfirm.h>
66
67#include <vm/vm.h>
68#include <vm/pmap.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>
74
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>
87
88void trap(struct trapframe *tf);
89void syscall(struct trapframe *tf);
90
91static int trap_cecc(void);
92static int trap_pfault(struct thread *td, struct trapframe *tf);
93
94extern char copy_fault[];
95extern char copy_nofault_begin[];
96extern char copy_nofault_end[];
97
98extern char fs_fault[];
99extern char fs_nofault_begin[];
100extern char fs_nofault_end[];
101extern char fs_nofault_intr_begin[];
102extern char fs_nofault_intr_end[];
103
104extern char fas_fault[];
105extern char fas_nofault_begin[];
106extern char fas_nofault_end[];
107
108const char *const trap_msg[] = {
109	"reserved",
110	"instruction access exception",
111	"instruction access error",
112	"instruction access protection",
113	"illtrap instruction",
114	"illegal instruction",
115	"privileged opcode",
116	"floating point disabled",
117	"floating point exception ieee 754",
118	"floating point exception other",
119	"tag overflow",
120	"division by zero",
121	"data access exception",
122	"data access error",
123	"data access protection",
124	"memory address not aligned",
125	"privileged action",
126	"async data error",
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",
145	"interrupt",
146	"physical address watchpoint",
147	"virtual address watchpoint",
148	"corrected ecc error",
149	"spill",
150	"fill",
151	"fill",
152	"breakpoint",
153	"clean window",
154	"range check",
155	"fix alignment",
156	"integer overflow",
157	"syscall",
158	"restore physical watchpoint",
159	"restore virtual watchpoint",
160	"kernel stack fault",
161};
162
163static 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 */
200	-1,			/* interrupt */
201	-1,			/* physical address watchpoint */
202	-1,			/* virtual address watchpoint */
203	-1,			/* corrected ecc error */
204	SIGILL,			/* spill */
205	SIGILL,			/* fill */
206	SIGILL,			/* fill */
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 */
216};
217
218CTASSERT(sizeof(trap_msg) / sizeof(*trap_msg) == T_MAX);
219CTASSERT(sizeof(trap_sig) / sizeof(*trap_sig) == T_MAX);
220
221CTASSERT(sizeof(struct trapframe) == 256);
222
223int debugger_on_signal = 0;
224SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
225    &debugger_on_signal, 0, "");
226
227u_int corrected_ecc = 0;
228SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
229    "corrected ECC errors");
230
231/*
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,
234 * in a safe way.
235 */
236void
237sun4u_set_traptable(void *tba_addr)
238{
239	static struct {
240		cell_t name;
241		cell_t nargs;
242		cell_t nreturns;
243		cell_t tba_addr;
244	} args = {
245		(cell_t)"SUNW,set-trap-table",
246		1,
247		0,
248	};
249
250	args.tba_addr = (cell_t)tba_addr;
251	ofw_entry(&args);
252}
253
254void
255trap(struct trapframe *tf)
256{
257	struct thread *td;
258	struct proc *p;
259	int error;
260	int sig;
261	register_t addr;
262	ksiginfo_t ksi;
263
264	td = curthread;
265
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));
269
270	PCPU_INC(cnt.v_trap);
271
272	if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
273		KASSERT(td != NULL, ("trap: curthread NULL"));
274		KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
275
276		p = td->td_proc;
277		td->td_pticks = 0;
278		td->td_frame = tf;
279		addr = tf->tf_tpc;
280		if (td->td_ucred != p->p_ucred)
281			cred_update_thread(td);
282
283		switch (tf->tf_type) {
284		case T_DATA_MISS:
285		case T_DATA_PROTECTION:
286			addr = tf->tf_sfar;
287			/* FALLTHROUGH */
288		case T_INSTRUCTION_MISS:
289			sig = trap_pfault(td, tf);
290			break;
291		case T_FILL:
292			sig = rwindow_load(td, tf, 2);
293			break;
294		case T_FILL_RET:
295			sig = rwindow_load(td, tf, 1);
296			break;
297		case T_SPILL:
298			sig = rwindow_save(td);
299			break;
300		case T_CORRECTED_ECC_ERROR:
301			sig = trap_cecc();
302			break;
303		default:
304			if (tf->tf_type > T_MAX)
305				panic("trap: bad trap type %#lx (user)",
306				    tf->tf_type);
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];
311			break;
312		}
313
314		if (sig != 0) {
315			/* Translate fault for emulators. */
316			if (p->p_sysent->sv_transtrap != NULL) {
317				sig = p->p_sysent->sv_transtrap(sig,
318				    tf->tf_type);
319			}
320			if (debugger_on_signal &&
321			    (sig == 4 || sig == 10 || sig == 11))
322				kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
323			ksiginfo_init_trap(&ksi);
324			ksi.ksi_signo = sig;
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);
329		}
330
331		userret(td, tf);
332		mtx_assert(&Giant, MA_NOTOWNED);
333	} else {
334		KASSERT((tf->tf_type & T_KERNEL) != 0,
335		    ("trap: kernel trap isn't"));
336
337		if (kdb_active) {
338			kdb_reenter();
339			return;
340		}
341
342		switch (tf->tf_type & ~T_KERNEL) {
343		case T_BREAKPOINT:
344		case T_KSTACK_FAULT:
345			error = (kdb_trap(tf->tf_type, 0, tf) == 0);
346			TF_DONE(tf);
347			break;
348#ifdef notyet
349		case T_PA_WATCHPOINT:
350		case T_VA_WATCHPOINT:
351			error = db_watch_trap(tf);
352			break;
353#endif
354		case T_DATA_MISS:
355		case T_DATA_PROTECTION:
356		case T_INSTRUCTION_MISS:
357			error = trap_pfault(td, tf);
358			break;
359		case T_DATA_EXCEPTION:
360		case T_MEM_ADDRESS_NOT_ALIGNED:
361			if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
362			    MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
363				if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
364				    tf->tf_tpc <= (u_long)copy_nofault_end) {
365					tf->tf_tpc = (u_long)copy_fault;
366					tf->tf_tnpc = tf->tf_tpc + 4;
367					error = 0;
368					break;
369				}
370				if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
371				    tf->tf_tpc <= (u_long)fs_nofault_end) {
372					tf->tf_tpc = (u_long)fs_fault;
373					tf->tf_tnpc = tf->tf_tpc + 4;
374					error = 0;
375					break;
376				}
377			}
378			error = 1;
379			break;
380		case T_DATA_ERROR:
381			/*
382			 * Handle PCI poke/peek as per UltraSPARC IIi
383			 * User's Manual 16.2.1, modulo checking the
384			 * TPC as USIII CPUs generate a precise trap
385			 * instead of a special deferred one.
386			 */
387			if (tf->tf_tpc > (u_long)fas_nofault_begin &&
388			    tf->tf_tpc < (u_long)fas_nofault_end) {
389				cache_flush();
390				cache_enable(PCPU_GET(impl));
391				tf->tf_tpc = (u_long)fas_fault;
392				tf->tf_tnpc = tf->tf_tpc + 4;
393				error = 0;
394				break;
395			}
396			error = 1;
397			break;
398		case T_CORRECTED_ECC_ERROR:
399			error = trap_cecc();
400			break;
401		default:
402			error = 1;
403			break;
404		}
405
406		if (error != 0) {
407			tf->tf_type &= ~T_KERNEL;
408			if (tf->tf_type > T_MAX)
409				panic("trap: bad trap type %#lx (kernel)",
410				    tf->tf_type);
411			panic("trap: %s (kernel)", trap_msg[tf->tf_type]);
412		}
413	}
414	CTR1(KTR_TRAP, "trap: td=%p return", td);
415}
416
417static int
418trap_cecc(void)
419{
420	u_long eee;
421
422	/*
423	 * Turn off (non-)correctable error reporting while we're dealing
424	 * with the error.
425	 */
426	eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
427	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
428	    AA_ESTATE_CEEN));
429	/* Flush the caches in order ensure no corrupt data got installed. */
430	cache_flush();
431	/* Ensure the caches are still turned on (should be). */
432	cache_enable(PCPU_GET(impl));
433	/* Clear the error from the AFSR. */
434	stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
435	corrected_ecc++;
436	printf("corrected ECC error\n");
437	/* Turn (non-)correctable error reporting back on. */
438	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
439	return (0);
440}
441
442static int
443trap_pfault(struct thread *td, struct trapframe *tf)
444{
445	struct vmspace *vm;
446	struct proc *p;
447	vm_offset_t va;
448	vm_prot_t prot;
449	vm_map_entry_t entry;
450	u_long ctx;
451	int type;
452	int rv;
453
454	if (td == NULL)
455		return (-1);
456	KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
457	KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
458	KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
459
460	p = td->td_proc;
461
462	rv = KERN_SUCCESS;
463	ctx = TLB_TAR_CTX(tf->tf_tar);
464	type = tf->tf_type & ~T_KERNEL;
465	va = TLB_TAR_VA(tf->tf_tar);
466
467	CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
468	    td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
469
470	if (type == T_DATA_PROTECTION)
471		prot = VM_PROT_WRITE;
472	else {
473		if (type == T_DATA_MISS)
474			prot = VM_PROT_READ;
475		else
476			prot = VM_PROT_READ | VM_PROT_EXECUTE;
477	}
478
479	if (ctx != TLB_CTX_KERNEL) {
480		if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
481		    (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
482		    tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
483			tf->tf_tpc = (u_long)fs_fault;
484			tf->tf_tnpc = tf->tf_tpc + 4;
485			return (0);
486		}
487
488		/*
489		 * This is a fault on non-kernel virtual memory.
490		 */
491		vm = p->p_vmspace;
492
493		/*
494		 * Keep swapout from messing with us during this
495		 * critical time.
496		 */
497		PROC_LOCK(p);
498		++p->p_lock;
499		PROC_UNLOCK(p);
500
501		/* Fault in the user page. */
502		rv = vm_fault(&vm->vm_map, va, prot, VM_FAULT_NORMAL);
503
504		/*
505		 * Now the process can be swapped again.
506		 */
507		PROC_LOCK(p);
508		--p->p_lock;
509		PROC_UNLOCK(p);
510	} else {
511		/*
512		 * This is a fault on kernel virtual memory.  Attempts to
513		 * access kernel memory from user mode cause privileged
514		 * action traps, not page fault.
515		 */
516		KASSERT(tf->tf_tstate & TSTATE_PRIV,
517		    ("trap_pfault: fault on nucleus context from user mode"));
518
519		if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
520		    tf->tf_tpc <= (u_long)copy_nofault_end) {
521			vm_map_lock_read(kernel_map);
522			if (vm_map_lookup_entry(kernel_map, va, &entry) &&
523			    (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
524				tf->tf_tpc = (u_long)copy_fault;
525				tf->tf_tnpc = tf->tf_tpc + 4;
526				vm_map_unlock_read(kernel_map);
527				return (0);
528			}
529			vm_map_unlock_read(kernel_map);
530		}
531
532		/*
533		 * We don't have to worry about process locking or stacks in
534		 * the kernel.
535		 */
536		rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
537	}
538
539	CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
540	    td, va, rv);
541	if (rv == KERN_SUCCESS)
542		return (0);
543	if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
544		if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
545		    tf->tf_tpc <= (u_long)fs_nofault_end) {
546			tf->tf_tpc = (u_long)fs_fault;
547			tf->tf_tnpc = tf->tf_tpc + 4;
548			return (0);
549		}
550		if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
551		    tf->tf_tpc <= (u_long)copy_nofault_end) {
552			tf->tf_tpc = (u_long)copy_fault;
553			tf->tf_tnpc = tf->tf_tpc + 4;
554			return (0);
555		}
556	}
557	return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
558}
559
560/* Maximum number of arguments that can be passed via the out registers. */
561#define	REG_MAXARGS	6
562
563int
564cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
565{
566	struct trapframe *tf;
567	struct proc *p;
568	register_t *argp;
569	int reg;
570	int regcnt;
571	int error;
572
573	p = td->td_proc;
574	tf = td->td_frame;
575	reg = 0;
576	regcnt = REG_MAXARGS;
577
578	sa->code = tf->tf_global[1];
579
580	if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
581		sa->code = tf->tf_out[reg++];
582		regcnt--;
583	}
584
585	if (p->p_sysent->sv_mask)
586		sa->code &= p->p_sysent->sv_mask;
587	if (sa->code >= p->p_sysent->sv_size)
588		sa->callp = &p->p_sysent->sv_table[0];
589	else
590		sa->callp = &p->p_sysent->sv_table[sa->code];
591
592	sa->narg = sa->callp->sy_narg;
593	KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
594	    ("Too many syscall arguments!"));
595	error = 0;
596	argp = sa->args;
597	bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
598	if (sa->narg > regcnt)
599		error = copyin((void *)(tf->tf_out[6] + SPOFF +
600		    offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
601		    (sa->narg - regcnt) * sizeof(sa->args[0]));
602	if (error == 0) {
603		td->td_retval[0] = 0;
604		td->td_retval[1] = 0;
605	}
606
607	return (error);
608}
609
610#include "../../kern/subr_syscall.c"
611
612/*
613 * Syscall handler
614 * The arguments to the syscall are passed in the out registers by the caller,
615 * and are saved in the trap frame.  The syscall number is passed in %g1 (and
616 * also saved in the trap frame).
617 */
618void
619syscall(struct trapframe *tf)
620{
621	struct thread *td;
622	struct syscall_args sa;
623	int error;
624
625	td = curthread;
626	td->td_frame = tf;
627
628	KASSERT(td != NULL, ("trap: curthread NULL"));
629	KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
630
631	/*
632	 * For syscalls, we don't want to retry the faulting instruction
633	 * (usually), instead we need to advance one instruction.
634	 */
635	td->td_pcb->pcb_tpc = tf->tf_tpc;
636	TF_DONE(tf);
637
638	error = syscallenter(td, &sa);
639	syscallret(td, error, &sa);
640}
641