rename amd64 architecture to x86_64
[dragonfly.git] / sys / platform / pc64 / x86_64 / trap.c
1 /*-
2  * Copyright (c) 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (C) 1994, David Greenman
5  * Copyright (c) 2008 The DragonFly Project.
6  * Copyright (c) 2008 Jordan Gordeev.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the University of Utah, and William Jolitz.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *      This product includes software developed by the University of
22  *      California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * from: @(#)trap.c     7.4 (Berkeley) 5/13/91
40  * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $
41  */
42
43 /*
44  * x86_64 Trap and System call handling
45  */
46
47 #include "opt_ddb.h"
48 #include "opt_ktrace.h"
49
50 #include <machine/frame.h>
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/proc.h>
55 #include <sys/pioctl.h>
56 #include <sys/types.h>
57 #include <sys/signal2.h>
58 #include <sys/syscall.h>
59 #include <sys/sysctl.h>
60 #include <sys/sysent.h>
61 #include <sys/systm.h>
62 #ifdef KTRACE
63 #include <sys/ktrace.h>
64 #endif
65 #include <sys/ktr.h>
66 #include <sys/sysmsg.h>
67 #include <sys/sysproto.h>
68 #include <sys/sysunion.h>
69
70 #include <vm/pmap.h>
71 #include <vm/vm.h>
72 #include <vm/vm_extern.h>
73 #include <vm/vm_kern.h>
74 #include <vm/vm_param.h>
75 #include <machine/cpu.h>
76 #include <machine/pcb.h>
77 #include <machine/smp.h>
78 #include <machine/thread.h>
79 #include <machine/vmparam.h>
80 #include <machine/md_var.h>
81 #include <machine_base/isa/intr_machdep.h>
82
83 #include <ddb/ddb.h>
84 #include <sys/thread2.h>
85
86 #ifdef SMP
87
88 #define MAKEMPSAFE(have_mplock)                 \
89         if (have_mplock == 0) {                 \
90                 get_mplock();                   \
91                 have_mplock = 1;                \
92         }
93
94 #else
95
96 #define MAKEMPSAFE(have_mplock)
97
98 #endif
99
100 extern void trap(struct trapframe *frame);
101
102 static int trap_pfault(struct trapframe *, int);
103 static void trap_fatal(struct trapframe *, vm_offset_t);
104 void dblfault_handler(struct trapframe *frame);
105
106 #define MAX_TRAP_MSG            30
107 static char *trap_msg[] = {
108         "",                                     /*  0 unused */
109         "privileged instruction fault",         /*  1 T_PRIVINFLT */
110         "",                                     /*  2 unused */
111         "breakpoint instruction fault",         /*  3 T_BPTFLT */
112         "",                                     /*  4 unused */
113         "",                                     /*  5 unused */
114         "arithmetic trap",                      /*  6 T_ARITHTRAP */
115         "system forced exception",              /*  7 T_ASTFLT */
116         "",                                     /*  8 unused */
117         "general protection fault",             /*  9 T_PROTFLT */
118         "trace trap",                           /* 10 T_TRCTRAP */
119         "",                                     /* 11 unused */
120         "page fault",                           /* 12 T_PAGEFLT */
121         "",                                     /* 13 unused */
122         "alignment fault",                      /* 14 T_ALIGNFLT */
123         "",                                     /* 15 unused */
124         "",                                     /* 16 unused */
125         "",                                     /* 17 unused */
126         "integer divide fault",                 /* 18 T_DIVIDE */
127         "non-maskable interrupt trap",          /* 19 T_NMI */
128         "overflow trap",                        /* 20 T_OFLOW */
129         "FPU bounds check fault",               /* 21 T_BOUND */
130         "FPU device not available",             /* 22 T_DNA */
131         "double fault",                         /* 23 T_DOUBLEFLT */
132         "FPU operand fetch fault",              /* 24 T_FPOPFLT */
133         "invalid TSS fault",                    /* 25 T_TSSFLT */
134         "segment not present fault",            /* 26 T_SEGNPFLT */
135         "stack fault",                          /* 27 T_STKFLT */
136         "machine check trap",                   /* 28 T_MCHK */
137         "SIMD floating-point exception",        /* 29 T_XMMFLT */
138         "reserved (unknown) fault",             /* 30 T_RESERVED */
139 };
140
141 #ifdef DDB
142 static int ddb_on_nmi = 1;
143 SYSCTL_INT(_machdep, OID_AUTO, ddb_on_nmi, CTLFLAG_RW,
144         &ddb_on_nmi, 0, "Go to DDB on NMI");
145 #endif
146 static int panic_on_nmi = 1;
147 SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
148         &panic_on_nmi, 0, "Panic on NMI");
149 static int fast_release;
150 SYSCTL_INT(_machdep, OID_AUTO, fast_release, CTLFLAG_RW,
151         &fast_release, 0, "Passive Release was optimal");
152 static int slow_release;
153 SYSCTL_INT(_machdep, OID_AUTO, slow_release, CTLFLAG_RW,
154         &slow_release, 0, "Passive Release was nonoptimal");
155 #ifdef SMP
156 static int syscall_mpsafe = 1;
157 SYSCTL_INT(_kern, OID_AUTO, syscall_mpsafe, CTLFLAG_RW,
158         &syscall_mpsafe, 0, "Allow MPSAFE marked syscalls to run without BGL");
159 TUNABLE_INT("kern.syscall_mpsafe", &syscall_mpsafe);
160 static int trap_mpsafe = 1;
161 SYSCTL_INT(_kern, OID_AUTO, trap_mpsafe, CTLFLAG_RW,
162         &trap_mpsafe, 0, "Allow traps to mostly run without the BGL");
163 TUNABLE_INT("kern.trap_mpsafe", &trap_mpsafe);
164 #endif
165
166 /*
167  * userenter() passively intercepts the thread switch function to increase
168  * the thread priority from a user priority to a kernel priority, reducing
169  * syscall and trap overhead for the case where no switch occurs.
170  */
171
172 static __inline void
173 userenter(struct thread *curtd)
174 {
175         curtd->td_release = lwkt_passive_release;
176 }
177
178 /*
179  * Handle signals, upcalls, profiling, and other AST's and/or tasks that
180  * must be completed before we can return to or try to return to userland.
181  *
182  * Note that td_sticks is a 64 bit quantity, but there's no point doing 64
183  * arithmatic on the delta calculation so the absolute tick values are
184  * truncated to an integer.
185  */
186 static void
187 userret(struct lwp *lp, struct trapframe *frame, int sticks)
188 {
189         struct proc *p = lp->lwp_proc;
190         int sig;
191
192         /*
193          * Charge system time if profiling.  Note: times are in microseconds.
194          * This may do a copyout and block, so do it first even though it
195          * means some system time will be charged as user time.
196          */
197         if (p->p_flag & P_PROFIL) {
198                 addupc_task(p, frame->tf_rip, 
199                         (u_int)((int)lp->lwp_thread->td_sticks - sticks));
200         }
201
202 recheck:
203         /*
204          * If the jungle wants us dead, so be it.
205          */
206         if (lp->lwp_flag & LWP_WEXIT) {
207                 get_mplock();
208                 lwp_exit(0);
209                 rel_mplock(); /* NOT REACHED */
210         }
211
212         /*
213          * Block here if we are in a stopped state.
214          */
215         if (p->p_stat == SSTOP) {
216                 get_mplock();
217                 tstop();
218                 rel_mplock();
219                 goto recheck;
220         }
221
222         /*
223          * Post any pending upcalls.  If running a virtual kernel be sure
224          * to restore the virtual kernel's vmspace before posting the upcall.
225          */
226         if (p->p_flag & P_UPCALLPEND) {
227                 p->p_flag &= ~P_UPCALLPEND;
228                 get_mplock();
229                 postupcall(lp);
230                 rel_mplock();
231                 goto recheck;
232         }
233
234         /*
235          * Post any pending signals.  If running a virtual kernel be sure
236          * to restore the virtual kernel's vmspace before posting the signal.
237          */
238         if ((sig = CURSIG_TRACE(lp)) != 0) {
239                 get_mplock();
240                 postsig(sig);
241                 rel_mplock();
242                 goto recheck;
243         }
244
245         /*
246          * block here if we are swapped out, but still process signals
247          * (such as SIGKILL).  proc0 (the swapin scheduler) is already
248          * aware of our situation, we do not have to wake it up.
249          */
250         if (p->p_flag & P_SWAPPEDOUT) {
251                 get_mplock();
252                 p->p_flag |= P_SWAPWAIT;
253                 swapin_request();
254                 if (p->p_flag & P_SWAPWAIT)
255                         tsleep(p, PCATCH, "SWOUT", 0);
256                 p->p_flag &= ~P_SWAPWAIT;
257                 rel_mplock();
258                 goto recheck;
259         }
260
261         /*
262          * Make sure postsig() handled request to restore old signal mask after
263          * running signal handler.
264          */
265         KKASSERT((lp->lwp_flag & LWP_OLDMASK) == 0);
266 }
267
268 /*
269  * Cleanup from userenter and any passive release that might have occured.
270  * We must reclaim the current-process designation before we can return
271  * to usermode.  We also handle both LWKT and USER reschedule requests.
272  */
273 static __inline void
274 userexit(struct lwp *lp)
275 {
276         struct thread *td = lp->lwp_thread;
277 /*      globaldata_t gd = td->td_gd;*/
278
279         /*
280          * Handle stop requests at kernel priority.  Any requests queued
281          * after this loop will generate another AST.
282          */
283         while (lp->lwp_proc->p_stat == SSTOP) {
284                 get_mplock();
285                 tstop();
286                 rel_mplock();
287         }
288
289         /*
290          * Reduce our priority in preparation for a return to userland.  If
291          * our passive release function was still in place, our priority was
292          * never raised and does not need to be reduced.
293          */
294         lwkt_passive_recover(td);
295
296         /*
297          * Become the current user scheduled process if we aren't already,
298          * and deal with reschedule requests and other factors.
299          */
300         lp->lwp_proc->p_usched->acquire_curproc(lp);
301         /* WARNING: we may have migrated cpu's */
302         /* gd = td->td_gd; */
303 }
304
305 #if !defined(KTR_KERNENTRY)
306 #define KTR_KERNENTRY   KTR_ALL
307 #endif
308 KTR_INFO_MASTER(kernentry);
309 KTR_INFO(KTR_KERNENTRY, kernentry, trap, 0, "STR",
310          sizeof(long) + sizeof(long) + sizeof(long) + sizeof(vm_offset_t));
311 KTR_INFO(KTR_KERNENTRY, kernentry, trap_ret, 0, "STR",
312          sizeof(long) + sizeof(long));
313 KTR_INFO(KTR_KERNENTRY, kernentry, syscall, 0, "STR",
314          sizeof(long) + sizeof(long) + sizeof(long));
315 KTR_INFO(KTR_KERNENTRY, kernentry, syscall_ret, 0, "STR",
316          sizeof(long) + sizeof(long) + sizeof(long));
317 KTR_INFO(KTR_KERNENTRY, kernentry, fork_ret, 0, "STR",
318          sizeof(long) + sizeof(long));
319
320 /*
321  * Exception, fault, and trap interface to the kernel.
322  * This common code is called from assembly language IDT gate entry
323  * routines that prepare a suitable stack frame, and restore this
324  * frame after the exception has been processed.
325  *
326  * This function is also called from doreti in an interlock to handle ASTs.
327  * For example:  hardwareint->INTROUTINE->(set ast)->doreti->trap
328  *
329  * NOTE!  We have to retrieve the fault address prior to obtaining the
330  * MP lock because get_mplock() may switch out.  YYY cr2 really ought
331  * to be retrieved by the assembly code, not here.
332  *
333  * XXX gd_trap_nesting_level currently prevents lwkt_switch() from panicing
334  * if an attempt is made to switch from a fast interrupt or IPI.  This is
335  * necessary to properly take fatal kernel traps on SMP machines if 
336  * get_mplock() has to block.
337  */
338
339 void
340 trap(struct trapframe *frame)
341 {
342         struct globaldata *gd = mycpu;
343         struct thread *td = gd->gd_curthread;
344         struct lwp *lp = td->td_lwp;
345         struct proc *p;
346         int sticks = 0;
347         int i = 0, ucode = 0, type, code;
348 #ifdef SMP
349         int have_mplock = 0;
350 #endif
351 #ifdef INVARIANTS
352         int crit_count = td->td_pri & ~TDPRI_MASK;
353 #endif
354         vm_offset_t eva;
355
356         p = td->td_proc;
357
358 #ifdef JG
359         kprintf0("TRAP ");
360         kprintf0("\"%s\" type=%ld\n",
361                 trap_msg[frame->tf_trapno], frame->tf_trapno);
362         kprintf0(" rip=%lx rsp=%lx\n", frame->tf_rip, frame->tf_rsp);
363         kprintf0(" err=%lx addr=%lx\n", frame->tf_err, frame->tf_addr);
364         kprintf0(" cs=%lx ss=%lx rflags=%lx\n", (unsigned long)frame->tf_cs, (unsigned long)frame->tf_ss, frame->tf_rflags);
365 #endif
366
367 #ifdef DDB
368         if (db_active) {
369                 ++gd->gd_trap_nesting_level;
370                 MAKEMPSAFE(have_mplock);
371                 trap_fatal(frame, frame->tf_addr);
372                 --gd->gd_trap_nesting_level;
373                 goto out2;
374         }
375 #endif
376 #ifdef DDB
377         if (db_active) {
378                 eva = (frame->tf_trapno == T_PAGEFLT ? frame->tf_addr : 0);
379                 ++gd->gd_trap_nesting_level;
380                 MAKEMPSAFE(have_mplock);
381                 trap_fatal(frame, eva);
382                 --gd->gd_trap_nesting_level;
383                 goto out2;
384         }
385 #endif
386
387         eva = 0;
388
389 #ifdef SMP
390         if (trap_mpsafe == 0) {
391                 ++gd->gd_trap_nesting_level;
392                 MAKEMPSAFE(have_mplock);
393                 --gd->gd_trap_nesting_level;
394         }
395 #endif
396
397         if ((frame->tf_rflags & PSL_I) == 0) {
398                 /*
399                  * Buggy application or kernel code has disabled interrupts
400                  * and then trapped.  Enabling interrupts now is wrong, but
401                  * it is better than running with interrupts disabled until
402                  * they are accidentally enabled later.
403                  */
404                 type = frame->tf_trapno;
405                 if (ISPL(frame->tf_cs) == SEL_UPL) {
406                         MAKEMPSAFE(have_mplock);
407                         /* JG curproc can be NULL */
408                         kprintf(
409                             "pid %ld (%s): trap %d with interrupts disabled\n",
410                             (long)curproc->p_pid, curproc->p_comm, type);
411                 } else if (type != T_NMI && type != T_BPTFLT &&
412                     type != T_TRCTRAP) {
413                         /*
414                          * XXX not quite right, since this may be for a
415                          * multiple fault in user mode.
416                          */
417                         MAKEMPSAFE(have_mplock);
418                         kprintf("kernel trap %d with interrupts disabled\n",
419                             type);
420                 }
421                 cpu_enable_intr();
422         }
423
424         type = frame->tf_trapno;
425         code = frame->tf_err;
426
427         if (ISPL(frame->tf_cs) == SEL_UPL) {
428                 /* user trap */
429
430                 KTR_LOG(kernentry_trap, p->p_pid, lp->lwp_tid,
431                         frame->tf_trapno, eva);
432
433                 userenter(td);
434
435                 sticks = (int)td->td_sticks;
436                 lp->lwp_md.md_regs = frame;
437
438                 switch (type) {
439                 case T_PRIVINFLT:       /* privileged instruction fault */
440                         ucode = ILL_PRVOPC;
441                         i = SIGILL;
442                         break;
443
444                 case T_BPTFLT:          /* bpt instruction fault */
445                 case T_TRCTRAP:         /* trace trap */
446                         frame->tf_rflags &= ~PSL_T;
447                         i = SIGTRAP;
448                         break;
449
450                 case T_ARITHTRAP:       /* arithmetic trap */
451                         ucode = code;
452                         i = SIGFPE;
453 #if 0
454 #if JG
455                         ucode = fputrap();
456 #else
457                         ucode = code;
458 #endif
459                         i = SIGFPE;
460 #endif
461                         break;
462
463                 case T_ASTFLT:          /* Allow process switch */
464                         mycpu->gd_cnt.v_soft++;
465                         if (mycpu->gd_reqflags & RQF_AST_OWEUPC) {
466                                 atomic_clear_int_nonlocked(&mycpu->gd_reqflags,
467                                             RQF_AST_OWEUPC);
468                                 addupc_task(p, p->p_prof.pr_addr,
469                                             p->p_prof.pr_ticks);
470                         }
471                         goto out;
472
473                 case T_PROTFLT:         /* general protection fault */
474                 case T_SEGNPFLT:        /* segment not present fault */
475                 case T_TSSFLT:          /* invalid TSS fault */
476                 case T_DOUBLEFLT:       /* double fault */
477                 default:
478                         ucode = code + BUS_SEGM_FAULT ;
479                         i = SIGBUS;
480                         break;
481
482                 case T_PAGEFLT:         /* page fault */
483                         MAKEMPSAFE(have_mplock);
484                         i = trap_pfault(frame, TRUE);
485                         if (frame->tf_rip == 0)
486                                 kprintf("T_PAGEFLT: Warning %%rip == 0!\n");
487                         if (i == -1)
488                                 goto out;
489                         if (i == 0)
490                                 goto out;
491
492                         ucode = T_PAGEFLT;
493                         break;
494
495                 case T_DIVIDE:          /* integer divide fault */
496                         ucode = FPE_INTDIV;
497                         i = SIGFPE;
498                         break;
499
500                 case T_NMI:
501                         MAKEMPSAFE(have_mplock);
502                         /* machine/parity/power fail/"kitchen sink" faults */
503                         if (isa_nmi(code) == 0) {
504 #ifdef DDB
505                                 /*
506                                  * NMI can be hooked up to a pushbutton
507                                  * for debugging.
508                                  */
509                                 if (ddb_on_nmi) {
510                                         kprintf ("NMI ... going to debugger\n");
511                                         kdb_trap(type, 0, frame);
512                                 }
513 #endif /* DDB */
514                                 goto out2;
515                         } else if (panic_on_nmi)
516                                 panic("NMI indicates hardware failure");
517                         break;
518
519                 case T_OFLOW:           /* integer overflow fault */
520                         ucode = FPE_INTOVF;
521                         i = SIGFPE;
522                         break;
523
524                 case T_BOUND:           /* bounds check fault */
525                         ucode = FPE_FLTSUB;
526                         i = SIGFPE;
527                         break;
528
529                 case T_DNA:
530                         /*
531                          * Virtual kernel intercept - pass the DNA exception
532                          * to the virtual kernel if it asked to handle it.
533                          * This occurs when the virtual kernel is holding
534                          * onto the FP context for a different emulated
535                          * process then the one currently running.
536                          *
537                          * We must still call npxdna() since we may have
538                          * saved FP state that the virtual kernel needs
539                          * to hand over to a different emulated process.
540                          */
541                         if (lp->lwp_vkernel && lp->lwp_vkernel->ve &&
542                             (td->td_pcb->pcb_flags & FP_VIRTFP)
543                         ) {
544                                 npxdna();
545                                 break;
546                         }
547
548                         /*
549                          * The kernel may have switched out the FP unit's
550                          * state, causing the user process to take a fault
551                          * when it tries to use the FP unit.  Restore the
552                          * state here
553                          */
554                         if (npxdna())
555                                 goto out;
556                         i = SIGFPE;
557                         ucode = FPE_FPU_NP_TRAP;
558                         break;
559
560                 case T_FPOPFLT:         /* FPU operand fetch fault */
561                         ucode = T_FPOPFLT;
562                         i = SIGILL;
563                         break;
564
565                 case T_XMMFLT:          /* SIMD floating-point exception */
566                         ucode = 0; /* XXX */
567                         i = SIGFPE;
568                         break;
569                 }
570         } else {
571                 /* kernel trap */
572
573                 switch (type) {
574                 case T_PAGEFLT:                 /* page fault */
575                         MAKEMPSAFE(have_mplock);
576                         trap_pfault(frame, FALSE);
577                         goto out2;
578
579                 case T_DNA:
580                         /*
581                          * The kernel is apparently using fpu for copying.
582                          * XXX this should be fatal unless the kernel has
583                          * registered such use.
584                          */
585                         if (npxdna())
586                                 goto out2;
587                         break;
588
589                 case T_STKFLT:          /* stack fault */
590                         break;
591
592                 case T_PROTFLT:         /* general protection fault */
593                 case T_SEGNPFLT:        /* segment not present fault */
594                         /*
595                          * Invalid segment selectors and out of bounds
596                          * %rip's and %rsp's can be set up in user mode.
597                          * This causes a fault in kernel mode when the
598                          * kernel tries to return to user mode.  We want
599                          * to get this fault so that we can fix the
600                          * problem here and not have to check all the
601                          * selectors and pointers when the user changes
602                          * them.
603                          */
604                         kprintf("trap.c line %d\n", __LINE__);
605                         if (mycpu->gd_intr_nesting_level == 0) {
606                                 if (td->td_pcb->pcb_onfault) {
607                                         frame->tf_rip = (register_t)
608                                                 td->td_pcb->pcb_onfault;
609                                         goto out2;
610                                 }
611                                 if (frame->tf_rip == (long)doreti_iret) {
612                                         frame->tf_rip = (long)doreti_iret_fault;
613                                         goto out2;
614                                 }
615                         }
616                         break;
617
618                 case T_TSSFLT:
619                         /*
620                          * PSL_NT can be set in user mode and isn't cleared
621                          * automatically when the kernel is entered.  This
622                          * causes a TSS fault when the kernel attempts to
623                          * `iret' because the TSS link is uninitialized.  We
624                          * want to get this fault so that we can fix the
625                          * problem here and not every time the kernel is
626                          * entered.
627                          */
628                         if (frame->tf_rflags & PSL_NT) {
629                                 frame->tf_rflags &= ~PSL_NT;
630                                 goto out2;
631                         }
632                         break;
633
634                 case T_TRCTRAP:  /* trace trap */
635 #if 0
636                         if (frame->tf_rip == (int)IDTVEC(syscall)) {
637                                 /*
638                                  * We've just entered system mode via the
639                                  * syscall lcall.  Continue single stepping
640                                  * silently until the syscall handler has
641                                  * saved the flags.
642                                  */
643                                 goto out2;
644                         }
645                         if (frame->tf_rip == (int)IDTVEC(syscall) + 1) {
646                                 /*
647                                  * The syscall handler has now saved the
648                                  * flags.  Stop single stepping it.
649                                  */
650                                 frame->tf_rflags &= ~PSL_T;
651                                 goto out2;
652                         }
653 #endif
654
655                         /*
656                          * Ignore debug register trace traps due to
657                          * accesses in the user's address space, which
658                          * can happen under several conditions such as
659                          * if a user sets a watchpoint on a buffer and
660                          * then passes that buffer to a system call.
661                          * We still want to get TRCTRAPS for addresses
662                          * in kernel space because that is useful when
663                          * debugging the kernel.
664                          */
665 #if JG
666                         if (user_dbreg_trap()) {
667                                 /*
668                                  * Reset breakpoint bits because the
669                                  * processor doesn't
670                                  */
671                                 /* XXX check upper bits here */
672                                 load_dr6(rdr6() & 0xfffffff0);
673                                 goto out2;
674                         }
675 #endif
676                         /*
677                          * FALLTHROUGH (TRCTRAP kernel mode, kernel address)
678                          */
679                 case T_BPTFLT:
680                         /*
681                          * If DDB is enabled, let it handle the debugger trap.
682                          * Otherwise, debugger traps "can't happen".
683                          */
684 #ifdef DDB
685                         MAKEMPSAFE(have_mplock);
686                         if (kdb_trap(type, 0, frame))
687                                 goto out2;
688 #endif
689                         break;
690
691                 case T_NMI:
692                         MAKEMPSAFE(have_mplock);
693                         /* machine/parity/power fail/"kitchen sink" faults */
694 #if NISA > 0
695                         if (isa_nmi(code) == 0) {
696 #ifdef DDB
697                                 /*
698                                  * NMI can be hooked up to a pushbutton
699                                  * for debugging.
700                                  */
701                                 if (ddb_on_nmi) {
702                                         kprintf ("NMI ... going to debugger\n");
703                                         kdb_trap(type, 0, frame);
704                                 }
705 #endif /* DDB */
706                                 goto out2;
707                         } else if (panic_on_nmi == 0)
708                                 goto out2;
709                         /* FALL THROUGH */
710 #endif /* NISA > 0 */
711                 }
712                 MAKEMPSAFE(have_mplock);
713                 trap_fatal(frame, 0);
714                 goto out2;
715         }
716
717         /*
718          * Virtual kernel intercept - if the fault is directly related to a
719          * VM context managed by a virtual kernel then let the virtual kernel
720          * handle it.
721          */
722         if (lp->lwp_vkernel && lp->lwp_vkernel->ve) {
723                 vkernel_trap(lp, frame);
724                 goto out2;
725         }
726
727         /*
728          * Virtual kernel intercept - if the fault is directly related to a
729          * VM context managed by a virtual kernel then let the virtual kernel
730          * handle it.
731          */
732         if (lp->lwp_vkernel && lp->lwp_vkernel->ve) {
733                 vkernel_trap(lp, frame);
734                 goto out;
735         }
736
737         /*
738          * Translate fault for emulators (e.g. Linux) 
739          */
740         if (*p->p_sysent->sv_transtrap)
741                 i = (*p->p_sysent->sv_transtrap)(i, type);
742
743         MAKEMPSAFE(have_mplock);
744         trapsignal(lp, i, ucode);
745
746 #ifdef DEBUG
747         if (type <= MAX_TRAP_MSG) {
748                 uprintf("fatal process exception: %s",
749                         trap_msg[type]);
750                 if ((type == T_PAGEFLT) || (type == T_PROTFLT))
751                         uprintf(", fault VA = 0x%lx", frame->tf_addr);
752                 uprintf("\n");
753         }
754 #endif
755
756 out:
757 #ifdef SMP
758         if (ISPL(frame->tf_cs) == SEL_UPL)
759                 KASSERT(td->td_mpcount == have_mplock, ("badmpcount trap/end from %p", (void *)frame->tf_rip));
760 #endif
761         userret(lp, frame, sticks);
762         userexit(lp);
763 out2:   ;
764 #ifdef SMP
765         if (have_mplock)
766                 rel_mplock();
767 #endif
768         if (p != NULL && lp != NULL)
769                 KTR_LOG(kernentry_trap_ret, p->p_pid, lp->lwp_tid);
770 #ifdef INVARIANTS
771         KASSERT(crit_count == (td->td_pri & ~TDPRI_MASK),
772                 ("syscall: critical section count mismatch! %d/%d",
773                 crit_count / TDPRI_CRIT, td->td_pri / TDPRI_CRIT));
774 #endif
775 }
776
777 static int
778 trap_pfault(struct trapframe *frame, int usermode)
779 {
780         vm_offset_t va;
781         struct vmspace *vm = NULL;
782         vm_map_t map;
783         int rv = 0;
784         vm_prot_t ftype;
785         thread_t td = curthread;
786         struct lwp *lp = td->td_lwp;
787
788         va = trunc_page(frame->tf_addr);
789         if (va >= VM_MIN_KERNEL_ADDRESS) {
790                 /*
791                  * Don't allow user-mode faults in kernel address space.
792                  */
793                 if (usermode)
794                         goto nogo;
795
796                 map = &kernel_map;
797         } else {
798                 /*
799                  * This is a fault on non-kernel virtual memory.
800                  * vm is initialized above to NULL. If curproc is NULL
801                  * or curproc->p_vmspace is NULL the fault is fatal.
802                  */
803                 if (lp != NULL)
804                         vm = lp->lwp_vmspace;
805
806                 if (vm == NULL)
807                         goto nogo;
808
809                 map = &vm->vm_map;
810         }
811
812         /*
813          * PGEX_I is defined only if the execute disable bit capability is
814          * supported and enabled.
815          */
816         if (frame->tf_err & PGEX_W)
817                 ftype = VM_PROT_WRITE;
818 #if JG
819         else if ((frame->tf_err & PGEX_I) && pg_nx != 0)
820                 ftype = VM_PROT_EXECUTE;
821 #endif
822         else
823                 ftype = VM_PROT_READ;
824
825         if (map != &kernel_map) {
826                 /*
827                  * Keep swapout from messing with us during this
828                  *      critical time.
829                  */
830                 PHOLD(lp->lwp_proc);
831
832                 /*
833                  * Grow the stack if necessary
834                  */
835                 /* grow_stack returns false only if va falls into
836                  * a growable stack region and the stack growth
837                  * fails.  It returns true if va was not within
838                  * a growable stack region, or if the stack 
839                  * growth succeeded.
840                  */
841                 if (!grow_stack(lp->lwp_proc, va)) {
842                         rv = KERN_FAILURE;
843                         PRELE(lp->lwp_proc);
844                         goto nogo;
845                 }
846
847                 /* Fault in the user page: */
848                 rv = vm_fault(map, va, ftype,
849                               (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
850                                                       : VM_FAULT_NORMAL);
851
852                 PRELE(lp->lwp_proc);
853         } else {
854                 /*
855                  * Don't have to worry about process locking or stacks
856                  * in the kernel.
857                  */
858                 rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
859         }
860
861         if (rv == KERN_SUCCESS)
862                 return (0);
863 nogo:
864         if (!usermode) {
865                 if (td->td_gd->gd_intr_nesting_level == 0 &&
866                     td->td_pcb->pcb_onfault) {
867                         frame->tf_rip = (register_t)td->td_pcb->pcb_onfault;
868                         return (0);
869                 }
870                 trap_fatal(frame, frame->tf_addr);
871                 return (-1);
872         }
873
874         /*
875          * NOTE: on x86_64 we have a tf_addr field in the trapframe, no
876          * kludge is needed to pass the fault address to signal handlers.
877          */
878         struct proc *p = td->td_proc;
879         kprintf("seg-fault accessing address %p rip=%p pid=%d p_comm=%s\n",
880                 (void *)va, (void *)frame->tf_rip, p->p_pid, p->p_comm);
881         /* Debugger("seg-fault"); */
882
883         return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
884 }
885
886 static void
887 trap_fatal(struct trapframe *frame, vm_offset_t eva)
888 {
889         int code, ss;
890         u_int type;
891         long rsp;
892         struct soft_segment_descriptor softseg;
893         char *msg;
894
895         code = frame->tf_err;
896         type = frame->tf_trapno;
897         sdtossd(&gdt[IDXSEL(frame->tf_cs & 0xffff)], &softseg);
898
899         if (type <= MAX_TRAP_MSG)
900                 msg = trap_msg[type];
901         else
902                 msg = "UNKNOWN";
903         kprintf("\n\nFatal trap %d: %s while in %s mode\n", type, msg,
904             ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
905 #ifdef SMP
906         /* three separate prints in case of a trap on an unmapped page */
907         kprintf("mp_lock = %08x; ", mp_lock);
908         kprintf("cpuid = %d; ", mycpu->gd_cpuid);
909         kprintf("lapic->id = %08x\n", lapic->id);
910 #endif
911         if (type == T_PAGEFLT) {
912                 kprintf("fault virtual address  = 0x%lx\n", eva);
913                 kprintf("fault code             = %s %s %s, %s\n",
914                         code & PGEX_U ? "user" : "supervisor",
915                         code & PGEX_W ? "write" : "read",
916                         code & PGEX_I ? "instruction" : "data",
917                         code & PGEX_P ? "protection violation" : "page not present");
918         }
919         kprintf("instruction pointer    = 0x%lx:0x%lx\n",
920                frame->tf_cs & 0xffff, frame->tf_rip);
921         if (ISPL(frame->tf_cs) == SEL_UPL) {
922                 ss = frame->tf_ss & 0xffff;
923                 rsp = frame->tf_rsp;
924         } else {
925                 ss = GSEL(GDATA_SEL, SEL_KPL);
926                 rsp = (long)&frame->tf_rsp;
927         }
928         kprintf("stack pointer          = 0x%x:0x%lx\n", ss, rsp);
929         kprintf("frame pointer          = 0x%x:0x%lx\n", ss, frame->tf_rbp);
930         kprintf("code segment           = base 0x%lx, limit 0x%lx, type 0x%x\n",
931                softseg.ssd_base, softseg.ssd_limit, softseg.ssd_type);
932         kprintf("                       = DPL %d, pres %d, long %d, def32 %d, gran %d\n",
933                softseg.ssd_dpl, softseg.ssd_p, softseg.ssd_long, softseg.ssd_def32,
934                softseg.ssd_gran);
935         kprintf("processor eflags       = ");
936         if (frame->tf_rflags & PSL_T)
937                 kprintf("trace trap, ");
938         if (frame->tf_rflags & PSL_I)
939                 kprintf("interrupt enabled, ");
940         if (frame->tf_rflags & PSL_NT)
941                 kprintf("nested task, ");
942         if (frame->tf_rflags & PSL_RF)
943                 kprintf("resume, ");
944         kprintf("IOPL = %ld\n", (frame->tf_rflags & PSL_IOPL) >> 12);
945         kprintf("current process                = ");
946         if (curproc) {
947                 kprintf("%lu\n",
948                     (u_long)curproc->p_pid);
949         } else {
950                 kprintf("Idle\n");
951         }
952         kprintf("current thread          = pri %d ", curthread->td_pri);
953         if (curthread->td_pri >= TDPRI_CRIT)
954                 kprintf("(CRIT)");
955         kprintf("\n");
956
957 #ifdef DDB
958         if ((debugger_on_panic || db_active) && kdb_trap(type, code, frame))
959                 return;
960 #endif
961         kprintf("trap number            = %d\n", type);
962         if (type <= MAX_TRAP_MSG)
963                 panic("%s", trap_msg[type]);
964         else
965                 panic("unknown/reserved trap");
966 }
967
968 /*
969  * Double fault handler. Called when a fault occurs while writing
970  * a frame for a trap/exception onto the stack. This usually occurs
971  * when the stack overflows (such is the case with infinite recursion,
972  * for example).
973  */
974 void
975 dblfault_handler(struct trapframe *frame)
976 {
977         kprintf0("DOUBLE FAULT\n");
978         kprintf("\nFatal double fault\n");
979         kprintf("rip = 0x%lx\n", frame->tf_rip);
980         kprintf("rsp = 0x%lx\n", frame->tf_rsp);
981         kprintf("rbp = 0x%lx\n", frame->tf_rbp);
982 #ifdef SMP
983         /* three separate prints in case of a trap on an unmapped page */
984         kprintf("mp_lock = %08x; ", mp_lock);
985         kprintf("cpuid = %d; ", mycpu->gd_cpuid);
986         kprintf("lapic->id = %08x\n", lapic->id);
987 #endif
988         panic("double fault");
989 }
990
991 /*
992  *      syscall2 -      MP aware system call request C handler
993  *
994  *      A system call is essentially treated as a trap except that the
995  *      MP lock is not held on entry or return.  We are responsible for
996  *      obtaining the MP lock if necessary and for handling ASTs
997  *      (e.g. a task switch) prior to return.
998  *
999  *      In general, only simple access and manipulation of curproc and
1000  *      the current stack is allowed without having to hold MP lock.
1001  *
1002  *      MPSAFE - note that large sections of this routine are run without
1003  *               the MP lock.
1004  */
1005 void
1006 syscall2(struct trapframe *frame)
1007 {
1008         struct thread *td = curthread;
1009         struct proc *p = td->td_proc;
1010         struct lwp *lp = td->td_lwp;
1011         caddr_t params;
1012         struct sysent *callp;
1013         register_t orig_tf_rflags;
1014         int sticks;
1015         int error;
1016         int narg;
1017 #ifdef INVARIANTS
1018         int crit_count = td->td_pri & ~TDPRI_MASK;
1019 #endif
1020 #ifdef SMP
1021         int have_mplock = 0;
1022 #endif
1023         register_t *argp;
1024         u_int code;
1025         int reg, regcnt;
1026         union sysunion args;
1027         register_t *argsdst;
1028
1029         mycpu->gd_cnt.v_syscall++;
1030
1031 #ifdef DIAGNOSTIC
1032         if (ISPL(frame->tf_cs) != SEL_UPL) {
1033                 get_mplock();
1034                 panic("syscall");
1035                 /* NOT REACHED */
1036         }
1037 #endif
1038
1039         KTR_LOG(kernentry_syscall, p->p_pid, lp->lwp_tid,
1040                 frame->tf_eax);
1041
1042 #ifdef SMP
1043         KASSERT(td->td_mpcount == 0, ("badmpcount syscall2 from %p", (void *)frame->tf_rip));
1044         if (syscall_mpsafe == 0)
1045                 MAKEMPSAFE(have_mplock);
1046 #endif
1047         userenter(td);          /* lazy raise our priority */
1048
1049         reg = 0;
1050         regcnt = 6;
1051         /*
1052          * Misc
1053          */
1054         sticks = (int)td->td_sticks;
1055         orig_tf_rflags = frame->tf_rflags;
1056
1057         /*
1058          * Virtual kernel intercept - if a VM context managed by a virtual
1059          * kernel issues a system call the virtual kernel handles it, not us.
1060          * Restore the virtual kernel context and return from its system
1061          * call.  The current frame is copied out to the virtual kernel.
1062          */
1063         if (lp->lwp_vkernel && lp->lwp_vkernel->ve) {
1064                 error = vkernel_trap(lp, frame);
1065                 frame->tf_rax = error;
1066                 if (error)
1067                         frame->tf_rflags |= PSL_C;
1068                 error = EJUSTRETURN;
1069                 goto out;
1070         }
1071
1072         /*
1073          * Get the system call parameters and account for time
1074          */
1075         lp->lwp_md.md_regs = frame;
1076         params = (caddr_t)frame->tf_rsp + sizeof(register_t);
1077         code = frame->tf_rax;
1078
1079         if (p->p_sysent->sv_prepsyscall) {
1080                 (*p->p_sysent->sv_prepsyscall)(
1081                         frame, (int *)(&args.nosys.sysmsg + 1),
1082                         &code, &params);
1083         } else {
1084                 if (code == SYS_syscall || code == SYS___syscall) {
1085                         code = frame->tf_rdi;
1086                         reg++;
1087                         regcnt--;
1088                 }
1089         }
1090
1091         if (p->p_sysent->sv_mask)
1092                 code &= p->p_sysent->sv_mask;
1093
1094         if (code >= p->p_sysent->sv_size)
1095                 callp = &p->p_sysent->sv_table[0];
1096         else
1097                 callp = &p->p_sysent->sv_table[code];
1098
1099         narg = callp->sy_narg & SYF_ARGMASK;
1100
1101         /*
1102          * On x86_64 we get up to six arguments in registers. The rest are
1103          * on the stack. The first six members of 'struct trapframe' happen
1104          * to be the registers used to pass arguments, in exactly the right
1105          * order.
1106          */
1107         argp = &frame->tf_rdi;
1108         argp += reg;
1109         argsdst = (register_t *)(&args.nosys.sysmsg + 1);
1110         /*
1111          * JG can we overflow the space pointed to by 'argsdst'
1112          * either with 'bcopy' or with 'copyin'?
1113          */
1114         bcopy(argp, argsdst, sizeof(register_t) * regcnt);
1115         /*
1116          * copyin is MP aware, but the tracing code is not
1117          */
1118         if (narg > regcnt) {
1119                 KASSERT(params != NULL, ("copyin args with no params!"));
1120                 error = copyin(params, &argsdst[regcnt],
1121                         (narg - regcnt) * sizeof(register_t));
1122                 if (error) {
1123 #ifdef KTRACE
1124                         if (KTRPOINT(td, KTR_SYSCALL)) {
1125                                 MAKEMPSAFE(have_mplock);
1126                                 
1127                                 ktrsyscall(lp, code, narg,
1128                                         (void *)(&args.nosys.sysmsg + 1));
1129                         }
1130 #endif
1131                         goto bad;
1132                 }
1133         }
1134
1135 #ifdef KTRACE
1136         if (KTRPOINT(td, KTR_SYSCALL)) {
1137                 MAKEMPSAFE(have_mplock);
1138                 ktrsyscall(lp, code, narg, (void *)(&args.nosys.sysmsg + 1));
1139         }
1140 #endif
1141
1142         /*
1143          * Default return value is 0 (will be copied to %rax).  Double-value
1144          * returns use %rax and %rdx.  %rdx is left unchanged for system
1145          * calls which return only one result.
1146          */
1147         args.sysmsg_fds[0] = 0;
1148         args.sysmsg_fds[1] = frame->tf_rdx;
1149
1150         /*
1151          * The syscall might manipulate the trap frame. If it does it
1152          * will probably return EJUSTRETURN.
1153          */
1154         args.sysmsg_frame = frame;
1155
1156         STOPEVENT(p, S_SCE, narg);      /* MP aware */
1157
1158 #ifdef SMP
1159         /*
1160          * Try to run the syscall without the MP lock if the syscall
1161          * is MP safe.  We have to obtain the MP lock no matter what if 
1162          * we are ktracing
1163          */
1164         if ((callp->sy_narg & SYF_MPSAFE) == 0)
1165                 MAKEMPSAFE(have_mplock);
1166 #endif
1167
1168         error = (*callp->sy_call)(&args);
1169
1170 out:
1171         /*
1172          * MP SAFE (we may or may not have the MP lock at this point)
1173          */
1174         //kprintf("SYSMSG %d ", error);
1175         switch (error) {
1176         case 0:
1177                 /*
1178                  * Reinitialize proc pointer `p' as it may be different
1179                  * if this is a child returning from fork syscall.
1180                  */
1181                 p = curproc;
1182                 lp = curthread->td_lwp;
1183                 frame->tf_rax = args.sysmsg_fds[0];
1184                 frame->tf_rdx = args.sysmsg_fds[1];
1185                 frame->tf_rflags &= ~PSL_C;
1186                 break;
1187         case ERESTART:
1188                 /*
1189                  * Reconstruct pc, we know that 'syscall' is 2 bytes.
1190                  * We have to do a full context restore so that %r10
1191                  * (which was holding the value of %rcx) is restored for
1192                  * the next iteration.
1193                  */
1194                 frame->tf_rip -= frame->tf_err;
1195                 frame->tf_r10 = frame->tf_rcx;
1196                 break;
1197         case EJUSTRETURN:
1198                 break;
1199         case EASYNC:
1200                 panic("Unexpected EASYNC return value (for now)");
1201         default:
1202 bad:
1203                 if (p->p_sysent->sv_errsize) {
1204                         if (error >= p->p_sysent->sv_errsize)
1205                                 error = -1;     /* XXX */
1206                         else
1207                                 error = p->p_sysent->sv_errtbl[error];
1208                 }
1209                 frame->tf_rax = error;
1210                 frame->tf_rflags |= PSL_C;
1211                 break;
1212         }
1213
1214         /*
1215          * Traced syscall.  trapsignal() is not MP aware.
1216          */
1217         if (orig_tf_rflags & PSL_T) {
1218                 MAKEMPSAFE(have_mplock);
1219                 frame->tf_rflags &= ~PSL_T;
1220                 trapsignal(lp, SIGTRAP, 0);
1221         }
1222
1223         /*
1224          * Handle reschedule and other end-of-syscall issues
1225          */
1226         userret(lp, frame, sticks);
1227
1228 #ifdef KTRACE
1229         if (KTRPOINT(td, KTR_SYSRET)) {
1230                 MAKEMPSAFE(have_mplock);
1231                 ktrsysret(lp, code, error, args.sysmsg_result);
1232         }
1233 #endif
1234
1235         /*
1236          * This works because errno is findable through the
1237          * register set.  If we ever support an emulation where this
1238          * is not the case, this code will need to be revisited.
1239          */
1240         STOPEVENT(p, S_SCX, code);
1241
1242         userexit(lp);
1243 #ifdef SMP
1244         /*
1245          * Release the MP lock if we had to get it
1246          */
1247         KASSERT(td->td_mpcount == have_mplock, 
1248                 ("badmpcount syscall2/end from %p", (void *)frame->tf_rip));
1249         if (have_mplock)
1250                 rel_mplock();
1251 #endif
1252         KTR_LOG(kernentry_syscall_ret, p->p_pid, lp->lwp_tid, error);
1253 #ifdef INVARIANTS
1254         KASSERT(crit_count == (td->td_pri & ~TDPRI_MASK), 
1255                 ("syscall: critical section count mismatch! %d/%d",
1256                 crit_count / TDPRI_CRIT, td->td_pri / TDPRI_CRIT));
1257 #endif
1258 }
1259
1260 void
1261 fork_return(struct lwp *lp, struct trapframe *frame)
1262 {
1263         frame->tf_rax = 0;              /* Child returns zero */
1264         frame->tf_rflags &= ~PSL_C;     /* success */
1265         frame->tf_rdx = 1;
1266
1267         generic_lwp_return(lp, frame);
1268         KTR_LOG(kernentry_fork_ret, lp->lwp_proc->p_pid, lp->lwp_tid);
1269 }
1270
1271 /*
1272  * Simplified back end of syscall(), used when returning from fork()
1273  * directly into user mode.  MP lock is held on entry and should be
1274  * released on return.  This code will return back into the fork
1275  * trampoline code which then runs doreti.
1276  */
1277 void
1278 generic_lwp_return(struct lwp *lp, struct trapframe *frame)
1279 {
1280         struct proc *p = lp->lwp_proc;
1281
1282         /*
1283          * Newly forked processes are given a kernel priority.  We have to
1284          * adjust the priority to a normal user priority and fake entry
1285          * into the kernel (call userenter()) to install a passive release
1286          * function just in case userret() decides to stop the process.  This
1287          * can occur when ^Z races a fork.  If we do not install the passive
1288          * release function the current process designation will not be
1289          * released when the thread goes to sleep.
1290          */
1291         lwkt_setpri_self(TDPRI_USER_NORM);
1292         userenter(lp->lwp_thread);
1293         userret(lp, frame, 0);
1294 #ifdef KTRACE
1295         if (KTRPOINT(lp->lwp_thread, KTR_SYSRET))
1296                 ktrsysret(lp, SYS_fork, 0, 0);
1297 #endif
1298         p->p_flag |= P_PASSIVE_ACQ;
1299         userexit(lp);
1300         p->p_flag &= ~P_PASSIVE_ACQ;
1301 #ifdef SMP
1302         KKASSERT(lp->lwp_thread->td_mpcount == 1);
1303         rel_mplock();
1304 #endif
1305 }
1306
1307 /*
1308  * If PGEX_FPFAULT is set then set FP_VIRTFP in the PCB to force a T_DNA
1309  * fault (which is then passed back to the virtual kernel) if an attempt is
1310  * made to use the FP unit.
1311  *
1312  * XXX this is a fairly big hack.
1313  */
1314 void
1315 set_vkernel_fp(struct trapframe *frame)
1316 {
1317         /* JGXXX */
1318 }