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