trap.c revision 199135
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 * 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.
25 *
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
36 * SUCH DAMAGE.
37 *
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
40 */
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/trap.c 199135 2009-11-10 11:43:07Z kib $");
44
45#include "opt_ddb.h"
46#include "opt_ktr.h"
47#include "opt_ktrace.h"
48
49#include <sys/param.h>
50#include <sys/kdb.h>
51#include <sys/kernel.h>
52#include <sys/bus.h>
53#include <sys/interrupt.h>
54#include <sys/ktr.h>
55#include <sys/lock.h>
56#include <sys/mutex.h>
57#include <sys/systm.h>
58#include <sys/pioctl.h>
59#include <sys/ptrace.h>
60#include <sys/proc.h>
61#include <sys/smp.h>
62#include <sys/signalvar.h>
63#include <sys/syscall.h>
64#include <sys/sysctl.h>
65#include <sys/sysent.h>
66#include <sys/vmmeter.h>
67#ifdef KTRACE
68#include <sys/uio.h>
69#include <sys/ktrace.h>
70#endif
71#include <security/audit/audit.h>
72
73#include <dev/ofw/openfirm.h>
74
75#include <vm/vm.h>
76#include <vm/pmap.h>
77#include <vm/vm_extern.h>
78#include <vm/vm_param.h>
79#include <vm/vm_kern.h>
80#include <vm/vm_map.h>
81#include <vm/vm_page.h>
82
83#include <machine/cpu.h>
84#include <machine/frame.h>
85#include <machine/intr_machdep.h>
86#include <machine/ofw_machdep.h>
87#include <machine/smp.h>
88#include <machine/trap.h>
89#include <machine/tstate.h>
90#include <machine/tte.h>
91#include <machine/tlb.h>
92#include <machine/tsb.h>
93#include <machine/watch.h>
94
95void trap(struct trapframe *tf);
96void syscall(struct trapframe *tf);
97
98static int trap_pfault(struct thread *td, struct trapframe *tf);
99
100extern char copy_fault[];
101extern char copy_nofault_begin[];
102extern char copy_nofault_end[];
103
104extern char fs_fault[];
105extern char fs_nofault_begin[];
106extern char fs_nofault_end[];
107extern char fs_nofault_intr_begin[];
108extern char fs_nofault_intr_end[];
109
110extern char fas_fault[];
111extern char fas_nofault_begin[];
112extern char fas_nofault_end[];
113
114extern char *syscallnames[];
115
116const char *const trap_msg[] = {
117	"reserved",
118	"instruction access exception",
119	"instruction access error",
120	"instruction access protection",
121	"illtrap instruction",
122	"illegal instruction",
123	"privileged opcode",
124	"floating point disabled",
125	"floating point exception ieee 754",
126	"floating point exception other",
127	"tag overflow",
128	"division by zero",
129	"data access exception",
130	"data access error",
131	"data access protection",
132	"memory address not aligned",
133	"privileged action",
134	"async data error",
135	"trap instruction 16",
136	"trap instruction 17",
137	"trap instruction 18",
138	"trap instruction 19",
139	"trap instruction 20",
140	"trap instruction 21",
141	"trap instruction 22",
142	"trap instruction 23",
143	"trap instruction 24",
144	"trap instruction 25",
145	"trap instruction 26",
146	"trap instruction 27",
147	"trap instruction 28",
148	"trap instruction 29",
149	"trap instruction 30",
150	"trap instruction 31",
151	"fast instruction access mmu miss",
152	"fast data access mmu miss",
153	"interrupt",
154	"physical address watchpoint",
155	"virtual address watchpoint",
156	"corrected ecc error",
157	"spill",
158	"fill",
159	"fill",
160	"breakpoint",
161	"clean window",
162	"range check",
163	"fix alignment",
164	"integer overflow",
165	"syscall",
166	"restore physical watchpoint",
167	"restore virtual watchpoint",
168	"kernel stack fault",
169};
170
171static const int trap_sig[] = {
172	SIGILL,			/* reserved */
173	SIGILL,			/* instruction access exception */
174	SIGILL,			/* instruction access error */
175	SIGILL,			/* instruction access protection */
176	SIGILL,			/* illtrap instruction */
177	SIGILL,			/* illegal instruction */
178	SIGBUS,			/* privileged opcode */
179	SIGFPE,			/* floating point disabled */
180	SIGFPE,			/* floating point exception ieee 754 */
181	SIGFPE,			/* floating point exception other */
182	SIGEMT,			/* tag overflow */
183	SIGFPE,			/* division by zero */
184	SIGILL,			/* data access exception */
185	SIGILL,			/* data access error */
186	SIGBUS,			/* data access protection */
187	SIGBUS,			/* memory address not aligned */
188	SIGBUS,			/* privileged action */
189	SIGBUS,			/* async data error */
190	SIGILL,			/* trap instruction 16 */
191	SIGILL,			/* trap instruction 17 */
192	SIGILL,			/* trap instruction 18 */
193	SIGILL,			/* trap instruction 19 */
194	SIGILL,			/* trap instruction 20 */
195	SIGILL,			/* trap instruction 21 */
196	SIGILL,			/* trap instruction 22 */
197	SIGILL,			/* trap instruction 23 */
198	SIGILL,			/* trap instruction 24 */
199	SIGILL,			/* trap instruction 25 */
200	SIGILL,			/* trap instruction 26 */
201	SIGILL,			/* trap instruction 27 */
202	SIGILL,			/* trap instruction 28 */
203	SIGILL,			/* trap instruction 29 */
204	SIGILL,			/* trap instruction 30 */
205	SIGILL,			/* trap instruction 31 */
206	SIGSEGV,		/* fast instruction access mmu miss */
207	SIGSEGV,		/* fast data access mmu miss */
208	-1,			/* interrupt */
209	-1,			/* physical address watchpoint */
210	-1,			/* virtual address watchpoint */
211	-1,			/* corrected ecc error */
212	SIGILL,			/* spill */
213	SIGILL,			/* fill */
214	SIGILL,			/* fill */
215	SIGTRAP,		/* breakpoint */
216	SIGILL,			/* clean window */
217	SIGILL,			/* range check */
218	SIGILL,			/* fix alignment */
219	SIGILL,			/* integer overflow */
220	SIGSYS,			/* syscall */
221	-1,			/* restore physical watchpoint */
222	-1,			/* restore virtual watchpoint */
223	-1,			/* kernel stack fault */
224};
225
226CTASSERT(sizeof(struct trapframe) == 256);
227
228int debugger_on_signal = 0;
229SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
230    &debugger_on_signal, 0, "");
231
232/*
233 * SUNW,set-trap-table allows to take over %tba from the PROM, which
234 * will turn off interrupts and handle outstanding ones while doing so,
235 * in a safe way.
236 */
237void
238sun4u_set_traptable(void *tba_addr)
239{
240	static struct {
241		cell_t name;
242		cell_t nargs;
243		cell_t nreturns;
244		cell_t tba_addr;
245	} args = {
246		(cell_t)"SUNW,set-trap-table",
247		2,
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		default:
301			if (tf->tf_type < 0 || tf->tf_type >= T_MAX ||
302			    trap_sig[tf->tf_type] == -1)
303				panic("trap: bad trap type");
304			sig = trap_sig[tf->tf_type];
305			break;
306		}
307
308		if (sig != 0) {
309			/* Translate fault for emulators. */
310			if (p->p_sysent->sv_transtrap != NULL) {
311				sig = p->p_sysent->sv_transtrap(sig,
312				    tf->tf_type);
313			}
314			if (debugger_on_signal &&
315			    (sig == 4 || sig == 10 || sig == 11))
316				kdb_enter(KDB_WHY_TRAPSIG, "trapsig");
317			ksiginfo_init_trap(&ksi);
318			ksi.ksi_signo = sig;
319			ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
320			ksi.ksi_addr = (void *)addr;
321			ksi.ksi_trapno = (int)tf->tf_type;
322			trapsignal(td, &ksi);
323		}
324
325		userret(td, tf);
326		mtx_assert(&Giant, MA_NOTOWNED);
327	} else {
328		KASSERT((tf->tf_type & T_KERNEL) != 0,
329		    ("trap: kernel trap isn't"));
330
331		if (kdb_active) {
332			kdb_reenter();
333			return;
334		}
335
336		switch (tf->tf_type & ~T_KERNEL) {
337		case T_BREAKPOINT:
338		case T_KSTACK_FAULT:
339			error = (kdb_trap(tf->tf_type, 0, tf) == 0);
340			TF_DONE(tf);
341			break;
342#ifdef notyet
343		case T_PA_WATCHPOINT:
344		case T_VA_WATCHPOINT:
345			error = db_watch_trap(tf);
346			break;
347#endif
348		case T_DATA_MISS:
349		case T_DATA_PROTECTION:
350		case T_INSTRUCTION_MISS:
351			error = trap_pfault(td, tf);
352			break;
353		case T_DATA_EXCEPTION:
354		case T_MEM_ADDRESS_NOT_ALIGNED:
355			if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
356			    MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
357				if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
358				    tf->tf_tpc <= (u_long)copy_nofault_end) {
359					tf->tf_tpc = (u_long)copy_fault;
360					tf->tf_tnpc = tf->tf_tpc + 4;
361					error = 0;
362					break;
363				}
364				if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
365				    tf->tf_tpc <= (u_long)fs_nofault_end) {
366					tf->tf_tpc = (u_long)fs_fault;
367					tf->tf_tnpc = tf->tf_tpc + 4;
368					error = 0;
369					break;
370				}
371			}
372			error = 1;
373			break;
374		case T_DATA_ERROR:
375			/*
376			 * Handle PCI poke/peek as per UltraSPARC IIi
377			 * User's Manual 16.2.1, modulo checking the
378			 * TPC as USIII CPUs generate a precise trap
379			 * instead of a special deferred one.
380			 */
381			if (tf->tf_tpc > (u_long)fas_nofault_begin &&
382			    tf->tf_tpc < (u_long)fas_nofault_end) {
383				cache_flush();
384				cache_enable();
385				tf->tf_tpc = (u_long)fas_fault;
386				tf->tf_tnpc = tf->tf_tpc + 4;
387				error = 0;
388				break;
389			}
390			error = 1;
391			break;
392		default:
393			error = 1;
394			break;
395		}
396
397		if (error != 0)
398			panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]);
399	}
400	CTR1(KTR_TRAP, "trap: td=%p return", td);
401}
402
403static int
404trap_pfault(struct thread *td, struct trapframe *tf)
405{
406	struct vmspace *vm;
407	struct proc *p;
408	vm_offset_t va;
409	vm_prot_t prot;
410	vm_map_entry_t entry;
411	u_long ctx;
412	int flags;
413	int type;
414	int rv;
415
416	if (td == NULL)
417		return (-1);
418	KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
419	KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
420	KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
421
422	p = td->td_proc;
423
424	rv = KERN_SUCCESS;
425	ctx = TLB_TAR_CTX(tf->tf_tar);
426	type = tf->tf_type & ~T_KERNEL;
427	va = TLB_TAR_VA(tf->tf_tar);
428
429	CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
430	    td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx);
431
432	if (type == T_DATA_PROTECTION) {
433		prot = VM_PROT_WRITE;
434		flags = VM_FAULT_DIRTY;
435	} else {
436		if (type == T_DATA_MISS)
437			prot = VM_PROT_READ;
438		else
439			prot = VM_PROT_READ | VM_PROT_EXECUTE;
440		flags = VM_FAULT_NORMAL;
441	}
442
443	if (ctx != TLB_CTX_KERNEL) {
444		if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
445		    (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
446		    tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
447			tf->tf_tpc = (u_long)fs_fault;
448			tf->tf_tnpc = tf->tf_tpc + 4;
449			return (0);
450		}
451
452		/*
453		 * This is a fault on non-kernel virtual memory.
454		 */
455		vm = p->p_vmspace;
456
457		/*
458		 * Keep swapout from messing with us during this
459		 * critical time.
460		 */
461		PROC_LOCK(p);
462		++p->p_lock;
463		PROC_UNLOCK(p);
464
465		/* Fault in the user page. */
466		rv = vm_fault(&vm->vm_map, va, prot, flags);
467
468		/*
469		 * Now the process can be swapped again.
470		 */
471		PROC_LOCK(p);
472		--p->p_lock;
473		PROC_UNLOCK(p);
474	} else {
475		/*
476		 * This is a fault on kernel virtual memory.  Attempts to
477		 * access kernel memory from user mode cause privileged
478		 * action traps, not page fault.
479		 */
480		KASSERT(tf->tf_tstate & TSTATE_PRIV,
481		    ("trap_pfault: fault on nucleus context from user mode"));
482
483		if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
484		    tf->tf_tpc <= (u_long)copy_nofault_end) {
485			vm_map_lock_read(kernel_map);
486			if (vm_map_lookup_entry(kernel_map, va, &entry) &&
487			    (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
488				tf->tf_tpc = (u_long)copy_fault;
489				tf->tf_tnpc = tf->tf_tpc + 4;
490				vm_map_unlock_read(kernel_map);
491				return (0);
492			}
493			vm_map_unlock_read(kernel_map);
494		}
495
496		/*
497		 * We don't have to worry about process locking or stacks in
498		 * the kernel.
499		 */
500		rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
501	}
502
503	CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
504	    td, va, rv);
505	if (rv == KERN_SUCCESS)
506		return (0);
507	if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
508		if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
509		    tf->tf_tpc <= (u_long)fs_nofault_end) {
510			tf->tf_tpc = (u_long)fs_fault;
511			tf->tf_tnpc = tf->tf_tpc + 4;
512			return (0);
513		}
514		if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
515		    tf->tf_tpc <= (u_long)copy_nofault_end) {
516			tf->tf_tpc = (u_long)copy_fault;
517			tf->tf_tnpc = tf->tf_tpc + 4;
518			return (0);
519		}
520	}
521	return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
522}
523
524/* Maximum number of arguments that can be passed via the out registers. */
525#define	REG_MAXARGS	6
526
527/*
528 * Syscall handler. The arguments to the syscall are passed in the o registers
529 * by the caller, and are saved in the trap frame. The syscall number is passed
530 * in %g1 (and also saved in the trap frame).
531 */
532void
533syscall(struct trapframe *tf)
534{
535	struct sysent *callp;
536	struct thread *td;
537	register_t args[8];
538	register_t *argp;
539	struct proc *p;
540	u_long code;
541	int reg;
542	int regcnt;
543	int narg;
544	int error;
545
546	td = curthread;
547	KASSERT(td != NULL, ("trap: curthread NULL"));
548	KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
549
550	p = td->td_proc;
551
552	PCPU_INC(cnt.v_syscall);
553
554	td->td_pticks = 0;
555	td->td_frame = tf;
556	if (td->td_ucred != p->p_ucred)
557		cred_update_thread(td);
558	code = tf->tf_global[1];
559
560	/*
561	 * For syscalls, we don't want to retry the faulting instruction
562	 * (usually), instead we need to advance one instruction.
563	 */
564	td->td_pcb->pcb_tpc = tf->tf_tpc;
565	TF_DONE(tf);
566
567	reg = 0;
568	regcnt = REG_MAXARGS;
569	if (p->p_sysent->sv_prepsyscall) {
570		/*
571		 * The prep code is MP aware.
572		 */
573#if 0
574		(*p->p_sysent->sv_prepsyscall)(tf, args, &code, &params);
575#endif
576	} else if (code == SYS_syscall || code == SYS___syscall) {
577		code = tf->tf_out[reg++];
578		regcnt--;
579	}
580
581	if (p->p_sysent->sv_mask)
582		code &= p->p_sysent->sv_mask;
583
584	if (code >= p->p_sysent->sv_size)
585		callp = &p->p_sysent->sv_table[0];
586	else
587		callp = &p->p_sysent->sv_table[code];
588
589	narg = callp->sy_narg;
590
591	KASSERT(narg <= sizeof(args) / sizeof(args[0]),
592	    ("Too many syscall arguments!"));
593	error = 0;
594	argp = args;
595	bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt);
596	if (narg > regcnt)
597		error = copyin((void *)(tf->tf_out[6] + SPOFF +
598		    offsetof(struct frame, fr_pad[6])),
599		    &args[regcnt], (narg - regcnt) * sizeof(args[0]));
600
601	CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td,
602	    syscallnames[code], argp[0], argp[1], argp[2]);
603
604#ifdef KTRACE
605	if (KTRPOINT(td, KTR_SYSCALL))
606		ktrsyscall(code, narg, argp);
607#endif
608
609	td->td_syscalls++;
610
611	if (error == 0) {
612		td->td_retval[0] = 0;
613		td->td_retval[1] = 0;
614
615		STOPEVENT(p, S_SCE, narg);	/* MP aware */
616
617		PTRACESTOP_SC(p, td, S_PT_SCE);
618
619		AUDIT_SYSCALL_ENTER(code, td);
620		error = (*callp->sy_call)(td, argp);
621		AUDIT_SYSCALL_EXIT(error, td);
622
623		CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p,
624		    error, syscallnames[code], td->td_retval[0],
625		    td->td_retval[1]);
626	}
627
628	cpu_set_syscall_retval(td, error);
629
630	/*
631	 * Check for misbehavior.
632	 */
633	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
634	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
635	KASSERT(td->td_critnest == 0,
636	    ("System call %s returning in a critical section",
637	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
638	KASSERT(td->td_locks == 0,
639	    ("System call %s returning with %d locks held",
640	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
641	    td->td_locks));
642
643	/*
644	 * Handle reschedule and other end-of-syscall issues
645	 */
646	userret(td, tf);
647
648#ifdef KTRACE
649	if (KTRPOINT(td, KTR_SYSRET))
650		ktrsysret(code, error, td->td_retval[0]);
651#endif
652	/*
653	 * This works because errno is findable through the
654	 * register set.  If we ever support an emulation where this
655	 * is not the case, this code will need to be revisited.
656	 */
657	STOPEVENT(p, S_SCX, code);
658
659	PTRACESTOP_SC(p, td, S_PT_SCX);
660}
661