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