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>
index | next in thread | previous in thread | raw e-mail
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)
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711221308.WAA22851>
