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