Commit a0816e18 authored by Brian Gerst's avatar Brian Gerst Committed by Linus Torvalds

[PATCH] Cleanup F00F bug code

This changes the F00F bug workaround code to use the fixmap facilities
instead of touching the page tables directly.  It also removes the
assumption that only 686's don't have the bug.  I have confirmation that
the patch works on buggy pentiums. 
parent 779f1643
...@@ -41,6 +41,7 @@ if [ "$CONFIG_M386" = "y" ]; then ...@@ -41,6 +41,7 @@ if [ "$CONFIG_M386" = "y" ]; then
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
define_bool CONFIG_X86_PPRO_FENCE y define_bool CONFIG_X86_PPRO_FENCE y
define_bool CONFIG_X86_F00F_BUG y
else else
define_bool CONFIG_X86_WP_WORKS_OK y define_bool CONFIG_X86_WP_WORKS_OK y
define_bool CONFIG_X86_INVLPG y define_bool CONFIG_X86_INVLPG y
...@@ -56,12 +57,14 @@ if [ "$CONFIG_M486" = "y" ]; then ...@@ -56,12 +57,14 @@ if [ "$CONFIG_M486" = "y" ]; then
define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_USE_STRING_486 y
define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_ALIGNMENT_16 y
define_bool CONFIG_X86_PPRO_FENCE y define_bool CONFIG_X86_PPRO_FENCE y
define_bool CONFIG_X86_F00F_BUG y
fi fi
if [ "$CONFIG_M586" = "y" ]; then if [ "$CONFIG_M586" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_int CONFIG_X86_L1_CACHE_SHIFT 5
define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_USE_STRING_486 y
define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_ALIGNMENT_16 y
define_bool CONFIG_X86_PPRO_FENCE y define_bool CONFIG_X86_PPRO_FENCE y
define_bool CONFIG_X86_F00F_BUG y
fi fi
if [ "$CONFIG_M586TSC" = "y" ]; then if [ "$CONFIG_M586TSC" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_int CONFIG_X86_L1_CACHE_SHIFT 5
...@@ -69,6 +72,7 @@ if [ "$CONFIG_M586TSC" = "y" ]; then ...@@ -69,6 +72,7 @@ if [ "$CONFIG_M586TSC" = "y" ]; then
define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_ALIGNMENT_16 y
define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_PPRO_FENCE y define_bool CONFIG_X86_PPRO_FENCE y
define_bool CONFIG_X86_F00F_BUG y
fi fi
if [ "$CONFIG_M586MMX" = "y" ]; then if [ "$CONFIG_M586MMX" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_int CONFIG_X86_L1_CACHE_SHIFT 5
...@@ -77,6 +81,7 @@ if [ "$CONFIG_M586MMX" = "y" ]; then ...@@ -77,6 +81,7 @@ if [ "$CONFIG_M586MMX" = "y" ]; then
define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_PPRO_FENCE y define_bool CONFIG_X86_PPRO_FENCE y
define_bool CONFIG_X86_F00F_BUG y
fi fi
if [ "$CONFIG_M686" = "y" ]; then if [ "$CONFIG_M686" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_int CONFIG_X86_L1_CACHE_SHIFT 5
......
...@@ -1961,13 +1961,10 @@ extern void trap_init_f00f_bug(void); ...@@ -1961,13 +1961,10 @@ extern void trap_init_f00f_bug(void);
static void __init init_intel(struct cpuinfo_x86 *c) static void __init init_intel(struct cpuinfo_x86 *c)
{ {
#ifndef CONFIG_M686
static int f00f_workaround_enabled = 0;
#endif
char *p = NULL; char *p = NULL;
unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
#ifndef CONFIG_M686 #ifdef CONFIG_X86_F00F_BUG
/* /*
* All current models of Pentium and Pentium with MMX technology CPUs * All current models of Pentium and Pentium with MMX technology CPUs
* have the F0 0F bug, which lets nonpriviledged users lock up the system. * have the F0 0F bug, which lets nonpriviledged users lock up the system.
...@@ -1975,6 +1972,8 @@ static void __init init_intel(struct cpuinfo_x86 *c) ...@@ -1975,6 +1972,8 @@ static void __init init_intel(struct cpuinfo_x86 *c)
*/ */
c->f00f_bug = 0; c->f00f_bug = 0;
if ( c->x86 == 5 ) { if ( c->x86 == 5 ) {
static int f00f_workaround_enabled = 0;
c->f00f_bug = 1; c->f00f_bug = 1;
if ( !f00f_workaround_enabled ) { if ( !f00f_workaround_enabled ) {
trap_init_f00f_bug(); trap_init_f00f_bug();
......
...@@ -775,35 +775,17 @@ asmlinkage void math_emulate(long arg) ...@@ -775,35 +775,17 @@ asmlinkage void math_emulate(long arg)
#endif /* CONFIG_MATH_EMULATION */ #endif /* CONFIG_MATH_EMULATION */
#ifndef CONFIG_M686 #ifdef CONFIG_X86_F00F_BUG
void __init trap_init_f00f_bug(void) void __init trap_init_f00f_bug(void)
{ {
unsigned long page; __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
pgd_t * pgd;
pmd_t * pmd;
pte_t * pte;
/*
* Allocate a new page in virtual address space,
* move the IDT into it and write protect this page.
*/
page = (unsigned long) vmalloc(PAGE_SIZE);
pgd = pgd_offset(&init_mm, page);
pmd = pmd_offset(pgd, page);
pte = pte_offset_kernel(pmd, page);
__free_page(pte_page(*pte));
*pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO);
/*
* Not that any PGE-capable kernel should have the f00f bug ...
*/
__flush_tlb_all();
/* /*
* "idt" is magic - it overlaps the idt_descr * "idt" is magic - it overlaps the idt_descr
* variable so that updating idt will automatically * variable so that updating idt will automatically
* update the idt descriptor.. * update the idt descriptor..
*/ */
idt = (struct desc_struct *)page; idt = (struct desc_struct *) fix_to_virt(FIX_F00F_IDT);
__asm__ __volatile__("lidt %0": "=m" (idt_descr)); __asm__ __volatile__("lidt %0": "=m" (idt_descr));
} }
#endif #endif
......
...@@ -282,6 +282,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -282,6 +282,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
return; return;
} }
#ifdef CONFIG_X86_F00F_BUG
/* /*
* Pentium F0 0F C7 C8 bug workaround. * Pentium F0 0F C7 C8 bug workaround.
*/ */
...@@ -295,6 +296,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -295,6 +296,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
return; return;
} }
} }
#endif
no_context: no_context:
/* Are we prepared to handle this kernel fault? */ /* Are we prepared to handle this kernel fault? */
......
...@@ -61,6 +61,9 @@ enum fixed_addresses { ...@@ -61,6 +61,9 @@ enum fixed_addresses {
FIX_LI_PCIA, /* Lithium PCI Bridge A */ FIX_LI_PCIA, /* Lithium PCI Bridge A */
FIX_LI_PCIB, /* Lithium PCI Bridge B */ FIX_LI_PCIB, /* Lithium PCI Bridge B */
#endif #endif
#ifdef CONFIG_X86_F00F_BUG
FIX_F00F_IDT, /* Virtual mapping for IDT */
#endif
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment