Commit d6b75584 authored by Andi Kleen's avatar Andi Kleen Committed by H. Peter Anvin

x86, mce: disable machine checks on offlined CPUs

Impact: Lower priority bug fix

Offlined CPUs could still get machine checks, but the machine check handler
cannot handle them properly, leading to an unconditional crash. Disable
machine checks on CPUs that are going down.
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
parent 5b4408fd
...@@ -906,6 +906,27 @@ static __cpuinit void mce_remove_device(unsigned int cpu) ...@@ -906,6 +906,27 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
cpu_clear(cpu, mce_device_initialized); cpu_clear(cpu, mce_device_initialized);
} }
/* Make sure there are no machine checks on offlined CPUs. */
static void __cpuexit mce_disable_cpu(void *h)
{
int i;
if (!mce_available(&current_cpu_data))
return;
for (i = 0; i < banks; i++)
wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
}
static void __cpuexit mce_reenable_cpu(void *h)
{
int i;
if (!mce_available(&current_cpu_data))
return;
for (i = 0; i < banks; i++)
wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]);
}
/* Get notified when a cpu comes on/off. Be hotplug friendly. */ /* Get notified when a cpu comes on/off. Be hotplug friendly. */
static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu) unsigned long action, void *hcpu)
...@@ -929,11 +950,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, ...@@ -929,11 +950,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN: case CPU_DOWN_PREPARE_FROZEN:
del_timer_sync(t); del_timer_sync(t);
smp_call_function_single(cpu, mce_disable_cpu, NULL, 1);
break; break;
case CPU_DOWN_FAILED: case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN: case CPU_DOWN_FAILED_FROZEN:
t->expires = round_jiffies_relative(jiffies + next_interval); t->expires = round_jiffies_relative(jiffies + next_interval);
add_timer_on(t, cpu); add_timer_on(t, cpu);
smp_call_function_single(cpu, mce_reenable_cpu, NULL, 1);
break; break;
} }
return NOTIFY_OK; return NOTIFY_OK;
......
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