trap.c revision 219608
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 219608 2011-03-13 13:42:43Z 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(struct trapframe) == 256);
219
220int debugger_on_signal = 0;
221SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
222    &debugger_on_signal, 0, "");
223
224u_int corrected_ecc = 0;
225SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
226    "corrected ECC errors");
227
228/*
229 * SUNW,set-trap-table allows to take over %tba from the PROM, which
230 * will turn off interrupts and handle outstanding ones while doing so,
231 * in a safe way.
232 */
233void
234sun4u_set_traptable(void *tba_addr)
235{
236	static struct {
237		cell_t name;
238		cell_t nargs;
239		cell_t nreturns;
240		cell_t tba_addr;
241	} args = {
242		(cell_t)"SUNW,set-trap-table",
243		1,
244		0,
245	};
246
247	args.tba_addr = (cell_t)tba_addr;
248	ofw_entry(&args);
249}
250
251void
252trap(struct trapframe *tf)
253{
254	struct thread *td;
255	struct proc *p;
256	int error;
257	int sig;
258	register_t addr;
259	ksiginfo_t ksi;
260
261	td = curthread;
262
263	CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td,
264	    trap_msg[tf->tf_type & ~T_KERNEL],
265	    (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil));
266
267	PCPU_INC(cnt.v_trap);
268
269	if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
270		KASSERT(td != NULL, ("trap: curthread NULL"));
271		KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
272
273		p = td->td_proc;
274		td->td_pticks = 0;
275		td->td_frame = tf;
276		addr = tf->tf_tpc;
277		if (td->td_ucred != p->p_ucred)
278			cred_update_thread(td);
279
280		switch (tf->tf_type) {
281		case T_DATA_MISS:
282		case T_DATA_PROTECTION:
283			addr = tf->tf_sfar;
284			/* FALLTHROUGH */
285		case T_INSTRUCTION_MISS:
286			sig = trap_pfault(td, tf);
287			break;
288		case T_FILL:
289			sig = rwindow_load(td, tf, 2);
290			break;
291		case T_FILL_RET:
292			sig = rwindow_load(td, tf, 1);
293			break;
294		case T_SPILL:
295			sig = rwindow_save(td);
296			break;
297		case T_CORRECTED_ECC_ERROR:
298			sig = trap_cecc();
299			break;
300		default:
301			if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
302				panic("trap: bad trap type %#lx (user)",
303				    tf->tf_type);
304			else if (trap_sig[tf->tf_type] == -1)
305				panic("trap: %s (user)",
306				    trap_msg[tf->tf_type]);
307			sig = trap_sig[tf->tf_type];
308			break;
309		}
310
311		if (sig != 0) {
312			/* Translate fault for emulators. */
313			if (p->p_sysent->sv_transtrap != NULL) {
314				sig = p->p_sysent->sv_transtrap(sig,
315				    tf->tf_type);
316			}
317			if (debugger_on_signal &&
318			    (sig == 4 || sig == 10 || sig == 11))
319				kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
320			ksiginfo_init_trap(&ksi);
321			ksi.ksi_signo = sig;
322			ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
323			ksi.ksi_addr = (void *)addr;
324			ksi.ksi_trapno = (int)tf->tf_type;
325			trapsignal(td, &ksi);
326		}
327
328		userret(td, tf);
329		mtx_assert(&Giant, MA_NOTOWNED);
330	} else {
331		KASSERT((tf->tf_type & T_KERNEL) != 0,
332		    ("trap: kernel trap isn't"));
333
334		if (kdb_active) {
335			kdb_reenter();
336			return;
337		}
338
339		switch (tf->tf_type & ~T_KERNEL) {
340		case T_BREAKPOINT:
341		case T_KSTACK_FAULT:
342			error = (kdb_trap(tf->tf_type, 0, tf) == 0);
343			TF_DONE(tf);
344			break;
345#ifdef notyet
346		case T_PA_WATCHPOINT:
347		case T_VA_WATCHPOINT:
348			error = db_watch_trap(tf);
349			break;
350#endif
351		case T_DATA_MISS:
352		case T_DATA_PROTECTION:
353		case T_INSTRUCTION_MISS:
354			error = trap_pfault(td, tf);
355			break;
356		case T_DATA_EXCEPTION:
357		case T_MEM_ADDRESS_NOT_ALIGNED:
358			if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
359			    MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
360				if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
361				    tf->tf_tpc <= (u_long)copy_nofault_end) {
362					tf->tf_tpc = (u_long)copy_fault;
363					tf->tf_tnpc = tf->tf_tpc + 4;
364					error = 0;
365					break;
366				}
367				if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
368				    tf->tf_tpc <= (u_long)fs_nofault_end) {
369					tf->tf_tpc = (u_long)fs_fault;
370					tf->tf_tnpc = tf->tf_tpc + 4;
371					error = 0;
372					break;
373				}
374			}
375			error = 1;
376			break;
377		case T_DATA_ERROR:
378			/*
379			 * Handle PCI poke/peek as per UltraSPARC IIi
380			 * User's Manual 16.2.1, modulo checking the
381			 * TPC as USIII CPUs generate a precise trap
382			 * instead of a special deferred one.
383			 */
384			if (tf->tf_tpc > (u_long)fas_nofault_begin &&
385			    tf->tf_tpc < (u_long)fas_nofault_end) {
386				cache_flush();
387				cache_enable(PCPU_GET(impl));
388				tf->tf_tpc = (u_long)fas_fault;
389				tf->tf_tnpc = tf->tf_tpc + 4;
390				error = 0;
391				break;
392			}
393			error = 1;
394			break;
395		case T_CORRECTED_ECC_ERROR:
396			error = trap_cecc();
397			break;
398		default:
399			error = 1;
400			break;
401		}
402
403		if (error != 0) {
404			tf->tf_type &= ~T_KERNEL;
405			if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
406				panic("trap: bad trap type %#lx (kernel)",
407				    tf->tf_type);
408			else if (trap_sig[tf->tf_type] == -1)
409				panic("trap: %s (kernel)",
410				    trap_msg[tf->tf_type]);
411		}
412	}
413	CTR1(KTR_TRAP, "trap: td=%p return", td);
414}
415
416static int
417trap_cecc(void)
418{
419	u_long eee;
420
421	/*
422	 * Turn off (non-)correctable error reporting while we're dealing
423	 * with the error.
424	 */
425	eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
426	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
427	    AA_ESTATE_CEEN));
428	/* Flush the caches in order ensure no corrupt data got installed. */
429	cache_flush();
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));
434	corrected_ecc++;
435	printf("corrected ECC error\n");
436	/* Turn (non-)correctable error reporting back on. */
437	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
438	return (0);
439}
440
441static int
442trap_pfault(struct thread *td, struct trapframe *tf)
443{
444	struct vmspace *vm;
445	struct proc *p;
446	vm_offset_t va;
447	vm_prot_t prot;
448	vm_map_entry_t entry;
449	u_long ctx;
450	int type;
451	int rv;
452
453	if (td == NULL)
454		return (-1);
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"));
458
459	p = td->td_proc;
460
461	rv = KERN_SUCCESS;
462	ctx = TLB_TAR_CTX(tf->tf_tar);
463	type = tf->tf_type & ~T_KERNEL;
464	va = TLB_TAR_VA(tf->tf_tar);
465
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);
468
469	if (type == T_DATA_PROTECTION)
470		prot = VM_PROT_WRITE;
471	else {
472		if (type == T_DATA_MISS)
473			prot = VM_PROT_READ;
474		else
475			prot = VM_PROT_READ | VM_PROT_EXECUTE;
476	}
477
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;
484			return (0);
485		}
486
487		/*
488		 * This is a fault on non-kernel virtual memory.
489		 */
490		vm = p->p_vmspace;
491
492		/*
493		 * Keep swapout from messing with us during this
494		 * critical time.
495		 */
496		PROC_LOCK(p);
497		++p->p_lock;
498		PROC_UNLOCK(p);
499
500		/* Fault in the user page. */
501		rv = vm_fault(&vm->vm_map, va, prot, VM_FAULT_NORMAL);
502
503		/*
504		 * Now the process can be swapped again.
505		 */
506		PROC_LOCK(p);
507		--p->p_lock;
508		PROC_UNLOCK(p);
509	} else {
510		/*
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.
514		 */
515		KASSERT(tf->tf_tstate & TSTATE_PRIV,
516		    ("trap_pfault: fault on nucleus context from user mode"));
517
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);
526				return (0);
527			}
528			vm_map_unlock_read(kernel_map);
529		}
530
531		/*
532		 * We don't have to worry about process locking or stacks in
533		 * the kernel.
534		 */
535		rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
536	}
537
538	CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
539	    td, va, rv);
540	if (rv == KERN_SUCCESS)
541		return (0);
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;
547			return (0);
548		}
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;
553			return (0);
554		}
555	}
556	return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
557}
558
559/* Maximum number of arguments that can be passed via the out registers. */
560#define	REG_MAXARGS	6
561
562int
563cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
564{
565	struct trapframe *tf;
566	struct proc *p;
567	register_t *argp;
568	int reg;
569	int regcnt;
570	int error;
571
572	p = td->td_proc;
573	tf = td->td_frame;
574	reg = 0;
575	regcnt = REG_MAXARGS;
576
577	sa->code = tf->tf_global[1];
578
579	if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
580		sa->code = tf->tf_out[reg++];
581		regcnt--;
582	}
583
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];
588	else
589		sa->callp = &p->p_sysent->sv_table[sa->code];
590
591	sa->narg = sa->callp->sy_narg;
592	KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
593	    ("Too many syscall arguments!"));
594	error = 0;
595	argp = sa->args;
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]));
601	if (error == 0) {
602		td->td_retval[0] = 0;
603		td->td_retval[1] = 0;
604	}
605
606	return (error);
607}
608
609/*
610 * Syscall handler
611 * The arguments to the syscall are passed in the out registers by the caller,
612 * and are saved in the trap frame.  The syscall number is passed in %g1 (and
613 * also saved in the trap frame).
614 */
615void
616syscall(struct trapframe *tf)
617{
618	struct thread *td;
619	struct syscall_args sa;
620	int error;
621
622	td = curthread;
623	td->td_frame = tf;
624
625	KASSERT(td != NULL, ("trap: curthread NULL"));
626	KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
627
628	/*
629	 * For syscalls, we don't want to retry the faulting instruction
630	 * (usually), instead we need to advance one instruction.
631	 */
632	td->td_pcb->pcb_tpc = tf->tf_tpc;
633	TF_DONE(tf);
634
635	error = syscallenter(td, &sa);
636	syscallret(td, error, &sa);
637}
638