trap.c revision 84849
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 * $FreeBSD: head/sys/sparc64/sparc64/trap.c 84849 2001-10-12 16:06:41Z tmm $
41 */
42
43#include "opt_ddb.h"
44#include "opt_ktr.h"
45
46#include <sys/param.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/pioctl.h>
54#include <sys/proc.h>
55#include <sys/syscall.h>
56#include <sys/sysent.h>
57#include <sys/user.h>
58#include <sys/vmmeter.h>
59
60#include <vm/vm.h>
61#include <vm/pmap.h>
62#include <vm/vm_extern.h>
63#include <vm/vm_param.h>
64#include <vm/vm_kern.h>
65#include <vm/vm_map.h>
66#include <vm/vm_page.h>
67
68#include <machine/clock.h>
69#include <machine/frame.h>
70#include <machine/intr_machdep.h>
71#include <machine/pcb.h>
72#include <machine/pv.h>
73#include <machine/trap.h>
74#include <machine/tstate.h>
75#include <machine/tte.h>
76#include <machine/tlb.h>
77#include <machine/tsb.h>
78#include <machine/watch.h>
79
80void trap(struct trapframe *tf);
81int trap_mmu_fault(struct thread *td, struct trapframe *tf);
82void syscall(struct trapframe *tf);
83
84u_long trap_mask = 0xffffffffffffffffL & ~(1 << T_INTR);
85
86extern char fsbail[];
87
88extern char *syscallnames[];
89
90const char *trap_msg[] = {
91	"reserved",
92	"power on reset",
93	"watchdog reset",
94	"externally initiated reset",
95	"software initiated reset",
96	"red state exception",
97	"instruction access exception",
98	"instruction access error",
99	"illegal instruction",
100	"privileged opcode",
101	"floating point disabled",
102	"floating point exception ieee 754",
103	"floating point exception other",
104	"tag overflow",
105	"division by zero",
106	"data access exception",
107	"data access error",
108	"memory address not aligned",
109	"lddf memory address not aligned",
110	"stdf memory address not aligned",
111	"privileged action",
112	"interrupt vector",
113	"physical address watchpoint",
114	"virtual address watchpoint",
115	"corrected ecc error",
116	"fast instruction access mmu miss",
117	"fast data access mmu miss",
118	"fast data access protection",
119	"spill",
120	"fill",
121	"fill",
122	"breakpoint",
123	"syscall",
124	"trap instruction",
125};
126
127void
128trap(struct trapframe *tf)
129{
130	struct thread *td;
131	struct proc *p;
132	u_int sticks;
133	int error;
134	int ucode;
135	int mask;
136	int type;
137	int sig;
138
139	KASSERT(PCPU_GET(curthread) != NULL, ("trap: curthread NULL"));
140	KASSERT(PCPU_GET(curthread)->td_kse != NULL, ("trap: curkse NULL"));
141	KASSERT(PCPU_GET(curthread)->td_proc != NULL, ("trap: curproc NULL"));
142
143	atomic_add_int(&cnt.v_trap, 1);
144
145	td = PCPU_GET(curthread);
146	p = td->td_proc;
147
148	error = 0;
149	type = tf->tf_type;
150	ucode = type;	/* XXX */
151	sticks = 0;
152
153	CTR5(KTR_TRAP, "trap: %s type=%s (%s) ws=%#lx ow=%#lx",
154	    p->p_comm, trap_msg[type & ~T_KERNEL],
155	    ((type & T_KERNEL) ? "kernel" : "user"),
156	    rdpr(wstate), rdpr(otherwin));
157
158	if ((type & T_KERNEL) == 0) {
159		sticks = td->td_kse->ke_sticks;
160		td->td_frame = tf;
161	}
162
163	switch (type) {
164
165	/*
166	 * User Mode Traps
167	 */
168	case T_ALIGN:
169	case T_ALIGN_LDDF:
170	case T_ALIGN_STDF:
171		sig = SIGBUS;
172		goto trapsig;
173	case T_BREAKPOINT:
174		sig = SIGTRAP;
175		goto trapsig;
176	case T_DIVIDE:
177		sig = SIGFPE;
178		goto trapsig;
179	case T_FP_DISABLED:
180		if (fp_enable_thread(td))
181			goto user;
182		/* Fallthrough. */
183	case T_FP_IEEE:
184	case T_FP_OTHER:
185		sig = SIGFPE;
186		goto trapsig;
187	case T_DATA_ERROR:
188	case T_DATA_EXCPTN:
189	case T_INSN_ERROR:
190	case T_INSN_EXCPTN:
191		sig = SIGILL;	/* XXX */
192		goto trapsig;
193	case T_DMMU_MISS:
194	case T_DMMU_PROT:
195	case T_IMMU_MISS:
196		error = trap_mmu_fault(td, tf);
197		if (error == 0)
198			goto user;
199		sig = error;
200		goto trapsig;
201	case T_FILL:
202		if (rwindow_load(td, tf, 2)) {
203			PROC_LOCK(p);
204			sigexit(td, SIGILL);
205			/* Not reached. */
206		}
207		goto out;
208	case T_FILL_RET:
209		if (rwindow_load(td, tf, 1)) {
210			PROC_LOCK(p);
211			sigexit(td, SIGILL);
212			/* Not reached. */
213		}
214		goto out;
215	case T_INSN_ILLEGAL:
216		sig = SIGILL;
217		goto trapsig;
218	case T_PRIV_ACTION:
219	case T_PRIV_OPCODE:
220		sig = SIGBUS;
221		goto trapsig;
222	case T_SOFT:
223		sig = SIGILL;
224		goto trapsig;
225	case T_SPILL:
226		if (rwindow_save(td)) {
227			PROC_LOCK(p);
228			sigexit(td, SIGILL);
229			/* Not reached. */
230		}
231		goto out;
232	case T_TAG_OVFLW:
233		sig = SIGEMT;
234		goto trapsig;
235
236	/*
237	 * Kernel Mode Traps
238	 */
239#ifdef DDB
240	case T_BREAKPOINT | T_KERNEL:
241		if (kdb_trap(tf) != 0)
242			goto out;
243		break;
244#endif
245	case T_DMMU_MISS | T_KERNEL:
246	case T_DMMU_PROT | T_KERNEL:
247		error = trap_mmu_fault(td, tf);
248		if (error == 0)
249			goto out;
250		break;
251	case T_WATCH_VIRT | T_KERNEL:
252		/*
253		 * At the moment, just print the information from the trap,
254		 * remove the watchpoint, use evil magic to execute the
255		 * instruction (we temporarily save the instruction at
256		 * %tnpc, write a trap instruction, resume, and reset the
257		 * watch point when the trap arrives).
258		 * To make sure that no interrupt gets in between and creates
259		 * a potentially large window where the watchpoint is inactive,
260		 * disable interrupts temporarily.
261		 * This is obviously fragile and evilish.
262		 */
263		printf("Virtual watchpoint triggered, tpc=0x%lx, tnpc=0x%lx\n",
264		    tf->tf_tpc, tf->tf_tnpc);
265		PCPU_SET(wp_pstate, (tf->tf_tstate & TSTATE_PSTATE_MASK) >>
266		    TSTATE_PSTATE_SHIFT);
267		tf->tf_tstate &= ~TSTATE_IE;
268		wrpr(pstate, rdpr(pstate), PSTATE_IE);
269		PCPU_SET(wp_insn, *((u_int *)tf->tf_tnpc));
270		*((u_int *)tf->tf_tnpc) = 0x91d03002;	/* ta %xcc, 2 */
271		flush(tf->tf_tnpc);
272		PCPU_SET(wp_va, watch_virt_get(&mask));
273		PCPU_SET(wp_mask, mask);
274		watch_virt_clear();
275		goto out;
276	case T_RESTOREWP | T_KERNEL:
277		/*
278		 * Undo the tweaks tone for T_WATCH, reset the watch point and
279		 * contunue execution.
280		 * Note that here, we run with interrupts enabled, so there
281		 * is a small chance that we will be interrupted before we
282		 * could reset the watch point.
283		 */
284		tf->tf_tstate = (tf->tf_tstate & ~TSTATE_PSTATE_MASK) |
285		    PCPU_GET(wp_pstate) << TSTATE_PSTATE_SHIFT;
286		watch_virt_set_mask(PCPU_GET(wp_va), PCPU_GET(wp_mask));
287		*(u_int *)tf->tf_tpc = PCPU_GET(wp_insn);
288		flush(tf->tf_tpc);
289		goto out;
290	default:
291		break;
292	}
293	panic("trap: %s", trap_msg[type & ~T_KERNEL]);
294
295trapsig:
296	/* Translate fault for emulators. */
297	if (p->p_sysent->sv_transtrap != NULL)
298		sig = (p->p_sysent->sv_transtrap)(sig, type);
299	trapsignal(p, sig, ucode);
300user:
301	userret(td, tf, sticks);
302out:
303	CTR1(KTR_TRAP, "trap: td=%p return", td);
304	return;
305}
306
307int
308trap_mmu_fault(struct thread *td, struct trapframe *tf)
309{
310	struct mmuframe *mf;
311	struct vmspace *vm;
312	struct stte *stp;
313	struct pcb *pcb;
314	struct tte tte;
315	struct proc *p;
316	vm_offset_t va;
317	vm_prot_t prot;
318	u_long ctx;
319	pmap_t pm;
320	int flags;
321	int type;
322	int rv;
323
324	p = td->td_proc;
325	KASSERT(td->td_pcb != NULL, ("trap_dmmu_miss: pcb NULL"));
326	KASSERT(p->p_vmspace != NULL, ("trap_dmmu_miss: vmspace NULL"));
327
328	rv = KERN_SUCCESS;
329	mf = (struct mmuframe *)tf->tf_arg;
330	ctx = TLB_TAR_CTX(mf->mf_tar);
331	pcb = td->td_pcb;
332	type = tf->tf_type & ~T_KERNEL;
333	va = TLB_TAR_VA(mf->mf_tar);
334	stp = NULL;
335
336	CTR4(KTR_TRAP, "trap_mmu_fault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
337	    td, p->p_vmspace->vm_pmap.pm_context, va, ctx);
338
339	if (type == T_DMMU_PROT) {
340		prot = VM_PROT_WRITE;
341		flags = VM_FAULT_DIRTY;
342	} else {
343		if (type == T_DMMU_MISS)
344			prot = VM_PROT_READ;
345		else
346			prot = VM_PROT_READ | VM_PROT_EXECUTE;
347		flags = VM_FAULT_NORMAL;
348	}
349
350	if (ctx == TLB_CTX_KERNEL) {
351		mtx_lock(&Giant);
352		rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
353		mtx_unlock(&Giant);
354		if (rv == KERN_SUCCESS) {
355			stp = tsb_kvtostte(va);
356			tte = stp->st_tte;
357			if (type == T_IMMU_MISS)
358				tlb_store(TLB_DTLB | TLB_ITLB, va, ctx, tte);
359			else
360				tlb_store(TLB_DTLB, va, ctx, tte);
361		}
362	} else if (tf->tf_type & T_KERNEL &&
363	    (td->td_intr_nesting_level != 0 || pcb->pcb_onfault == NULL ||
364	    pcb->pcb_onfault == fsbail)) {
365		rv = KERN_FAILURE;
366	} else {
367		mtx_lock(&Giant);
368		vm = p->p_vmspace;
369		pm = &vm->vm_pmap;
370		stp = tsb_stte_lookup(pm, va);
371		if (stp == NULL || type == T_DMMU_PROT) {
372			/*
373			 * Keep the process from being swapped out at this
374			 * critical time.
375			 */
376			PROC_LOCK(p);
377			++p->p_lock;
378			PROC_UNLOCK(p);
379
380			/*
381			 * Grow the stack if necessary.  vm_map_growstack only
382			 * fails if the va falls into a growable stack region
383			 * and the stack growth fails.  If it succeeds, or the
384			 * va was not within a growable stack region, fault in
385			 * the user page.
386			 */
387			if (vm_map_growstack(p, va) != KERN_SUCCESS)
388				rv = KERN_FAILURE;
389			else
390				rv = vm_fault(&vm->vm_map, va, prot, flags);
391
392			/*
393			 * Now the process can be swapped again.
394			 */
395			PROC_LOCK(p);
396			--p->p_lock;
397			PROC_UNLOCK(p);
398		} else {
399			stp = tsb_stte_promote(pm, va, stp);
400			stp->st_tte.tte_data |= TD_REF;
401			switch (type) {
402			case T_IMMU_MISS:
403				if ((stp->st_tte.tte_data & TD_EXEC) == 0) {
404					rv = KERN_FAILURE;
405					break;
406				}
407				tlb_store(TLB_DTLB | TLB_ITLB, va, ctx,
408				    stp->st_tte);
409				break;
410			case T_DMMU_PROT:
411				if ((stp->st_tte.tte_data & TD_SW) == 0) {
412					rv = KERN_FAILURE;
413					break;
414				}
415				/* Fallthrough. */
416			case T_DMMU_MISS:
417				tlb_store(TLB_DTLB, va, ctx, stp->st_tte);
418				break;
419			}
420		}
421		mtx_unlock(&Giant);
422	}
423	CTR3(KTR_TRAP, "trap_mmu_fault: return p=%p va=%#lx rv=%d", p, va, rv);
424	if (rv == KERN_SUCCESS)
425		return (0);
426	if (tf->tf_type & T_KERNEL) {
427		if (pcb->pcb_onfault != NULL && ctx != TLB_CTX_KERNEL) {
428			tf->tf_tpc = (u_long)pcb->pcb_onfault;
429			tf->tf_tnpc = tf->tf_tpc + 4;
430			return (0);
431		}
432	}
433	return (rv == KERN_PROTECTION_FAILURE ? SIGBUS : SIGSEGV);
434}
435
436/* Maximum number of arguments that can be passed via the out registers. */
437#define	REG_MAXARGS	6
438
439/*
440 * Syscall handler. The arguments to the syscall are passed in the o registers
441 * by the caller, and are saved in the trap frame. The syscall number is passed
442 * in %g1 (and also saved in the trap frame).
443 */
444void
445syscall(struct trapframe *tf)
446{
447	struct sysent *callp;
448	struct thread *td;
449	register_t args[8];
450	register_t *argp;
451	struct proc *p;
452	u_int sticks;
453	u_long code;
454	u_long tpc;
455	int reg;
456	int regcnt;
457	int narg;
458	int error;
459
460	KASSERT(PCPU_GET(curthread) != NULL, ("trap: curthread NULL"));
461	KASSERT(PCPU_GET(curthread)->td_kse != NULL, ("trap: curkse NULL"));
462	KASSERT(PCPU_GET(curthread)->td_proc != NULL, ("trap: curproc NULL"));
463
464	atomic_add_int(&cnt.v_syscall, 1);
465
466	td = PCPU_GET(curthread);
467	p = td->td_proc;
468
469	narg = 0;
470	error = 0;
471	reg = 0;
472	regcnt = REG_MAXARGS;
473
474	sticks = td->td_kse->ke_sticks;
475	td->td_frame = tf;
476	code = tf->tf_global[1];
477
478	/*
479	 * For syscalls, we don't want to retry the faulting instruction
480	 * (usually), instead we need to advance one instruction.
481	 */
482	tpc = tf->tf_tpc;
483	tf->tf_tpc = tf->tf_tnpc;
484	tf->tf_tnpc += 4;
485
486	if (p->p_sysent->sv_prepsyscall) {
487		/*
488		 * The prep code is MP aware.
489		 */
490#if 0
491		(*p->p_sysent->sv_prepsyscall)(tf, args, &code, &params);
492#endif
493	} else 	if (code == SYS_syscall || code == SYS___syscall) {
494		code = tf->tf_out[reg++];
495		regcnt--;
496	}
497
498 	if (p->p_sysent->sv_mask)
499 		code &= p->p_sysent->sv_mask;
500
501 	if (code >= p->p_sysent->sv_size)
502 		callp = &p->p_sysent->sv_table[0];
503  	else
504 		callp = &p->p_sysent->sv_table[code];
505
506	narg = callp->sy_narg & SYF_ARGMASK;
507
508	if (narg <= regcnt)
509		argp = &tf->tf_out[reg];
510	else {
511		KASSERT(narg <= sizeof(args) / sizeof(args[0]),
512		    ("Too many syscall arguments!"));
513		argp = args;
514		bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt);
515		error = copyin((void *)(tf->tf_out[6] + SPOFF +
516		    offsetof(struct frame, f_pad[6])),
517		    &args[reg + regcnt], (narg - regcnt) * sizeof(args[0]));
518		if (error != 0)
519			goto bad;
520	}
521
522	CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td,
523	    syscallnames[code], argp[0], argp[1], argp[2]);
524
525	/*
526	 * Try to run the syscall without the MP lock if the syscall
527	 * is MP safe.
528	 */
529	if ((callp->sy_narg & SYF_MPSAFE) == 0)
530		mtx_lock(&Giant);
531
532#ifdef KTRACE
533	/*
534	 * We have to obtain the MP lock no matter what if
535	 * we are ktracing
536	 */
537	if (KTRPOINT(p, KTR_SYSCALL)) {
538		ktrsyscall(p->p_tracep, code, narg, args);
539	}
540#endif
541	td->td_retval[0] = 0;
542	td->td_retval[1] = tf->tf_out[1];
543
544	STOPEVENT(p, S_SCE, narg);	/* MP aware */
545
546	error = (*callp->sy_call)(td, argp);
547
548	CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p,
549	    error, syscallnames[code], td->td_retval[0], td->td_retval[1]);
550
551	/*
552	 * MP SAFE (we may or may not have the MP lock at this point)
553	 */
554	switch (error) {
555	case 0:
556		tf->tf_out[0] = td->td_retval[0];
557		tf->tf_out[1] = td->td_retval[1];
558		tf->tf_tstate &= ~TSTATE_XCC_C;
559		break;
560
561	case ERESTART:
562		/*
563		 * Undo the tpc advancement we have done above, we want to
564		 * reexecute the system call.
565		 */
566		tf->tf_tpc = tpc;
567		tf->tf_tnpc -= 4;
568		break;
569
570	case EJUSTRETURN:
571		break;
572
573	default:
574bad:
575 		if (p->p_sysent->sv_errsize) {
576 			if (error >= p->p_sysent->sv_errsize)
577  				error = -1;	/* XXX */
578   			else
579  				error = p->p_sysent->sv_errtbl[error];
580		}
581		tf->tf_out[0] = error;
582		tf->tf_tstate |= TSTATE_XCC_C;
583		break;
584	}
585
586	/*
587	 * Handle reschedule and other end-of-syscall issues
588	 */
589	userret(td, tf, sticks);
590
591#ifdef KTRACE
592	if (KTRPOINT(p, KTR_SYSRET)) {
593		ktrsysret(p->p_tracep, code, error, td->td_retval[0]);
594	}
595#endif
596
597	/*
598	 * Release Giant if we had to get it.  Don't use mtx_owned(),
599	 * we want to catch broken syscalls.
600	 */
601	if ((callp->sy_narg & SYF_MPSAFE) == 0)
602		mtx_unlock(&Giant);
603
604	/*
605	 * This works because errno is findable through the
606	 * register set.  If we ever support an emulation where this
607	 * is not the case, this code will need to be revisited.
608	 */
609	STOPEVENT(p, S_SCX, code);
610
611#ifdef WITNESS
612	if (witness_list(td)) {
613		panic("system call %s returning with mutex(s) held\n",
614		    syscallnames[code]);
615	}
616#endif
617	mtx_assert(&sched_lock, MA_NOTOWNED);
618	mtx_assert(&Giant, MA_NOTOWNED);
619}
620