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