aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-08-17 04:19:00 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-17 07:28:25 -0400
commite412cd257e0d51e0ecbb89f50953835b5a0681b2 (patch)
tree42b67c3a392511b4d2b2e6fc05008566246dc35b /arch/x86
parentc7f6fa44115d401e89db730f357629d39f8e4ba6 (diff)
x86, mce: Don't initialize MCEs on unknown CPUs
An older test-box started hanging at the following point during bootup: [ 0.022996] Mount-cache hash table entries: 512 [ 0.024996] Initializing cgroup subsys debug [ 0.025996] Initializing cgroup subsys cpuacct [ 0.026995] Initializing cgroup subsys devices [ 0.027995] Initializing cgroup subsys freezer [ 0.028995] mce: CPU supports 5 MCE banks I've bisected it down to commit 4efc0670 ("x86, mce: use 64bit machine check code on 32bit"), which utilizes the MCE code on 32-bit systems too. The problem is caused by this detail in my config: # CONFIG_CPU_SUP_INTEL is not set This disables the quirks in mce_cpu_quirks() but still enables MCE support - which then hangs due to the missing quirk workaround needed on this CPU: if (c->x86 == 6 && c->x86_model < 0x1A && banks > 0) mce_banks[0].init = 0; The safe solution is to not initialize MCEs if we dont know on what CPU we are running (or if that CPU's support code got disabled in the config). Also be a bit more defensive on 32-bit systems: dont do a boot-time dump of pending MCEs not just on the specific system that we found a problem with (Pentium-M), but earlier ones as well. Now this problem is probably not common and disabling CPU support is rare - but still being more defensive in something we turned on for a wide range of CPUs is prudent. Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> LKML-Reference: Message-ID: <4A88E3E4.40506@jp.fujitsu.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index a0c2910d96a0..01213048f62f 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1226,8 +1226,13 @@ static void mce_init(void)
1226} 1226}
1227 1227
1228/* Add per CPU specific workarounds here */ 1228/* Add per CPU specific workarounds here */
1229static void mce_cpu_quirks(struct cpuinfo_x86 *c) 1229static int mce_cpu_quirks(struct cpuinfo_x86 *c)
1230{ 1230{
1231 if (c->x86_vendor == X86_VENDOR_UNKNOWN) {
1232 pr_info("MCE: unknown CPU type - not enabling MCE support.\n");
1233 return -EOPNOTSUPP;
1234 }
1235
1231 /* This should be disabled by the BIOS, but isn't always */ 1236 /* This should be disabled by the BIOS, but isn't always */
1232 if (c->x86_vendor == X86_VENDOR_AMD) { 1237 if (c->x86_vendor == X86_VENDOR_AMD) {
1233 if (c->x86 == 15 && banks > 4) { 1238 if (c->x86 == 15 && banks > 4) {
@@ -1274,14 +1279,19 @@ static void mce_cpu_quirks(struct cpuinfo_x86 *c)
1274 monarch_timeout < 0) 1279 monarch_timeout < 0)
1275 monarch_timeout = USEC_PER_SEC; 1280 monarch_timeout = USEC_PER_SEC;
1276 1281
1277 /* There are also broken BIOSes on some Pentium M systems. */ 1282 /*
1278 if (c->x86 == 6 && c->x86_model == 13 && mce_bootlog < 0) 1283 * There are also broken BIOSes on some Pentium M and
1284 * earlier systems:
1285 */
1286 if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0)
1279 mce_bootlog = 0; 1287 mce_bootlog = 0;
1280 } 1288 }
1281 if (monarch_timeout < 0) 1289 if (monarch_timeout < 0)
1282 monarch_timeout = 0; 1290 monarch_timeout = 0;
1283 if (mce_bootlog != 0) 1291 if (mce_bootlog != 0)
1284 mce_panic_timeout = 30; 1292 mce_panic_timeout = 30;
1293
1294 return 0;
1285} 1295}
1286 1296
1287static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c) 1297static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c)
@@ -1342,11 +1352,10 @@ void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
1342 if (!mce_available(c)) 1352 if (!mce_available(c))
1343 return; 1353 return;
1344 1354
1345 if (mce_cap_init() < 0) { 1355 if (mce_cap_init() < 0 || mce_cpu_quirks(c) < 0) {
1346 mce_disabled = 1; 1356 mce_disabled = 1;
1347 return; 1357 return;
1348 } 1358 }
1349 mce_cpu_quirks(c);
1350 1359
1351 machine_check_vector = do_machine_check; 1360 machine_check_vector = do_machine_check;
1352 1361