Add a DEBUG_INTERRUPTS option for debugging unexpected (trap 30) interrupts.
[dragonfly.git] / sys / platform / pc32 / 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  * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.38 2003/10/25 17:36:22 dillon Exp $
40  */
41
42 /*
43  * 386 Trap and System call handling
44  */
45
46 #include "use_isa.h"
47 #include "use_npx.h"
48
49 #include "opt_cpu.h"
50 #include "opt_ddb.h"
51 #include "opt_ktrace.h"
52 #include "opt_clock.h"
53 #include "opt_trap.h"
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/proc.h>
58 #include <sys/pioctl.h>
59 #include <sys/kernel.h>
60 #include <sys/resourcevar.h>
61 #include <sys/signalvar.h>
62 #include <sys/syscall.h>
63 #include <sys/sysctl.h>
64 #include <sys/sysent.h>
65 #include <sys/uio.h>
66 #include <sys/vmmeter.h>
67 #include <sys/malloc.h>
68 #ifdef KTRACE
69 #include <sys/ktrace.h>
70 #endif
71 #include <sys/sysproto.h>
72 #include <sys/sysunion.h>
73
74 #include <vm/vm.h>
75 #include <vm/vm_param.h>
76 #include <sys/lock.h>
77 #include <vm/pmap.h>
78 #include <vm/vm_kern.h>
79 #include <vm/vm_map.h>
80 #include <vm/vm_page.h>
81 #include <vm/vm_extern.h>
82
83 #include <machine/cpu.h>
84 #include <machine/ipl.h>
85 #include <machine/md_var.h>
86 #include <machine/pcb.h>
87 #ifdef SMP
88 #include <machine/smp.h>
89 #endif
90 #include <machine/tss.h>
91 #include <machine/globaldata.h>
92
93 #include <i386/isa/intr_machdep.h>
94
95 #ifdef POWERFAIL_NMI
96 #include <sys/syslog.h>
97 #include <machine/clock.h>
98 #endif
99
100 #include <machine/vm86.h>
101
102 #include <ddb/ddb.h>
103 #include <sys/msgport2.h>
104 #include <sys/thread2.h>
105
106 int (*pmath_emulate) (struct trapframe *);
107
108 extern void trap (struct trapframe frame);
109 extern int trapwrite (unsigned addr);
110 extern void syscall2 (struct trapframe frame);
111 extern void sendsys2 (struct trapframe frame);
112
113 static int trap_pfault (struct trapframe *, int, vm_offset_t);
114 static void trap_fatal (struct trapframe *, vm_offset_t);
115 void dblfault_handler (void);
116
117 extern inthand_t IDTVEC(syscall);
118
119 #define MAX_TRAP_MSG            28
120 static char *trap_msg[] = {
121         "",                                     /*  0 unused */
122         "privileged instruction fault",         /*  1 T_PRIVINFLT */
123         "",                                     /*  2 unused */
124         "breakpoint instruction fault",         /*  3 T_BPTFLT */
125         "",                                     /*  4 unused */
126         "",                                     /*  5 unused */
127         "arithmetic trap",                      /*  6 T_ARITHTRAP */
128         "system forced exception",              /*  7 T_ASTFLT */
129         "",                                     /*  8 unused */
130         "general protection fault",             /*  9 T_PROTFLT */
131         "trace trap",                           /* 10 T_TRCTRAP */
132         "",                                     /* 11 unused */
133         "page fault",                           /* 12 T_PAGEFLT */
134         "",                                     /* 13 unused */
135         "alignment fault",                      /* 14 T_ALIGNFLT */
136         "",                                     /* 15 unused */
137         "",                                     /* 16 unused */
138         "",                                     /* 17 unused */
139         "integer divide fault",                 /* 18 T_DIVIDE */
140         "non-maskable interrupt trap",          /* 19 T_NMI */
141         "overflow trap",                        /* 20 T_OFLOW */
142         "FPU bounds check fault",               /* 21 T_BOUND */
143         "FPU device not available",             /* 22 T_DNA */
144         "double fault",                         /* 23 T_DOUBLEFLT */
145         "FPU operand fetch fault",              /* 24 T_FPOPFLT */
146         "invalid TSS fault",                    /* 25 T_TSSFLT */
147         "segment not present fault",            /* 26 T_SEGNPFLT */
148         "stack fault",                          /* 27 T_STKFLT */
149         "machine check trap",                   /* 28 T_MCHK */
150 };
151
152 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
153 extern int has_f00f_bug;
154 #endif
155
156 #ifdef DDB
157 static int ddb_on_nmi = 1;
158 SYSCTL_INT(_machdep, OID_AUTO, ddb_on_nmi, CTLFLAG_RW,
159         &ddb_on_nmi, 0, "Go to DDB on NMI");
160 #endif
161 static int panic_on_nmi = 1;
162 SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
163         &panic_on_nmi, 0, "Panic on NMI");
164 static int fast_release;
165 SYSCTL_INT(_machdep, OID_AUTO, fast_release, CTLFLAG_RW,
166         &fast_release, 0, "Passive Release was optimal");
167 static int slow_release;
168 SYSCTL_INT(_machdep, OID_AUTO, slow_release, CTLFLAG_RW,
169         &slow_release, 0, "Passive Release was nonoptimal");
170 static int pass_release;
171 SYSCTL_INT(_machdep, OID_AUTO, pass_release, CTLFLAG_RW,
172         &pass_release, 0, "Passive Release on switch");
173 static int pass_hold;
174 SYSCTL_INT(_machdep, OID_AUTO, pass_hold, CTLFLAG_RW,
175         &pass_hold, 0, "Passive Held on switch");
176
177 MALLOC_DEFINE(M_SYSMSG, "sysmsg", "sysmsg structure");
178
179 /*
180  * USER->KERNEL transition.  Do not transition us out of userland from the
181  * point of view of the userland scheduler unless we actually have to
182  * switch.
183  *
184  * passive_release is called from within a critical section and the BGL will
185  * still be held.  This function is NOT called for preemptions, only for
186  * switchouts.  We only actually release our P_CURPROC designation when we
187  * are going to sleep, otherwise another process might be assigned P_CURPROC
188  * unnecessarily.
189  */
190 static void
191 passive_release(struct thread *td)
192 {
193         struct proc *p = td->td_proc;
194
195         if ((p->p_flag & P_CP_RELEASED) == 0) {
196                 p->p_flag |= P_CP_RELEASED;
197                 lwkt_setpri_self(TDPRI_KERN_USER);
198         }
199         if ((p->p_flag & P_CURPROC) && (td->td_flags & TDF_RUNQ) == 0) {
200                 td->td_release = NULL;
201                 release_curproc(p);
202                 ++pass_release;
203         } else if ((p->p_flag & (P_CURPROC|P_PASSIVE_ACQ)) == (P_CURPROC|P_PASSIVE_ACQ)) {
204                 td->td_release = NULL;
205                 release_curproc(p);
206         } else {
207                 ++pass_hold;
208         }
209 }
210
211 /*
212  * userenter() passively intercepts the thread switch function to increase
213  * the thread priority from a user priority to a kernel priority, reducing
214  * syscall and trap overhead for the case where no switch occurs.
215  */
216
217 static __inline void
218 userenter(struct thread *curtd)
219 {
220         curtd->td_release = passive_release;
221 }
222
223 static __inline void
224 userexit(struct proc *p)
225 {
226         struct thread *td = p->p_thread;
227
228         /*
229          * Reacquire our P_CURPROC status and adjust the LWKT priority
230          * for our return to userland.  We can fast path the case where
231          * td_release was not called by checking particular proc flags.
232          * Otherwise we do it the slow way.
233          *
234          * Lowering our priority may make other higher priority threads
235          * runnable. lwkt_setpri_self() does not switch away, so call
236          * lwkt_maybe_switch() to deal with it.
237          */
238         td->td_release = NULL;
239         if ((p->p_flag & (P_CP_RELEASED|P_CURPROC)) == P_CURPROC) {
240                 ++fast_release;
241         } else {
242                 ++slow_release;
243                 acquire_curproc(p);
244
245                 switch(p->p_rtprio.type) {
246                 case RTP_PRIO_IDLE:
247                         lwkt_setpri_self(TDPRI_USER_IDLE);
248                         break;
249                 case RTP_PRIO_REALTIME:
250                 case RTP_PRIO_FIFO:
251                         lwkt_setpri_self(TDPRI_USER_REAL);
252                         break;
253                 default:
254                         lwkt_setpri_self(TDPRI_USER_NORM);
255                         break;
256                 }
257         }
258         lwkt_maybe_switch();
259 }
260
261
262 static void
263 userret(struct proc *p, struct trapframe *frame, u_quad_t oticks)
264 {
265         int sig;
266
267         /*
268          * Post any pending signals
269          */
270         while ((sig = CURSIG(p)) != 0) {
271                 postsig(sig);
272         }
273
274         /*
275          * If a reschedule has been requested then we release the current
276          * process in order to shift our P_CURPROC designation to another
277          * user process.  userexit() will reacquire P_CURPROC and block
278          * there.
279          */
280         if (resched_wanted()) {
281                 p->p_thread->td_release = NULL;
282                 if ((p->p_flag & P_CP_RELEASED) == 0) {
283                         p->p_flag |= P_CP_RELEASED;
284                         lwkt_setpri_self(TDPRI_KERN_USER);
285                 }
286                 if (p->p_flag & P_CURPROC) {
287                         release_curproc(p);
288                 } else {
289                         clear_resched();
290                 }
291         }
292
293         /*
294          * Charge system time if profiling.  Note: times are in microseconds.
295          */
296         if (p->p_flag & P_PROFIL) {
297                 addupc_task(p, frame->tf_eip, 
298                     (u_int)(curthread->td_sticks - oticks));
299         }
300
301         /*
302          * Post any pending signals XXX
303          */
304         while ((sig = CURSIG(p)) != 0)
305                 postsig(sig);
306 }
307
308 #ifdef DEVICE_POLLING
309 extern u_int32_t poll_in_trap;
310 extern int ether_poll (int count);
311 #endif /* DEVICE_POLLING */
312
313 /*
314  * Exception, fault, and trap interface to the FreeBSD kernel.
315  * This common code is called from assembly language IDT gate entry
316  * routines that prepare a suitable stack frame, and restore this
317  * frame after the exception has been processed.
318  *
319  * This function is also called from doreti in an interlock to handle ASTs.
320  * For example:  hardwareint->INTROUTINE->(set ast)->doreti->trap
321  *
322  * NOTE!  We have to retrieve the fault address prior to obtaining the
323  * MP lock because get_mplock() may switch out.  YYY cr2 really ought
324  * to be retrieved by the assembly code, not here.
325  */
326 void
327 trap(frame)
328         struct trapframe frame;
329 {
330         struct thread *td = curthread;
331         struct proc *p;
332         u_quad_t sticks = 0;
333         int i = 0, ucode = 0, type, code;
334         vm_offset_t eva;
335
336         p = td->td_proc;
337 #ifdef DDB
338         if (db_active) {
339                 eva = (frame.tf_trapno == T_PAGEFLT ? rcr2() : 0);
340                 get_mplock();
341                 trap_fatal(&frame, eva);
342                 goto out2;
343         }
344 #endif
345
346         eva = 0;
347         if (frame.tf_trapno == T_PAGEFLT) {
348                 /*
349                  * For some Cyrix CPUs, %cr2 is clobbered by interrupts.
350                  * This problem is worked around by using an interrupt
351                  * gate for the pagefault handler.  We are finally ready
352                  * to read %cr2 and then must reenable interrupts.
353                  *
354                  * XXX this should be in the switch statement, but the
355                  * NO_FOOF_HACK and VM86 goto and ifdefs obfuscate the
356                  * flow of control too much for this to be obviously
357                  * correct.
358                  */
359                 eva = rcr2();
360                 get_mplock();
361                 cpu_enable_intr();
362         } else {
363                 get_mplock();
364         }
365         /*
366          * MP lock is held at this point
367          */
368
369         if (!(frame.tf_eflags & PSL_I)) {
370                 /*
371                  * Buggy application or kernel code has disabled interrupts
372                  * and then trapped.  Enabling interrupts now is wrong, but
373                  * it is better than running with interrupts disabled until
374                  * they are accidentally enabled later.
375                  */
376                 type = frame.tf_trapno;
377                 if (ISPL(frame.tf_cs)==SEL_UPL || (frame.tf_eflags & PSL_VM)) {
378                         printf(
379                             "pid %ld (%s): trap %d with interrupts disabled\n",
380                             (long)curproc->p_pid, curproc->p_comm, type);
381                 } else if (type != T_BPTFLT && type != T_TRCTRAP) {
382                         /*
383                          * XXX not quite right, since this may be for a
384                          * multiple fault in user mode.
385                          */
386                         printf("kernel trap %d with interrupts disabled\n",
387                             type);
388                 }
389                 cpu_enable_intr();
390         }
391
392
393 #ifdef DEVICE_POLLING
394         if (poll_in_trap)
395                 ether_poll(poll_in_trap);
396 #endif /* DEVICE_POLLING */
397
398 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
399 restart:
400 #endif
401         type = frame.tf_trapno;
402         code = frame.tf_err;
403
404         if (in_vm86call) {
405                 if (frame.tf_eflags & PSL_VM &&
406                     (type == T_PROTFLT || type == T_STKFLT)) {
407 #ifdef SMP
408                         KKASSERT(curthread->td_mpcount > 0);
409 #endif
410                         i = vm86_emulate((struct vm86frame *)&frame);
411 #ifdef SMP
412                         KKASSERT(curthread->td_mpcount > 0);
413 #endif
414                         if (i != 0) {
415                                 /*
416                                  * returns to original process
417                                  */
418                                 vm86_trap((struct vm86frame *)&frame);
419                                 KKASSERT(0);
420                         }
421                         goto out2;
422                 }
423                 switch (type) {
424                         /*
425                          * these traps want either a process context, or
426                          * assume a normal userspace trap.
427                          */
428                 case T_PROTFLT:
429                 case T_SEGNPFLT:
430                         trap_fatal(&frame, eva);
431                         goto out2;
432                 case T_TRCTRAP:
433                         type = T_BPTFLT;        /* kernel breakpoint */
434                         /* FALL THROUGH */
435                 }
436                 goto kernel_trap;       /* normal kernel trap handling */
437         }
438
439         if ((ISPL(frame.tf_cs) == SEL_UPL) || (frame.tf_eflags & PSL_VM)) {
440                 /* user trap */
441
442                 userenter(td);
443
444                 sticks = curthread->td_sticks;
445                 p->p_md.md_regs = &frame;
446
447                 switch (type) {
448                 case T_PRIVINFLT:       /* privileged instruction fault */
449                         ucode = type;
450                         i = SIGILL;
451                         break;
452
453                 case T_BPTFLT:          /* bpt instruction fault */
454                 case T_TRCTRAP:         /* trace trap */
455                         frame.tf_eflags &= ~PSL_T;
456                         i = SIGTRAP;
457                         break;
458
459                 case T_ARITHTRAP:       /* arithmetic trap */
460                         ucode = code;
461                         i = SIGFPE;
462                         break;
463
464                 case T_ASTFLT:          /* Allow process switch */
465                         mycpu->gd_cnt.v_soft++;
466                         if (mycpu->gd_reqflags & RQF_AST_OWEUPC) {
467                                 atomic_clear_int_nonlocked(&mycpu->gd_reqflags,
468                                             RQF_AST_OWEUPC);
469                                 addupc_task(p, p->p_stats->p_prof.pr_addr,
470                                             p->p_stats->p_prof.pr_ticks);
471                         }
472                         goto out;
473
474                         /*
475                          * The following two traps can happen in
476                          * vm86 mode, and, if so, we want to handle
477                          * them specially.
478                          */
479                 case T_PROTFLT:         /* general protection fault */
480                 case T_STKFLT:          /* stack fault */
481                         if (frame.tf_eflags & PSL_VM) {
482                                 i = vm86_emulate((struct vm86frame *)&frame);
483                                 if (i == 0)
484                                         goto out;
485                                 break;
486                         }
487                         /* FALL THROUGH */
488
489                 case T_SEGNPFLT:        /* segment not present fault */
490                 case T_TSSFLT:          /* invalid TSS fault */
491                 case T_DOUBLEFLT:       /* double fault */
492                 default:
493                         ucode = code + BUS_SEGM_FAULT ;
494                         i = SIGBUS;
495                         break;
496
497                 case T_PAGEFLT:         /* page fault */
498                         i = trap_pfault(&frame, TRUE, eva);
499                         if (i == -1)
500                                 goto out;
501 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
502                         if (i == -2)
503                                 goto restart;
504 #endif
505                         if (i == 0)
506                                 goto out;
507
508                         ucode = T_PAGEFLT;
509                         break;
510
511                 case T_DIVIDE:          /* integer divide fault */
512                         ucode = FPE_INTDIV;
513                         i = SIGFPE;
514                         break;
515
516 #if NISA > 0
517                 case T_NMI:
518 #ifdef POWERFAIL_NMI
519                         goto handle_powerfail;
520 #else /* !POWERFAIL_NMI */
521                         /* machine/parity/power fail/"kitchen sink" faults */
522                         if (isa_nmi(code) == 0) {
523 #ifdef DDB
524                                 /*
525                                  * NMI can be hooked up to a pushbutton
526                                  * for debugging.
527                                  */
528                                 if (ddb_on_nmi) {
529                                         printf ("NMI ... going to debugger\n");
530                                         kdb_trap (type, 0, &frame);
531                                 }
532 #endif /* DDB */
533                                 goto out2;
534                         } else if (panic_on_nmi)
535                                 panic("NMI indicates hardware failure");
536                         break;
537 #endif /* POWERFAIL_NMI */
538 #endif /* NISA > 0 */
539
540                 case T_OFLOW:           /* integer overflow fault */
541                         ucode = FPE_INTOVF;
542                         i = SIGFPE;
543                         break;
544
545                 case T_BOUND:           /* bounds check fault */
546                         ucode = FPE_FLTSUB;
547                         i = SIGFPE;
548                         break;
549
550                 case T_DNA:
551 #if NNPX > 0
552                         /* if a transparent fault (due to context switch "late") */
553                         if (npxdna())
554                                 goto out;
555 #endif
556                         if (!pmath_emulate) {
557                                 i = SIGFPE;
558                                 ucode = FPE_FPU_NP_TRAP;
559                                 break;
560                         }
561                         i = (*pmath_emulate)(&frame);
562                         if (i == 0) {
563                                 if (!(frame.tf_eflags & PSL_T))
564                                         goto out2;
565                                 frame.tf_eflags &= ~PSL_T;
566                                 i = SIGTRAP;
567                         }
568                         /* else ucode = emulator_only_knows() XXX */
569                         break;
570
571                 case T_FPOPFLT:         /* FPU operand fetch fault */
572                         ucode = T_FPOPFLT;
573                         i = SIGILL;
574                         break;
575
576                 case T_XMMFLT:          /* SIMD floating-point exception */
577                         ucode = 0; /* XXX */
578                         i = SIGFPE;
579                         break;
580                 }
581         } else {
582 kernel_trap:
583                 /* kernel trap */
584
585                 switch (type) {
586                 case T_PAGEFLT:                 /* page fault */
587                         (void) trap_pfault(&frame, FALSE, eva);
588                         goto out2;
589
590                 case T_DNA:
591 #if NNPX > 0
592                         /*
593                          * The kernel is apparently using npx for copying.
594                          * XXX this should be fatal unless the kernel has
595                          * registered such use.
596                          */
597                         if (npxdna())
598                                 goto out2;
599 #endif
600                         break;
601
602                 case T_PROTFLT:         /* general protection fault */
603                 case T_SEGNPFLT:        /* segment not present fault */
604                         /*
605                          * Invalid segment selectors and out of bounds
606                          * %eip's and %esp's can be set up in user mode.
607                          * This causes a fault in kernel mode when the
608                          * kernel tries to return to user mode.  We want
609                          * to get this fault so that we can fix the
610                          * problem here and not have to check all the
611                          * selectors and pointers when the user changes
612                          * them.
613                          */
614 #define MAYBE_DORETI_FAULT(where, whereto)                              \
615         do {                                                            \
616                 if (frame.tf_eip == (int)where) {                       \
617                         frame.tf_eip = (int)whereto;                    \
618                         goto out2;                                      \
619                 }                                                       \
620         } while (0)
621                         if (mycpu->gd_intr_nesting_level == 0) {
622                                 /*
623                                  * Invalid %fs's and %gs's can be created using
624                                  * procfs or PT_SETREGS or by invalidating the
625                                  * underlying LDT entry.  This causes a fault
626                                  * in kernel mode when the kernel attempts to
627                                  * switch contexts.  Lose the bad context
628                                  * (XXX) so that we can continue, and generate
629                                  * a signal.
630                                  */
631                                 if (frame.tf_eip == (int)cpu_switch_load_gs) {
632                                         curthread->td_pcb->pcb_gs = 0;
633                                         psignal(p, SIGBUS);
634                                         goto out2;
635                                 }
636                                 MAYBE_DORETI_FAULT(doreti_iret,
637                                                    doreti_iret_fault);
638                                 MAYBE_DORETI_FAULT(doreti_popl_ds,
639                                                    doreti_popl_ds_fault);
640                                 MAYBE_DORETI_FAULT(doreti_popl_es,
641                                                    doreti_popl_es_fault);
642                                 MAYBE_DORETI_FAULT(doreti_popl_fs,
643                                                    doreti_popl_fs_fault);
644                                 if (curthread->td_pcb->pcb_onfault) {
645                                         frame.tf_eip = (int)curthread->td_pcb->pcb_onfault;
646                                         goto out2;
647                                 }
648                         }
649                         break;
650
651                 case T_TSSFLT:
652                         /*
653                          * PSL_NT can be set in user mode and isn't cleared
654                          * automatically when the kernel is entered.  This
655                          * causes a TSS fault when the kernel attempts to
656                          * `iret' because the TSS link is uninitialized.  We
657                          * want to get this fault so that we can fix the
658                          * problem here and not every time the kernel is
659                          * entered.
660                          */
661                         if (frame.tf_eflags & PSL_NT) {
662                                 frame.tf_eflags &= ~PSL_NT;
663                                 goto out2;
664                         }
665                         break;
666
667                 case T_TRCTRAP:  /* trace trap */
668                         if (frame.tf_eip == (int)IDTVEC(syscall)) {
669                                 /*
670                                  * We've just entered system mode via the
671                                  * syscall lcall.  Continue single stepping
672                                  * silently until the syscall handler has
673                                  * saved the flags.
674                                  */
675                                 goto out2;
676                         }
677                         if (frame.tf_eip == (int)IDTVEC(syscall) + 1) {
678                                 /*
679                                  * The syscall handler has now saved the
680                                  * flags.  Stop single stepping it.
681                                  */
682                                 frame.tf_eflags &= ~PSL_T;
683                                 goto out2;
684                         }
685                         /*
686                          * Ignore debug register trace traps due to
687                          * accesses in the user's address space, which
688                          * can happen under several conditions such as
689                          * if a user sets a watchpoint on a buffer and
690                          * then passes that buffer to a system call.
691                          * We still want to get TRCTRAPS for addresses
692                          * in kernel space because that is useful when
693                          * debugging the kernel.
694                          */
695                         if (user_dbreg_trap()) {
696                                 /*
697                                  * Reset breakpoint bits because the
698                                  * processor doesn't
699                                  */
700                                 load_dr6(rdr6() & 0xfffffff0);
701                                 goto out2;
702                         }
703                         /*
704                          * Fall through (TRCTRAP kernel mode, kernel address)
705                          */
706                 case T_BPTFLT:
707                         /*
708                          * If DDB is enabled, let it handle the debugger trap.
709                          * Otherwise, debugger traps "can't happen".
710                          */
711 #ifdef DDB
712                         if (kdb_trap (type, 0, &frame))
713                                 goto out2;
714 #endif
715                         break;
716
717 #if NISA > 0
718                 case T_NMI:
719 #ifdef POWERFAIL_NMI
720 #ifndef TIMER_FREQ
721 #  define TIMER_FREQ 1193182
722 #endif
723         handle_powerfail:
724                 {
725                   static unsigned lastalert = 0;
726
727                   if(time_second - lastalert > 10)
728                     {
729                       log(LOG_WARNING, "NMI: power fail\n");
730                       sysbeep(TIMER_FREQ/880, hz);
731                       lastalert = time_second;
732                     }
733                     /* YYY mp count */
734                   goto out2;
735                 }
736 #else /* !POWERFAIL_NMI */
737                         /* machine/parity/power fail/"kitchen sink" faults */
738                         if (isa_nmi(code) == 0) {
739 #ifdef DDB
740                                 /*
741                                  * NMI can be hooked up to a pushbutton
742                                  * for debugging.
743                                  */
744                                 if (ddb_on_nmi) {
745                                         printf ("NMI ... going to debugger\n");
746                                         kdb_trap (type, 0, &frame);
747                                 }
748 #endif /* DDB */
749                                 goto out2;
750                         } else if (panic_on_nmi == 0)
751                                 goto out2;
752                         /* FALL THROUGH */
753 #endif /* POWERFAIL_NMI */
754 #endif /* NISA > 0 */
755                 }
756
757                 trap_fatal(&frame, eva);
758                 goto out2;
759         }
760
761         /* Translate fault for emulators (e.g. Linux) */
762         if (*p->p_sysent->sv_transtrap)
763                 i = (*p->p_sysent->sv_transtrap)(i, type);
764
765         trapsignal(p, i, ucode);
766
767 #ifdef DEBUG
768         if (type <= MAX_TRAP_MSG) {
769                 uprintf("fatal process exception: %s",
770                         trap_msg[type]);
771                 if ((type == T_PAGEFLT) || (type == T_PROTFLT))
772                         uprintf(", fault VA = 0x%lx", (u_long)eva);
773                 uprintf("\n");
774         }
775 #endif
776
777 out:
778 #ifdef SMP
779         if (ISPL(frame.tf_cs) == SEL_UPL)
780                 KASSERT(curthread->td_mpcount == 1, ("badmpcount trap from %p", (void *)frame.tf_eip));
781 #endif
782         userret(p, &frame, sticks);
783         userexit(p);
784 out2:
785 #ifdef SMP
786         KKASSERT(curthread->td_mpcount > 0);
787 #endif
788         rel_mplock();
789 }
790
791 #ifdef notyet
792 /*
793  * This version doesn't allow a page fault to user space while
794  * in the kernel. The rest of the kernel needs to be made "safe"
795  * before this can be used. I think the only things remaining
796  * to be made safe are the iBCS2 code and the process tracing/
797  * debugging code.
798  */
799 static int
800 trap_pfault(frame, usermode, eva)
801         struct trapframe *frame;
802         int usermode;
803         vm_offset_t eva;
804 {
805         vm_offset_t va;
806         struct vmspace *vm = NULL;
807         vm_map_t map = 0;
808         int rv = 0;
809         vm_prot_t ftype;
810         struct proc *p = curproc;
811
812         if (frame->tf_err & PGEX_W)
813                 ftype = VM_PROT_WRITE;
814         else
815                 ftype = VM_PROT_READ;
816
817         va = trunc_page(eva);
818         if (va < VM_MIN_KERNEL_ADDRESS) {
819                 vm_offset_t v;
820                 vm_page_t mpte;
821
822                 if (p == NULL ||
823                     (!usermode && va < VM_MAXUSER_ADDRESS &&
824                      (mycpu->gd_intr_nesting_level != 0 || 
825                       curthread->td_pcb->pcb_onfault == NULL))) {
826                         trap_fatal(frame, eva);
827                         return (-1);
828                 }
829
830                 /*
831                  * This is a fault on non-kernel virtual memory.
832                  * vm is initialized above to NULL. If curproc is NULL
833                  * or curproc->p_vmspace is NULL the fault is fatal.
834                  */
835                 vm = p->p_vmspace;
836                 if (vm == NULL)
837                         goto nogo;
838
839                 map = &vm->vm_map;
840
841                 /*
842                  * Keep swapout from messing with us during this
843                  *      critical time.
844                  */
845                 ++p->p_lock;
846
847                 /*
848                  * Grow the stack if necessary
849                  */
850                 /* grow_stack returns false only if va falls into
851                  * a growable stack region and the stack growth
852                  * fails.  It returns true if va was not within
853                  * a growable stack region, or if the stack 
854                  * growth succeeded.
855                  */
856                 if (!grow_stack (p, va)) {
857                         rv = KERN_FAILURE;
858                         --p->p_lock;
859                         goto nogo;
860                 }
861                 
862                 /* Fault in the user page: */
863                 rv = vm_fault(map, va, ftype,
864                               (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
865                                                       : VM_FAULT_NORMAL);
866
867                 --p->p_lock;
868         } else {
869                 /*
870                  * Don't allow user-mode faults in kernel address space.
871                  */
872                 if (usermode)
873                         goto nogo;
874
875                 /*
876                  * Since we know that kernel virtual address addresses
877                  * always have pte pages mapped, we just have to fault
878                  * the page.
879                  */
880                 rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
881         }
882
883         if (rv == KERN_SUCCESS)
884                 return (0);
885 nogo:
886         if (!usermode) {
887                 if (mycpu->gd_intr_nesting_level == 0 && curthread->td_pcb->pcb_onfault) {
888                         frame->tf_eip = (int)curthread->td_pcb->pcb_onfault;
889                         return (0);
890                 }
891                 trap_fatal(frame, eva);
892                 return (-1);
893         }
894
895         /* kludge to pass faulting virtual address to sendsig */
896         frame->tf_err = eva;
897
898         return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
899 }
900 #endif
901
902 int
903 trap_pfault(frame, usermode, eva)
904         struct trapframe *frame;
905         int usermode;
906         vm_offset_t eva;
907 {
908         vm_offset_t va;
909         struct vmspace *vm = NULL;
910         vm_map_t map = 0;
911         int rv = 0;
912         vm_prot_t ftype;
913         struct proc *p = curproc;
914
915         va = trunc_page(eva);
916         if (va >= KERNBASE) {
917                 /*
918                  * Don't allow user-mode faults in kernel address space.
919                  * An exception:  if the faulting address is the invalid
920                  * instruction entry in the IDT, then the Intel Pentium
921                  * F00F bug workaround was triggered, and we need to
922                  * treat it is as an illegal instruction, and not a page
923                  * fault.
924                  */
925 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
926                 if ((eva == (unsigned int)&idt[6]) && has_f00f_bug) {
927                         frame->tf_trapno = T_PRIVINFLT;
928                         return -2;
929                 }
930 #endif
931                 if (usermode)
932                         goto nogo;
933
934                 map = kernel_map;
935         } else {
936                 /*
937                  * This is a fault on non-kernel virtual memory.
938                  * vm is initialized above to NULL. If curproc is NULL
939                  * or curproc->p_vmspace is NULL the fault is fatal.
940                  */
941                 if (p != NULL)
942                         vm = p->p_vmspace;
943
944                 if (vm == NULL)
945                         goto nogo;
946
947                 map = &vm->vm_map;
948         }
949
950         if (frame->tf_err & PGEX_W)
951                 ftype = VM_PROT_WRITE;
952         else
953                 ftype = VM_PROT_READ;
954
955         if (map != kernel_map) {
956                 /*
957                  * Keep swapout from messing with us during this
958                  *      critical time.
959                  */
960                 ++p->p_lock;
961
962                 /*
963                  * Grow the stack if necessary
964                  */
965                 /* grow_stack returns false only if va falls into
966                  * a growable stack region and the stack growth
967                  * fails.  It returns true if va was not within
968                  * a growable stack region, or if the stack 
969                  * growth succeeded.
970                  */
971                 if (!grow_stack (p, va)) {
972                         rv = KERN_FAILURE;
973                         --p->p_lock;
974                         goto nogo;
975                 }
976
977                 /* Fault in the user page: */
978                 rv = vm_fault(map, va, ftype,
979                               (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
980                                                       : VM_FAULT_NORMAL);
981
982                 --p->p_lock;
983         } else {
984                 /*
985                  * Don't have to worry about process locking or stacks in the kernel.
986                  */
987                 rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
988         }
989
990         if (rv == KERN_SUCCESS)
991                 return (0);
992 nogo:
993         if (!usermode) {
994                 if (mycpu->gd_intr_nesting_level == 0 && curthread->td_pcb->pcb_onfault) {
995                         frame->tf_eip = (int)curthread->td_pcb->pcb_onfault;
996                         return (0);
997                 }
998                 trap_fatal(frame, eva);
999                 return (-1);
1000         }
1001
1002         /* kludge to pass faulting virtual address to sendsig */
1003         frame->tf_err = eva;
1004
1005         return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
1006 }
1007
1008 static void
1009 trap_fatal(frame, eva)
1010         struct trapframe *frame;
1011         vm_offset_t eva;
1012 {
1013         int code, type, ss, esp;
1014         struct soft_segment_descriptor softseg;
1015
1016         code = frame->tf_err;
1017         type = frame->tf_trapno;
1018         sdtossd(&gdt[IDXSEL(frame->tf_cs & 0xffff)].sd, &softseg);
1019
1020         if (type <= MAX_TRAP_MSG)
1021                 printf("\n\nFatal trap %d: %s while in %s mode\n",
1022                         type, trap_msg[type],
1023                         frame->tf_eflags & PSL_VM ? "vm86" :
1024                         ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
1025 #ifdef SMP
1026         /* three seperate prints in case of a trap on an unmapped page */
1027         printf("mp_lock = %08x; ", mp_lock);
1028         printf("cpuid = %d; ", mycpu->gd_cpuid);
1029         printf("lapic.id = %08x\n", lapic.id);
1030 #endif
1031         if (type == T_PAGEFLT) {
1032                 printf("fault virtual address   = 0x%x\n", eva);
1033                 printf("fault code              = %s %s, %s\n",
1034                         code & PGEX_U ? "user" : "supervisor",
1035                         code & PGEX_W ? "write" : "read",
1036                         code & PGEX_P ? "protection violation" : "page not present");
1037         }
1038         printf("instruction pointer     = 0x%x:0x%x\n",
1039                frame->tf_cs & 0xffff, frame->tf_eip);
1040         if ((ISPL(frame->tf_cs) == SEL_UPL) || (frame->tf_eflags & PSL_VM)) {
1041                 ss = frame->tf_ss & 0xffff;
1042                 esp = frame->tf_esp;
1043         } else {
1044                 ss = GSEL(GDATA_SEL, SEL_KPL);
1045                 esp = (int)&frame->tf_esp;
1046         }
1047         printf("stack pointer           = 0x%x:0x%x\n", ss, esp);
1048         printf("frame pointer           = 0x%x:0x%x\n", ss, frame->tf_ebp);
1049         printf("code segment            = base 0x%x, limit 0x%x, type 0x%x\n",
1050                softseg.ssd_base, softseg.ssd_limit, softseg.ssd_type);
1051         printf("                        = DPL %d, pres %d, def32 %d, gran %d\n",
1052                softseg.ssd_dpl, softseg.ssd_p, softseg.ssd_def32,
1053                softseg.ssd_gran);
1054         printf("processor eflags        = ");
1055         if (frame->tf_eflags & PSL_T)
1056                 printf("trace trap, ");
1057         if (frame->tf_eflags & PSL_I)
1058                 printf("interrupt enabled, ");
1059         if (frame->tf_eflags & PSL_NT)
1060                 printf("nested task, ");
1061         if (frame->tf_eflags & PSL_RF)
1062                 printf("resume, ");
1063         if (frame->tf_eflags & PSL_VM)
1064                 printf("vm86, ");
1065         printf("IOPL = %d\n", (frame->tf_eflags & PSL_IOPL) >> 12);
1066         printf("current process         = ");
1067         if (curproc) {
1068                 printf("%lu (%s)\n",
1069                     (u_long)curproc->p_pid, curproc->p_comm ?
1070                     curproc->p_comm : "");
1071         } else {
1072                 printf("Idle\n");
1073         }
1074         printf("current thread          = pri %d ", curthread->td_pri);
1075         if (curthread->td_pri >= TDPRI_CRIT)
1076                 printf("(CRIT)");
1077         printf("\n");
1078         printf("interrupt mask          = ");
1079         if ((curthread->td_cpl & net_imask) == net_imask)
1080                 printf("net ");
1081         if ((curthread->td_cpl & tty_imask) == tty_imask)
1082                 printf("tty ");
1083         if ((curthread->td_cpl & bio_imask) == bio_imask)
1084                 printf("bio ");
1085         if ((curthread->td_cpl & cam_imask) == cam_imask)
1086                 printf("cam ");
1087         if (curthread->td_cpl == 0)
1088                 printf("none");
1089 #ifdef SMP
1090 /**
1091  *  XXX FIXME:
1092  *      we probably SHOULD have stopped the other CPUs before now!
1093  *      another CPU COULD have been touching cpl at this moment...
1094  */
1095         printf(" <- SMP: XXX");
1096 #endif
1097         printf("\n");
1098
1099 #ifdef KDB
1100         if (kdb_trap(&psl))
1101                 return;
1102 #endif
1103 #ifdef DDB
1104         if ((debugger_on_panic || db_active) && kdb_trap(type, code, frame))
1105                 return;
1106 #endif
1107         printf("trap number             = %d\n", type);
1108         if (type <= MAX_TRAP_MSG)
1109                 panic("%s", trap_msg[type]);
1110         else
1111                 panic("unknown/reserved trap");
1112 }
1113
1114 /*
1115  * Double fault handler. Called when a fault occurs while writing
1116  * a frame for a trap/exception onto the stack. This usually occurs
1117  * when the stack overflows (such is the case with infinite recursion,
1118  * for example).
1119  *
1120  * XXX Note that the current PTD gets replaced by IdlePTD when the
1121  * task switch occurs. This means that the stack that was active at
1122  * the time of the double fault is not available at <kstack> unless
1123  * the machine was idle when the double fault occurred. The downside
1124  * of this is that "trace <ebp>" in ddb won't work.
1125  */
1126 void
1127 dblfault_handler()
1128 {
1129         struct mdglobaldata *gd = mdcpu;
1130
1131         printf("\nFatal double fault:\n");
1132         printf("eip = 0x%x\n", gd->gd_common_tss.tss_eip);
1133         printf("esp = 0x%x\n", gd->gd_common_tss.tss_esp);
1134         printf("ebp = 0x%x\n", gd->gd_common_tss.tss_ebp);
1135 #ifdef SMP
1136         /* three seperate prints in case of a trap on an unmapped page */
1137         printf("mp_lock = %08x; ", mp_lock);
1138         printf("cpuid = %d; ", mycpu->gd_cpuid);
1139         printf("lapic.id = %08x\n", lapic.id);
1140 #endif
1141         panic("double fault");
1142 }
1143
1144 /*
1145  * Compensate for 386 brain damage (missing URKR).
1146  * This is a little simpler than the pagefault handler in trap() because
1147  * it the page tables have already been faulted in and high addresses
1148  * are thrown out early for other reasons.
1149  */
1150 int trapwrite(addr)
1151         unsigned addr;
1152 {
1153         struct proc *p;
1154         vm_offset_t va;
1155         struct vmspace *vm;
1156         int rv;
1157
1158         va = trunc_page((vm_offset_t)addr);
1159         /*
1160          * XXX - MAX is END.  Changed > to >= for temp. fix.
1161          */
1162         if (va >= VM_MAXUSER_ADDRESS)
1163                 return (1);
1164
1165         p = curproc;
1166         vm = p->p_vmspace;
1167
1168         ++p->p_lock;
1169
1170         if (!grow_stack (p, va)) {
1171                 --p->p_lock;
1172                 return (1);
1173         }
1174
1175         /*
1176          * fault the data page
1177          */
1178         rv = vm_fault(&vm->vm_map, va, VM_PROT_WRITE, VM_FAULT_DIRTY);
1179
1180         --p->p_lock;
1181
1182         if (rv != KERN_SUCCESS)
1183                 return 1;
1184
1185         return (0);
1186 }
1187
1188 /*
1189  *      syscall2 -      MP aware system call request C handler
1190  *
1191  *      A system call is essentially treated as a trap except that the
1192  *      MP lock is not held on entry or return.  We are responsible for
1193  *      obtaining the MP lock if necessary and for handling ASTs
1194  *      (e.g. a task switch) prior to return.
1195  *
1196  *      In general, only simple access and manipulation of curproc and
1197  *      the current stack is allowed without having to hold MP lock.
1198  */
1199 void
1200 syscall2(struct trapframe frame)
1201 {
1202         struct thread *td = curthread;
1203         struct proc *p = td->td_proc;
1204         caddr_t params;
1205         int i;
1206         struct sysent *callp;
1207         register_t orig_tf_eflags;
1208         u_quad_t sticks;
1209         int error;
1210         int narg;
1211         u_int code;
1212         union sysunion args;
1213
1214 #ifdef DIAGNOSTIC
1215         if (ISPL(frame.tf_cs) != SEL_UPL) {
1216                 get_mplock();
1217                 panic("syscall");
1218                 /* NOT REACHED */
1219         }
1220 #endif
1221
1222 #ifdef SMP
1223         KASSERT(curthread->td_mpcount == 0, ("badmpcount syscall from %p", (void *)frame.tf_eip));
1224         get_mplock();
1225 #endif
1226         /*
1227          * access non-atomic field from critical section.  p_sticks is
1228          * updated by the clock interrupt.  Also use this opportunity
1229          * to lazy-raise our LWKT priority.
1230          */
1231         userenter(td);
1232         crit_enter_quick(td);
1233         sticks = curthread->td_sticks;
1234         crit_exit_quick(td);
1235
1236         p->p_md.md_regs = &frame;
1237         params = (caddr_t)frame.tf_esp + sizeof(int);
1238         code = frame.tf_eax;
1239         orig_tf_eflags = frame.tf_eflags;
1240
1241         if (p->p_sysent->sv_prepsyscall) {
1242                 /*
1243                  * The prep code is not MP aware.
1244                  */
1245                 (*p->p_sysent->sv_prepsyscall)(&frame, (int *)(&args.nosys.usrmsg + 1), &code, &params);
1246         } else {
1247                 /*
1248                  * Need to check if this is a 32 bit or 64 bit syscall.
1249                  * fuword is MP aware.
1250                  */
1251                 if (code == SYS_syscall) {
1252                         /*
1253                          * Code is first argument, followed by actual args.
1254                          */
1255                         code = fuword(params);
1256                         params += sizeof(int);
1257                 } else if (code == SYS___syscall) {
1258                         /*
1259                          * Like syscall, but code is a quad, so as to maintain
1260                          * quad alignment for the rest of the arguments.
1261                          */
1262                         code = fuword(params);
1263                         params += sizeof(quad_t);
1264                 }
1265         }
1266
1267         if (p->p_sysent->sv_mask)
1268                 code &= p->p_sysent->sv_mask;
1269
1270         if (code >= p->p_sysent->sv_size)
1271                 callp = &p->p_sysent->sv_table[0];
1272         else
1273                 callp = &p->p_sysent->sv_table[code];
1274
1275         narg = callp->sy_narg & SYF_ARGMASK;
1276
1277         /*
1278          * copyin is MP aware, but the tracing code is not
1279          */
1280         if (params && (i = narg * sizeof(register_t)) &&
1281             (error = copyin(params, (caddr_t)(&args.nosys.usrmsg + 1), (u_int)i))) {
1282 #ifdef KTRACE
1283                 if (KTRPOINT(td, KTR_SYSCALL))
1284                         ktrsyscall(p->p_tracep, code, narg, (void *)(&args.nosys.usrmsg + 1));
1285 #endif
1286                 goto bad;
1287         }
1288
1289 #if 0
1290         /*
1291          * Try to run the syscall without the MP lock if the syscall
1292          * is MP safe.  We have to obtain the MP lock no matter what if 
1293          * we are ktracing
1294          */
1295         if ((callp->sy_narg & SYF_MPSAFE) == 0) {
1296                 get_mplock();
1297                 have_mplock = 1;
1298         }
1299 #endif
1300
1301 #ifdef KTRACE
1302         if (KTRPOINT(td, KTR_SYSCALL)) {
1303                 ktrsyscall(p->p_tracep, code, narg, (void *)(&args.nosys.usrmsg + 1));
1304         }
1305 #endif
1306         lwkt_initmsg(&args.lmsg, &td->td_msgport, code);
1307         args.sysmsg_fds[0] = 0;
1308         args.sysmsg_fds[1] = frame.tf_edx;
1309
1310         STOPEVENT(p, S_SCE, narg);      /* MP aware */
1311
1312         error = (*callp->sy_call)(&args);
1313
1314         /*
1315          * MP SAFE (we may or may not have the MP lock at this point)
1316          */
1317         switch (error) {
1318         case 0:
1319                 /*
1320                  * Reinitialize proc pointer `p' as it may be different
1321                  * if this is a child returning from fork syscall.
1322                  */
1323                 p = curproc;
1324                 frame.tf_eax = args.sysmsg_fds[0];
1325                 frame.tf_edx = args.sysmsg_fds[1];
1326                 frame.tf_eflags &= ~PSL_C;
1327                 break;
1328         case ERESTART:
1329                 /*
1330                  * Reconstruct pc, assuming lcall $X,y is 7 bytes,
1331                  * int 0x80 is 2 bytes. We saved this in tf_err.
1332                  */
1333                 frame.tf_eip -= frame.tf_err;
1334                 break;
1335         case EJUSTRETURN:
1336                 break;
1337         case EASYNC:
1338                 panic("Unexpected EASYNC return value (for now)");
1339         default:
1340 bad:
1341                 if (p->p_sysent->sv_errsize) {
1342                         if (error >= p->p_sysent->sv_errsize)
1343                                 error = -1;     /* XXX */
1344                         else
1345                                 error = p->p_sysent->sv_errtbl[error];
1346                 }
1347                 frame.tf_eax = error;
1348                 frame.tf_eflags |= PSL_C;
1349                 break;
1350         }
1351
1352         /*
1353          * Traced syscall.  trapsignal() is not MP aware.
1354          */
1355         if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
1356                 frame.tf_eflags &= ~PSL_T;
1357                 trapsignal(p, SIGTRAP, 0);
1358         }
1359
1360         /*
1361          * Handle reschedule and other end-of-syscall issues
1362          */
1363         userret(p, &frame, sticks);
1364
1365 #ifdef KTRACE
1366         if (KTRPOINT(td, KTR_SYSRET)) {
1367                 ktrsysret(p->p_tracep, code, error, args.sysmsg_result);
1368         }
1369 #endif
1370
1371         /*
1372          * This works because errno is findable through the
1373          * register set.  If we ever support an emulation where this
1374          * is not the case, this code will need to be revisited.
1375          */
1376         STOPEVENT(p, S_SCX, code);
1377
1378         userexit(p);
1379 #ifdef SMP
1380         /*
1381          * Release the MP lock if we had to get it
1382          */
1383         KASSERT(curthread->td_mpcount == 1, ("badmpcount syscall from %p", (void *)frame.tf_eip));
1384         rel_mplock();
1385 #endif
1386 }
1387
1388 /*
1389  *      sendsys2 -      MP aware system message request C handler
1390  */
1391 void
1392 sendsys2(struct trapframe frame)
1393 {
1394         struct globaldata *gd;
1395         struct thread *td = curthread;
1396         struct proc *p = td->td_proc;
1397         register_t orig_tf_eflags;
1398         struct sysent *callp;
1399         union sysunion *sysun;
1400         lwkt_msg_t umsg;
1401         u_quad_t sticks;
1402         int error;
1403         int narg;
1404         u_int code = 0;
1405         int msgsize;
1406         int result;
1407
1408 #ifdef DIAGNOSTIC
1409         if (ISPL(frame.tf_cs) != SEL_UPL) {
1410                 get_mplock();
1411                 panic("syscall");
1412                 /* NOT REACHED */
1413         }
1414 #endif
1415
1416 #ifdef SMP
1417         KASSERT(curthread->td_mpcount == 0, ("badmpcount syscall from %p", (void *)frame.tf_eip));
1418         get_mplock();
1419 #endif
1420         /*
1421          * access non-atomic field from critical section.  p_sticks is
1422          * updated by the clock interrupt.  Also use this opportunity
1423          * to lazy-raise our LWKT priority.
1424          */
1425         userenter(td);
1426         crit_enter_quick(td);
1427         sticks = curthread->td_sticks;
1428         crit_exit_quick(td);
1429
1430         p->p_md.md_regs = &frame;
1431         orig_tf_eflags = frame.tf_eflags;
1432         result = 0;
1433
1434         /*
1435          * Handle the waitport/waitmsg/checkport/checkmsg case
1436          *
1437          * YYY MOVE THIS TO INT 0x82!  We don't really need to combine it
1438          * with sendsys().
1439          */
1440         if ((msgsize = frame.tf_edx) <= 0) {
1441                 if (frame.tf_ecx) {
1442                         printf("waitmsg/checkmsg not yet supported: %08x\n",
1443                                 frame.tf_ecx);
1444                         error = ENOTSUP;
1445                         goto bad2;
1446                 }
1447                 if (frame.tf_eax) {
1448                         printf("waitport/checkport only the default port is supported at the moment\n");
1449                         error = ENOTSUP;
1450                         goto bad2;
1451                 }
1452                 switch(msgsize) {
1453                 case 0:
1454                         /*
1455                          * Wait on port for message
1456                          */
1457                         sysun = lwkt_getport(&td->td_msgport);
1458                         /* XXX block */
1459                         break;
1460                 case -1:
1461                         /*
1462                          * Test port for message
1463                          */
1464                         sysun = lwkt_getport(&td->td_msgport);
1465                         break;
1466                 default:
1467                         error = ENOSYS;
1468                         goto bad2;
1469                 }
1470                 if (sysun) {
1471                         gd = td->td_gd;
1472                         umsg = sysun->lmsg.opaque.ms_umsg;
1473                         frame.tf_eax = (register_t)umsg;
1474                         if (sysun->lmsg.ms_cleanupmsg)
1475                                 sysun->lmsg.ms_cleanupmsg(&td->td_msgport, &sysun->lmsg);
1476                         atomic_add_int_nonlocked(&td->td_msgport.mp_refs, -1);
1477                         sysun->nosys.usrmsg.umsg.u.ms_fds[0] = sysun->lmsg.u.ms_fds[0];
1478                         sysun->nosys.usrmsg.umsg.u.ms_fds[1] = sysun->lmsg.u.ms_fds[1];
1479                         sysun->nosys.usrmsg.umsg.ms_error = sysun->lmsg.ms_error;
1480                         error = sysun->lmsg.ms_error;
1481                         result = sysun->lmsg.u.ms_fds[0]; /* for ktrace */
1482                         if (error != 0 || code != SYS_execve) {
1483                                 error = copyout(
1484                                             &sysun->nosys.usrmsg.umsg.ms_copyout_start,
1485                                             &umsg->ms_copyout_start,
1486                                             ms_copyout_size);
1487                         }
1488                         crit_enter_quick(td);
1489                         sysun->lmsg.opaque.ms_sysunnext = gd->gd_freesysun;
1490                         gd->gd_freesysun = sysun;
1491                         crit_exit_quick(td);
1492                 } else {
1493                         frame.tf_eax = 0;
1494                 }
1495                 frame.tf_edx = 0;
1496                 code = 0;
1497                 error = 0;
1498                 goto good;
1499         }
1500
1501         /*
1502          * Extract the system call message.  If msgsize is zero we are 
1503          * blocking on a message and/or message port.  If msgsize is -1 
1504          * we are testing a message for completion or a message port for
1505          * activity.
1506          *
1507          * The userland system call message size includes the size of the
1508          * userland lwkt_msg plus arguments.  We load it into the userland
1509          * portion of our sysunion structure then we initialize the kerneland
1510          * portion and go.
1511          */
1512
1513         /*
1514          * Bad message size
1515          */
1516         if (msgsize < sizeof(struct lwkt_msg) ||
1517             msgsize > sizeof(union sysunion) - sizeof(union sysmsg)
1518         ) {
1519                 error = ENOSYS;
1520                 goto bad2;
1521         }
1522
1523         /*
1524          * Obtain a sysun from our per-cpu cache or allocate a new one.  Use
1525          * the opaque field to store the original (user) message pointer.
1526          * A critical section is necessary to interlock against interrupts
1527          * returning system messages to the thread cache.
1528          */
1529         gd = td->td_gd;
1530         crit_enter_quick(td);
1531         if ((sysun = gd->gd_freesysun) != NULL) {
1532                 gd->gd_freesysun = sysun->lmsg.opaque.ms_sysunnext;
1533                 crit_exit_quick(td);
1534         } else {
1535                 crit_exit_quick(td);
1536                 sysun = malloc(sizeof(union sysunion), M_SYSMSG, M_WAITOK);
1537         }
1538         atomic_add_int_nonlocked(&td->td_msgport.mp_refs, 1);
1539
1540         /*
1541          * Copy the user request into the kernel copy of the user request.
1542          */
1543         umsg = (void *)frame.tf_ecx;
1544         error = copyin(umsg, &sysun->nosys.usrmsg, msgsize);
1545         if (error)
1546                 goto bad1;
1547         if ((sysun->nosys.usrmsg.umsg.ms_flags & MSGF_ASYNC) &&
1548             (error = suser(td)) != 0
1549         ) {
1550                 goto bad1;
1551         }
1552
1553         /*
1554          * Initialize the kernel message from the copied-in data and
1555          * pull in appropriate flags from the userland message.
1556          */
1557         lwkt_initmsg(&sysun->lmsg, &td->td_msgport, 
1558             sysun->nosys.usrmsg.umsg.ms_cmd);
1559         sysun->lmsg.opaque.ms_umsg = umsg;
1560         sysun->lmsg.ms_flags |= sysun->nosys.usrmsg.umsg.ms_flags & MSGF_ASYNC;
1561
1562         /*
1563          * Extract the system call number, lookup the system call, and
1564          * set the default return value.
1565          */
1566         code = (u_int)sysun->lmsg.ms_cmd;
1567         if (code >= p->p_sysent->sv_size) {
1568                 error = ENOSYS;
1569                 goto bad1;
1570         }
1571
1572         callp = &p->p_sysent->sv_table[code];
1573
1574         narg = (msgsize - sizeof(struct lwkt_msg)) / sizeof(register_t);
1575
1576 #ifdef KTRACE
1577         if (KTRPOINT(td, KTR_SYSCALL)) {
1578                 ktrsyscall(p->p_tracep, code, narg, (void *)(&sysun->nosys.usrmsg + 1));
1579         }
1580 #endif
1581         sysun->lmsg.u.ms_fds[0] = 0;
1582         sysun->lmsg.u.ms_fds[1] = 0;
1583
1584         STOPEVENT(p, S_SCE, narg);      /* MP aware */
1585
1586         /*
1587          * Make the system call.  An error code is always returned, results
1588          * are copied back via ms_result32 or ms_result64.  YYY temporary
1589          * stage copy p_retval[] into ms_result32/64
1590          *
1591          * NOTE!  XXX if this is a child returning from a fork curproc
1592          * might be different.  YYY huh? a child returning from a fork
1593          * should never 'return' from this call, it should go right to the
1594          * fork_trampoline function.
1595          */
1596         error = (*callp->sy_call)(sysun);
1597         gd = td->td_gd; /* RELOAD, might have switched cpus */
1598
1599 bad1:
1600         /*
1601          * If a synchronous return copy p_retval to ms_result64 and return
1602          * the sysmsg to the free pool.
1603          *
1604          * YYY Don't writeback message if execve() YYY
1605          */
1606         if (error != EASYNC) {
1607                 atomic_add_int_nonlocked(&td->td_msgport.mp_refs, -1);
1608                 sysun->nosys.usrmsg.umsg.u.ms_fds[0] = sysun->lmsg.u.ms_fds[0];
1609                 sysun->nosys.usrmsg.umsg.u.ms_fds[1] = sysun->lmsg.u.ms_fds[1];
1610                 result = sysun->nosys.usrmsg.umsg.u.ms_fds[0]; /* for ktrace */
1611                 if (error != 0 || code != SYS_execve) {
1612                         int error2;
1613                         error2 = copyout(&sysun->nosys.usrmsg.umsg.ms_copyout_start,
1614                                         &umsg->ms_copyout_start,
1615                                         ms_copyout_size);
1616                         if (error == 0)
1617                                 error2 = error;
1618                 }
1619                 crit_enter_quick(td);
1620                 sysun->lmsg.opaque.ms_sysunnext = gd->gd_freesysun;
1621                 gd->gd_freesysun = sysun;
1622                 crit_exit_quick(td);
1623         }
1624 bad2:
1625         frame.tf_eax = error;
1626 good:
1627
1628         /*
1629          * Traced syscall.  trapsignal() is not MP aware.
1630          */
1631         if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
1632                 frame.tf_eflags &= ~PSL_T;
1633                 trapsignal(p, SIGTRAP, 0);
1634         }
1635
1636         /*
1637          * Handle reschedule and other end-of-syscall issues
1638          */
1639         userret(p, &frame, sticks);
1640
1641 #ifdef KTRACE
1642         if (KTRPOINT(td, KTR_SYSRET)) {
1643                 ktrsysret(p->p_tracep, code, error, result);
1644         }
1645 #endif
1646
1647         /*
1648          * This works because errno is findable through the
1649          * register set.  If we ever support an emulation where this
1650          * is not the case, this code will need to be revisited.
1651          */
1652         STOPEVENT(p, S_SCX, code);
1653
1654         userexit(p);
1655 #ifdef SMP
1656         /*
1657          * Release the MP lock if we had to get it
1658          */
1659         KASSERT(curthread->td_mpcount == 1, ("badmpcount syscall from %p", (void *)frame.tf_eip));
1660         rel_mplock();
1661 #endif
1662 }
1663
1664 /*
1665  * Simplified back end of syscall(), used when returning from fork()
1666  * directly into user mode.  MP lock is held on entry and should be
1667  * released on return.  This code will return back into the fork
1668  * trampoline code which then runs doreti.
1669  */
1670 void
1671 fork_return(p, frame)
1672         struct proc *p;
1673         struct trapframe frame;
1674 {
1675         frame.tf_eax = 0;               /* Child returns zero */
1676         frame.tf_eflags &= ~PSL_C;      /* success */
1677         frame.tf_edx = 1;
1678
1679         userret(p, &frame, 0);
1680 #ifdef KTRACE
1681         if (KTRPOINT(p->p_thread, KTR_SYSRET))
1682                 ktrsysret(p->p_tracep, SYS_fork, 0, 0);
1683 #endif
1684         p->p_flag |= P_PASSIVE_ACQ;
1685         userexit(p);
1686         p->p_flag &= ~P_PASSIVE_ACQ;
1687 #ifdef SMP
1688         KKASSERT(curthread->td_mpcount == 1);
1689         rel_mplock();
1690 #endif
1691 }
1692