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