diff options
Diffstat (limited to 'arch/x86/kernel/cpu/bugs.c')
-rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 50 |
1 files changed, 20 insertions, 30 deletions
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 170d2f5523b2..c9b58a806e85 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -59,8 +59,12 @@ static void __init check_fpu(void) | |||
59 | return; | 59 | return; |
60 | } | 60 | } |
61 | 61 | ||
62 | /* trap_init() enabled FXSR and company _before_ testing for FP problems here. */ | 62 | /* |
63 | /* Test for the divl bug.. */ | 63 | * trap_init() enabled FXSR and company _before_ testing for FP |
64 | * problems here. | ||
65 | * | ||
66 | * Test for the divl bug.. | ||
67 | */ | ||
64 | __asm__("fninit\n\t" | 68 | __asm__("fninit\n\t" |
65 | "fldl %1\n\t" | 69 | "fldl %1\n\t" |
66 | "fdivl %2\n\t" | 70 | "fdivl %2\n\t" |
@@ -108,10 +112,15 @@ static void __init check_popad(void) | |||
108 | "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " | 112 | "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " |
109 | : "=&a" (res) | 113 | : "=&a" (res) |
110 | : "d" (inp) | 114 | : "d" (inp) |
111 | : "ecx", "edi" ); | 115 | : "ecx", "edi"); |
112 | /* If this fails, it means that any user program may lock the CPU hard. Too bad. */ | 116 | /* |
113 | if (res != 12345678) printk( "Buggy.\n" ); | 117 | * If this fails, it means that any user program may lock the |
114 | else printk( "OK.\n" ); | 118 | * CPU hard. Too bad. |
119 | */ | ||
120 | if (res != 12345678) | ||
121 | printk("Buggy.\n"); | ||
122 | else | ||
123 | printk("OK.\n"); | ||
115 | #endif | 124 | #endif |
116 | } | 125 | } |
117 | 126 | ||
@@ -122,13 +131,7 @@ static void __init check_popad(void) | |||
122 | * (for due to lack of "invlpg" and working WP on a i386) | 131 | * (for due to lack of "invlpg" and working WP on a i386) |
123 | * - In order to run on anything without a TSC, we need to be | 132 | * - In order to run on anything without a TSC, we need to be |
124 | * compiled for a i486. | 133 | * compiled for a i486. |
125 | * - In order to support the local APIC on a buggy Pentium machine, | 134 | */ |
126 | * we need to be compiled with CONFIG_X86_GOOD_APIC disabled, | ||
127 | * which happens implicitly if compiled for a Pentium or lower | ||
128 | * (unless an advanced selection of CPU features is used) as an | ||
129 | * otherwise config implies a properly working local APIC without | ||
130 | * the need to do extra reads from the APIC. | ||
131 | */ | ||
132 | 135 | ||
133 | static void __init check_config(void) | 136 | static void __init check_config(void) |
134 | { | 137 | { |
@@ -137,25 +140,11 @@ static void __init check_config(void) | |||
137 | * i486+ only features! (WP works in supervisor mode and the | 140 | * i486+ only features! (WP works in supervisor mode and the |
138 | * new "invlpg" and "bswap" instructions) | 141 | * new "invlpg" and "bswap" instructions) |
139 | */ | 142 | */ |
140 | #if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_BSWAP) | 143 | #if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || \ |
144 | defined(CONFIG_X86_BSWAP) | ||
141 | if (boot_cpu_data.x86 == 3) | 145 | if (boot_cpu_data.x86 == 3) |
142 | panic("Kernel requires i486+ for 'invlpg' and other features"); | 146 | panic("Kernel requires i486+ for 'invlpg' and other features"); |
143 | #endif | 147 | #endif |
144 | |||
145 | /* | ||
146 | * If we were told we had a good local APIC, check for buggy Pentia, | ||
147 | * i.e. all B steppings and the C2 stepping of P54C when using their | ||
148 | * integrated APIC (see 11AP erratum in "Pentium Processor | ||
149 | * Specification Update"). | ||
150 | */ | ||
151 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC) | ||
152 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL | ||
153 | && cpu_has_apic | ||
154 | && boot_cpu_data.x86 == 5 | ||
155 | && boot_cpu_data.x86_model == 2 | ||
156 | && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) | ||
157 | panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); | ||
158 | #endif | ||
159 | } | 148 | } |
160 | 149 | ||
161 | 150 | ||
@@ -170,6 +159,7 @@ void __init check_bugs(void) | |||
170 | check_fpu(); | 159 | check_fpu(); |
171 | check_hlt(); | 160 | check_hlt(); |
172 | check_popad(); | 161 | check_popad(); |
173 | init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); | 162 | init_utsname()->machine[1] = |
163 | '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); | ||
174 | alternative_instructions(); | 164 | alternative_instructions(); |
175 | } | 165 | } |