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