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