diff options
Diffstat (limited to 'sys/kern/subr_trap.c')
-rw-r--r-- | sys/kern/subr_trap.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index e53b015..9bebd7e 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.114 1997/11/06 19:28:09 phk Exp $ + * $Id: trap.c,v 1.115 1997/11/24 13:25:37 bde Exp $ */ /* @@ -142,6 +142,11 @@ static char *trap_msg[] = { static void userret __P((struct proc *p, struct trapframe *frame, u_quad_t oticks)); +#ifndef NO_F00F_HACK +extern struct gate_descriptor *t_idt; +extern int has_f00f_bug; +#endif + static inline void userret(p, frame, oticks) struct proc *p; @@ -211,6 +216,9 @@ trap(frame) u_long eva; #endif +#ifndef NO_F00F_HACK +restart: +#endif type = frame.tf_trapno; code = frame.tf_err; @@ -276,6 +284,10 @@ trap(frame) i = trap_pfault(&frame, TRUE); if (i == -1) return; +#ifndef NO_F00F_HACK + if (i == -2) + goto restart; +#endif if (i == 0) goto out; @@ -642,7 +654,18 @@ trap_pfault(frame, usermode) if (va >= KERNBASE) { /* * Don't allow user-mode faults in kernel address space. + * An exception: if the faulting address is the invalid + * instruction entry in the IDT, then the Intel Pentium + * F00F bug workaround was triggered, and we need to + * treat it is as an illegal instruction, and not a page + * fault. */ +#ifndef NO_F00F_HACK + if ((eva == (unsigned int)&t_idt[6]) && has_f00f_bug) { + frame->tf_trapno = T_PRIVINFLT; + return -2; + } +#endif if (usermode) goto nogo; |