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/5.2/sys/sparc64/sparc64/trap.c 122464 2003-11-11 06:41:54Z jake $
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/kernel.h>
49 #include <sys/bus.h>
50 #include <sys/interrupt.h>
51 #include <sys/ktr.h>
52 #include <sys/lock.h>
53 #include <sys/mutex.h>
54 #include <sys/systm.h>
55 #include <sys/pioctl.h>
56 #include <sys/ptrace.h>
57 #include <sys/proc.h>
58 #include <sys/smp.h>
59 #include <sys/signalvar.h>
60 #include <sys/syscall.h>
61 #include <sys/sysctl.h>
62 #include <sys/sysent.h>
63 #include <sys/user.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 atomic_add_int(&cnt.v_trap, 1);
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 Debugger("trapsig");
287 trapsignal(td, sig, tf->tf_type);
288 }
289
290 userret(td, tf, sticks);
291 mtx_assert(&Giant, MA_NOTOWNED);
292 #ifdef DIAGNOSTIC
293 cred_free_thread(td);
294 #endif
295 } else {
296 KASSERT((tf->tf_type & T_KERNEL) != 0,
297 ("trap: kernel trap isn't"));
298
299 switch (tf->tf_type & ~T_KERNEL) {
300 #ifdef DDB
301 case T_BREAKPOINT:
302 case T_KSTACK_FAULT:
303 error = (kdb_trap(tf) == 0);
304 break;
305 #ifdef notyet
306 case T_PA_WATCHPOINT:
307 case T_VA_WATCHPOINT:
308 error = db_watch_trap(tf);
309 break;
310 #endif
311 #endif
312 case T_DATA_MISS:
313 case T_DATA_PROTECTION:
314 case T_INSTRUCTION_MISS:
315 error = trap_pfault(td, tf);
316 break;
317 case T_DATA_EXCEPTION:
318 case T_MEM_ADDRESS_NOT_ALIGNED:
319 if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
320 MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
321 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
322 tf->tf_tpc <= (u_long)copy_nofault_end) {
323 tf->tf_tpc = (u_long)copy_fault;
324 tf->tf_tnpc = tf->tf_tpc + 4;
325 error = 0;
326 break;
327 }
328 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
329 tf->tf_tpc <= (u_long)fs_nofault_end) {
330 tf->tf_tpc = (u_long)fs_fault;
331 tf->tf_tnpc = tf->tf_tpc + 4;
332 error = 0;
333 break;
334 }
335 }
336 error = 1;
337 break;
338 case T_DATA_ERROR:
339 /*
340 * handle PCI poke/peek as per UltraSPARC IIi
341 * User's Manual 16.2.1.
342 */
343 #define MEMBARSYNC_INST ((u_int32_t)0x8143e040)
344 if (tf->tf_tpc > (u_long)fas_nofault_begin &&
345 tf->tf_tpc < (u_long)fas_nofault_end &&
346 *(u_int32_t *)tf->tf_tpc == MEMBARSYNC_INST &&
347 ((u_int32_t *)tf->tf_tpc)[-2] == MEMBARSYNC_INST) {
348 cache_flush();
349 cache_enable();
350 tf->tf_tpc = (u_long)fas_fault;
351 tf->tf_tnpc = tf->tf_tpc + 4;
352 error = 0;
353 break;
354 }
355 #undef MEMBARSYNC_INST
356 error = 1;
357 break;
358 default:
359 error = 1;
360 break;
361 }
362
363 if (error != 0)
364 panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]);
365 }
366 CTR1(KTR_TRAP, "trap: td=%p return", td);
367 }
368
369 static int
370 trap_pfault(struct thread *td, struct trapframe *tf)
371 {
372 struct vmspace *vm;
373 struct pcb *pcb;
374 struct proc *p;
375 vm_offset_t va;
376 vm_prot_t prot;
377 u_long ctx;
378 int flags;
379 int type;
380 int rv;
381
382 if (td == NULL)
383 return (-1);
384 KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
385 KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
386 KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
387
388 p = td->td_proc;
389
390 rv = KERN_SUCCESS;
391 ctx = TLB_TAR_CTX(tf->tf_tar);
392 pcb = td->td_pcb;
393 type = tf->tf_type & ~T_KERNEL;
394 va = TLB_TAR_VA(tf->tf_tar);
395
396 CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
397 td, p->p_vmspace->vm_pmap.pm_context[PCPU_GET(cpuid)], va, ctx);
398
399 if (type == T_DATA_PROTECTION) {
400 prot = VM_PROT_WRITE;
401 flags = VM_FAULT_DIRTY;
402 } else {
403 if (type == T_DATA_MISS)
404 prot = VM_PROT_READ;
405 else
406 prot = VM_PROT_READ | VM_PROT_EXECUTE;
407 flags = VM_FAULT_NORMAL;
408 }
409
410 if (ctx != TLB_CTX_KERNEL) {
411 if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
412 (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
413 tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
414 tf->tf_tpc = (u_long)fs_fault;
415 tf->tf_tnpc = tf->tf_tpc + 4;
416 return (0);
417 }
418
419 /*
420 * This is a fault on non-kernel virtual memory.
421 */
422 vm = p->p_vmspace;
423
424 /*
425 * Keep swapout from messing with us during this
426 * critical time.
427 */
428 PROC_LOCK(p);
429 ++p->p_lock;
430 PROC_UNLOCK(p);
431
432 /* Fault in the user page. */
433 rv = vm_fault(&vm->vm_map, va, prot, flags);
434
435 /*
436 * Now the process can be swapped again.
437 */
438 PROC_LOCK(p);
439 --p->p_lock;
440 PROC_UNLOCK(p);
441 } else {
442 /*
443 * This is a fault on kernel virtual memory. Attempts to
444 * access kernel memory from user mode cause privileged
445 * action traps, not page fault.
446 */
447 KASSERT(tf->tf_tstate & TSTATE_PRIV,
448 ("trap_pfault: fault on nucleus context from user mode"));
449
450 /*
451 * Don't have to worry about process locking or stacks in the
452 * kernel.
453 */
454 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
455 }
456
457 CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
458 td, va, rv);
459 if (rv == KERN_SUCCESS)
460 return (0);
461 if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
462 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
463 tf->tf_tpc <= (u_long)fs_nofault_end) {
464 tf->tf_tpc = (u_long)fs_fault;
465 tf->tf_tnpc = tf->tf_tpc + 4;
466 return (0);
467 }
468 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
469 tf->tf_tpc <= (u_long)copy_nofault_end) {
470 tf->tf_tpc = (u_long)copy_fault;
471 tf->tf_tnpc = tf->tf_tpc + 4;
472 return (0);
473 }
474 }
475 return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
476 }
477
478 /* Maximum number of arguments that can be passed via the out registers. */
479 #define REG_MAXARGS 6
480
481 /*
482 * Syscall handler. The arguments to the syscall are passed in the o registers
483 * by the caller, and are saved in the trap frame. The syscall number is passed
484 * in %g1 (and also saved in the trap frame).
485 */
486 void
487 syscall(struct trapframe *tf)
488 {
489 struct sysent *callp;
490 struct thread *td;
491 register_t args[8];
492 register_t *argp;
493 struct proc *p;
494 u_int sticks;
495 u_long code;
496 u_long tpc;
497 int reg;
498 int regcnt;
499 int narg;
500 int error;
501
502 td = PCPU_GET(curthread);
503 KASSERT(td != NULL, ("trap: curthread NULL"));
504 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
505
506 p = td->td_proc;
507
508 atomic_add_int(&cnt.v_syscall, 1);
509
510 narg = 0;
511 error = 0;
512 reg = 0;
513 regcnt = REG_MAXARGS;
514
515 sticks = td->td_sticks;
516 td->td_frame = tf;
517 if (td->td_ucred != p->p_ucred)
518 cred_update_thread(td);
519 if (p->p_flag & P_SA)
520 thread_user_enter(p, td);
521 code = tf->tf_global[1];
522
523 /*
524 * For syscalls, we don't want to retry the faulting instruction
525 * (usually), instead we need to advance one instruction.
526 */
527 tpc = tf->tf_tpc;
528 TF_DONE(tf);
529
530 if (p->p_sysent->sv_prepsyscall) {
531 /*
532 * The prep code is MP aware.
533 */
534 #if 0
535 (*p->p_sysent->sv_prepsyscall)(tf, args, &code, ¶ms);
536 #endif
537 } else if (code == SYS_syscall || code == SYS___syscall) {
538 code = tf->tf_out[reg++];
539 regcnt--;
540 }
541
542 if (p->p_sysent->sv_mask)
543 code &= p->p_sysent->sv_mask;
544
545 if (code >= p->p_sysent->sv_size)
546 callp = &p->p_sysent->sv_table[0];
547 else
548 callp = &p->p_sysent->sv_table[code];
549
550 narg = callp->sy_narg & SYF_ARGMASK;
551
552 if (narg <= regcnt) {
553 argp = &tf->tf_out[reg];
554 error = 0;
555 } else {
556 KASSERT(narg <= sizeof(args) / sizeof(args[0]),
557 ("Too many syscall arguments!"));
558 argp = args;
559 bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt);
560 error = copyin((void *)(tf->tf_out[6] + SPOFF +
561 offsetof(struct frame, fr_pad[6])),
562 &args[regcnt], (narg - regcnt) * sizeof(args[0]));
563 }
564
565 CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td,
566 syscallnames[code], argp[0], argp[1], argp[2]);
567
568 /*
569 * Try to run the syscall without the MP lock if the syscall
570 * is MP safe.
571 */
572 if ((callp->sy_narg & SYF_MPSAFE) == 0)
573 mtx_lock(&Giant);
574
575 #ifdef KTRACE
576 if (KTRPOINT(td, KTR_SYSCALL))
577 ktrsyscall(code, narg, argp);
578 #endif
579 if (error == 0) {
580 td->td_retval[0] = 0;
581 td->td_retval[1] = 0;
582
583 STOPEVENT(p, S_SCE, narg); /* MP aware */
584
585 PTRACESTOP_SC(p, td, S_PT_SCE);
586
587 error = (*callp->sy_call)(td, argp);
588
589 CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p,
590 error, syscallnames[code], td->td_retval[0],
591 td->td_retval[1]);
592 }
593
594 /*
595 * MP SAFE (we may or may not have the MP lock at this point)
596 */
597 switch (error) {
598 case 0:
599 tf->tf_out[0] = td->td_retval[0];
600 tf->tf_out[1] = td->td_retval[1];
601 tf->tf_tstate &= ~TSTATE_XCC_C;
602 break;
603
604 case ERESTART:
605 /*
606 * Undo the tpc advancement we have done above, we want to
607 * reexecute the system call.
608 */
609 tf->tf_tpc = tpc;
610 tf->tf_tnpc -= 4;
611 break;
612
613 case EJUSTRETURN:
614 break;
615
616 default:
617 if (p->p_sysent->sv_errsize) {
618 if (error >= p->p_sysent->sv_errsize)
619 error = -1; /* XXX */
620 else
621 error = p->p_sysent->sv_errtbl[error];
622 }
623 tf->tf_out[0] = error;
624 tf->tf_tstate |= TSTATE_XCC_C;
625 break;
626 }
627
628 /*
629 * Release Giant if we had to get it. Don't use mtx_owned(),
630 * we want to catch broken syscalls.
631 */
632 if ((callp->sy_narg & SYF_MPSAFE) == 0)
633 mtx_unlock(&Giant);
634
635 /*
636 * Handle reschedule and other end-of-syscall issues
637 */
638 userret(td, tf, sticks);
639
640 #ifdef KTRACE
641 if (KTRPOINT(td, KTR_SYSRET))
642 ktrsysret(code, error, td->td_retval[0]);
643 #endif
644 /*
645 * This works because errno is findable through the
646 * register set. If we ever support an emulation where this
647 * is not the case, this code will need to be revisited.
648 */
649 STOPEVENT(p, S_SCX, code);
650
651 PTRACESTOP_SC(p, td, S_PT_SCX);
652
653 #ifdef DIAGNOSTIC
654 cred_free_thread(td);
655 #endif
656 WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
657 (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
658 mtx_assert(&sched_lock, MA_NOTOWNED);
659 mtx_assert(&Giant, MA_NOTOWNED);
660 }
Cache object: 2f3433b5bf637c579a5c0b584ebed43d
|