f00f.patch (fwd)

From: Ejovi (Joey) N. (joeyat_private)
Date: Fri Dec 19 1997 - 10:45:07 PST

  • Next message: Ron Holt: "Re: CERT Advisory CA-97.28 - Teardrop_Land"

    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 *));
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:37:09 PDT