Bugtraq mailing list archives

f00f.patch (fwd)


From: joey () DEVELOPMENT NYCT NET (Ejovi)
Date: Fri, 19 Dec 1997 13:45:07 -0500


The OpenBSD patch for the f00f has been made of avail. for sometime now on
http://www.openbsd.org/ and on the OpenBSD mailing list.
This is a forward of the patch as on the web page.
http://www.openbsd.org/errata.html

Apply by doing
        cd /sys/arch/i386
        patch -p0 < f00f.patch

And then rebuild your kernel.

Index: i386/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/genassym.cf,v
retrieving revision 1.5
diff -u -r1.5 genassym.cf
--- genassym.cf 1997/10/19 06:34:23     1.5
+++ genassym.cf 1997/12/09 05:16:00
@@ -1,4 +1,4 @@
-#      $OpenBSD: genassym.cf,v 1.5 1997/10/19 06:34:23 mickey Exp $
+#      $OpenBSD: genassym.cf,v 1.6 1997/12/09 03:36:39 deraadt Exp $
 #
 # Copyright (c) 1982, 1990 The Regents of the University of California.
 # All rights reserved.
@@ -108,6 +108,8 @@
 define TF_CS           offsetof(struct trapframe, tf_cs)
 define TF_TRAPNO       offsetof(struct trapframe, tf_trapno)
 define TF_EFLAGS       offsetof(struct trapframe, tf_eflags)
+define TF_EIP          offsetof(struct trapframe, tf_eip)
+define TF_ERR          offsetof(struct trapframe, tf_err)

 define FRAMESIZE       sizeof(struct trapframe)

Index: i386/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v
retrieving revision 1.36
diff -u -r1.36 locore.s
--- locore.s    1997/10/22 23:37:12     1.36
+++ locore.s    1997/12/09 05:16:00
@@ -1,4 +1,4 @@
-/*     $OpenBSD: locore.s,v 1.36 1997/10/22 23:37:12 mickey Exp $      */
+/*     $OpenBSD: locore.s,v 1.37 1997/12/09 03:36:39 deraadt Exp $     */
 /*     $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $    */

 /*-
@@ -1931,6 +1931,19 @@
        TRAP(T_STKFLT)
 IDTVEC(prot)
        TRAP(T_PROTFLT)
+#ifdef I586_CPU
+IDTVEC(f00f_redirect)
+       pushl   $T_PAGEFLT
+       INTRENTRY
+       testb   $PGEX_U,TF_ERR(%esp)
+       jnz     calltrap
+       movl    %cr2,%eax
+       subl    _idt,%eax
+       cmpl    $(6*8),%eax
+       jne     calltrap
+       movb    $T_PRIVINFLT,TF_TRAPNO(%esp)
+       jmp     calltrap
+#endif
 IDTVEC(page)
        TRAP(T_PAGEFLT)
 IDTVEC(rsvd)
Index: i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.63
diff -u -r1.63 machdep.c
--- machdep.c   1997/10/28 09:11:35     1.63
+++ machdep.c   1997/12/09 05:16:00
@@ -1,4 +1,4 @@
-/*     $OpenBSD: machdep.c,v 1.63 1997/10/28 09:11:35 niklas Exp $     */
+/*     $OpenBSD: machdep.c,v 1.67 1997/12/09 03:36:40 deraadt Exp $    */
 /*     $NetBSD: machdep.c,v 1.202 1996/05/18 15:54:59 christos Exp $   */

 /*-
@@ -489,6 +489,10 @@
                calibrate_cyclecounter();
                printf(" %d MHz", pentium_mhz);
        }
+       if (!strcmp(cpu_model, "Pentium (GenuineIntel 586-class CPU)")) {
+               fix_f00f();
+               printf("\nCPU: F00F bug workaround installed");
+       }
 #endif
        printf("\n");

@@ -1079,7 +1083,8 @@

 union descriptor gdt[NGDT];
 union descriptor ldt[NLDT];
-struct gate_descriptor idt[NIDT];
+struct gate_descriptor idt_region[NIDT];
+struct gate_descriptor *idt = idt_region;

 extern  struct user *proc0paddr;

@@ -1139,6 +1144,45 @@
        IDTVEC(fpu),     IDTVEC(align),
        IDTVEC(syscall), IDTVEC(osyscall);

+#if defined(I586_CPU)
+extern IDTVEC(f00f_redirect);
+pt_entry_t *pmap_pte __P((pmap_t, vm_offset_t));
+
+int cpu_f00f_bug = 0;
+
+void
+fix_f00f()
+{
+       struct region_descriptor region;
+       vm_offset_t va;
+       pt_entry_t *pte;
+       void *p;
+
+       /* Allocate two new pages */
+       va = kmem_alloc(kernel_map, NBPG*2);
+       p = (void *)(va + NBPG - 7*sizeof(*idt));
+
+       /* Copy over old IDT */
+       bcopy(idt, p, sizeof(idt_region));
+       idt = p;
+
+       /* Fix up paging redirect */
+       setgate(&idt[ 14], &IDTVEC(f00f_redirect), 0, SDT_SYS386TGT,
+               SEL_KPL, GCODE_SEL);
+
+       /* Map first page RO */
+       pte = pmap_pte(pmap_kernel(), va);
+       *pte &= ~PG_RW;
+
+       /* Reload idtr */
+       setregion(&region, idt, sizeof(idt_region) - 1);
+       lidt(&region);
+
+       /* Tell the rest of the world */
+       cpu_f00f_bug = 1;
+}
+#endif
+
 void
 init386(first_avail)
        vm_offset_t first_avail;
@@ -1213,7 +1257,7 @@

        setregion(&region, gdt, sizeof(gdt) - 1);
        lgdt(&region);
-       setregion(&region, idt, sizeof(idt) - 1);
+       setregion(&region, idt, sizeof(idt_region) - 1);
        lidt(&region);

 #if NISA > 0
@@ -1440,8 +1484,8 @@
         * Try to cause a triple fault and watchdog reset by setting the
         * IDT to point to nothing.
         */
-       bzero((caddr_t)idt, sizeof(idt));
-       setregion(&region, idt, sizeof(idt) - 1);
+       bzero((caddr_t)idt, sizeof(idt_region));
+       setregion(&region, idt, sizeof(idt_region) - 1);
        lidt(&region);
        __asm __volatile("divl %0,%1" : : "q" (0), "a" (0));

Index: include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.17
diff -u -r1.17 cpu.h
--- cpu.h       1997/10/25 21:47:27     1.17
+++ cpu.h       1997/12/09 05:16:00
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.17 1997/10/25 21:47:27 mickey Exp $ */
+/*     $OpenBSD: cpu.h,v 1.18 1997/12/09 03:36:41 deraadt Exp $        */
 /*     $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $        */

 /*-
@@ -140,6 +140,10 @@
 extern struct cpu_nameclass i386_cpus[];
 #ifdef I586_CPU
 extern int pentium_mhz;
+
+/* F00F bug fix stuff for pentium cpu */
+extern int cpu_f00f_bug;
+void fix_f00f __P((void));
 #endif

 /* autoconf.c */
Index: include/segments.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/segments.h,v
retrieving revision 1.5
diff -u -r1.5 segments.h
--- segments.h  1997/04/17 03:44:51     1.5
+++ segments.h  1997/12/09 05:16:00
@@ -128,7 +128,8 @@

 #ifdef _KERNEL
 extern union descriptor gdt[], ldt[];
-extern struct gate_descriptor idt[];
+extern struct gate_descriptor idt_region[];
+extern struct gate_descriptor *idt;

 void setgate __P((struct gate_descriptor *, void *, int, int, int, int));
 void setregion __P((struct region_descriptor *, void *, size_t));
Index: isa/isa_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/isa/isa_machdep.c,v
retrieving revision 1.22
diff -u -r1.22 isa_machdep.c
--- isa_machdep.c       1997/09/24 22:28:16     1.22
+++ isa_machdep.c       1997/12/09 05:16:00
@@ -1,4 +1,4 @@
-/*     $OpenBSD: isa_machdep.c,v 1.22 1997/09/24 22:28:16 niklas Exp $ */
+/*     $OpenBSD: isa_machdep.c,v 1.23 1997/12/09 03:36:42 deraadt Exp $
*/
 /*     $NetBSD: isa_machdep.c,v 1.14 1996/05/12 23:06:18 mycroft Exp $ */

 /*-
@@ -62,7 +62,6 @@
 /* default interrupt vector table entries */
 typedef (*vector) __P((void));
 extern vector IDTVEC(intr)[], IDTVEC(fast)[];
-extern struct gate_descriptor idt[];
 void isa_strayintr __P((int));
 void intr_calculatemasks __P((void));
 int fakeintr __P((void *));



Current thread: