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