Date: Sat, 22 Nov 1997 22:08:00 +0900 From: ohki@gssm.otsuka.tsukuba.ac.jp To: freebsd-bugs@FreeBSD.org Cc: ohki@gssm.otsuka.tsukuba.ac.jp Subject: Re: Pentium f00f problem -- possible fix Message-ID: <199711221308.WAA22851@smr00.gssm.otsuka.tsukuba.ac.jp> In-Reply-To: Your message of "Sat, 22 Nov 97 19:03:16 JST" References: <199711221003.TAA22516@smr00.gssm.otsuka.tsukuba.ac.jp>
next in thread | previous in thread | raw e-mail | index | archive | help
I wrote: > Hi FreeBSD folks > > You might have fixed the problem of newly discovered bug of Pentium. > (code sequence of 0xf0 0x0f 0xc7 0xc8 freezes the system) > > I implemented the recommended solution comes from Intel, > and enclosed context diffs. > It is my pleasure if it helps you. Following is more better (since eliminating CPU-type checking at page fault handler. No efficiency penalty except Pentinum) --- i386/i386/locore.s-ORIG Sat Feb 1 21:10:54 1997 +++ i386/i386/locore.s Sat Nov 22 21:54:29 1997 @@ -99,6 +99,18 @@ */ .data ALIGN_DATA /* just to be sure */ +#if defined(I586_CPU) + /* + * workaround for f00f problem of Pentium + * trap to page fault before the machine hangs + * How can I align to a page boundary precisely? + */ + .globl _idt + .space PAGE_SIZE - 8*7 +_idt: + .space 8*7 /* cause page fault for idt[0] to idt[6] */ + .space PAGE_SIZE +#endif defined(I586_CPU) .globl tmpstk .space 0x2000 /* space for tmpstk - temporary stack */ --- i386/i386/machdep.c-ORIG Thu Apr 3 15:37:31 1997 +++ i386/i386/machdep.c Sat Nov 22 20:17:40 1997 @@ -39,6 +39,7 @@ */ #include "npx.h" +#include "opt_cpu.h" /* XXX */ #include "opt_sysvipc.h" #include "opt_ddb.h" #include "opt_bounce.h" @@ -206,6 +207,10 @@ * Good {morning,afternoon,evening,night}. */ printf(version); +#if defined(I586_CPU) + if (cpu == CPU_586) + printf("Pentium -- workaround for f00f problem enabled!\n"); +#endif defined(I586_CPU) earlysetcpuclass(); startrtclock(); identifycpu(); @@ -930,6 +935,9 @@ IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall), IDTVEC(int0x80_syscall); +#if defined(I586_CPU) +extern inthand_t IDTVEC(page_f00f); +#endif /* defined(I586_CPU) */ void sdtossd(sd, ssd) @@ -1046,6 +1054,14 @@ r_idt.rd_limit = sizeof(idt) - 1; r_idt.rd_base = (int) idt; lidt(&r_idt); +#if defined(I586_CPU) + if (cpu == CPU_586) { + unsigned *pte = (unsigned *)vtopte(idt); + setidt(14, &IDTVEC(page_f00f), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + *pte &= ~PG_V; + printf("Pentium -- enable workaround for f00f problem!\n"); + } +#endif defined(I586_CPU) _default_ldt = GSEL(GLDT_SEL, SEL_KPL); lldt(_default_ldt); --- i386/i386/exception.s-ORIG Mon Aug 12 02:41:23 1996 +++ i386/i386/exception.s Sat Nov 22 21:53:26 1997 @@ -33,6 +33,7 @@ * $Id: exception.s,v 1.19 1996/08/11 17:41:23 davidg Exp $ */ +#include "opt_cpu.h" /* XXX */ #include "npx.h" /* NNPX */ #include "assym.s" /* system defines */ #include <sys/errno.h> /* error return codes */ @@ -111,6 +112,40 @@ TRAP(T_STKFLT) IDTVEC(prot) TRAP(T_PROTFLT) +#if defined(I586_CPU) +#define IDTVECnm(name) __CONCAT(_X,name) +IDTVEC(page_f00f) + /* data segment is not KERNEL ! */ + pushl %eax + movl %cr2,%eax + subl $_idt,%eax + shrl $3,%eax + cmpl $6,%eax + ja 1f + /* + * page fault via accessing idt[0] to idt[6] + * dispatch to them + */ + movl %cs:trp_vec(,%eax,4),%eax + movl %eax,4(%esp) /* holding error code */ + popl %eax + addl $4,%esp /* adjust stack to discard error code */ + jmp *-4(%esp) + ALIGN_TEXT /* do I really need this ? */ + /* order must be the same as in machdep.c */ +trp_vec: + .long IDTVECnm(div) + .long IDTVECnm(dbg) + .long IDTVECnm(nmi) + .long IDTVECnm(bpt) + .long IDTVECnm(ofl) + .long IDTVECnm(bnd) + .long IDTVECnm(ill) +1: + popl %eax + jmp IDTVECnm(page) +#undef IDTVECnm +#endif /* defined(I586_CPU) */ IDTVEC(page) TRAP(T_PAGEFLT) IDTVEC(mchk)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711221308.WAA22851>