aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mcheck/mce_64.c
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2009-02-12 07:39:31 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2009-02-17 18:32:56 -0500
commitd6b75584a3eaab8cb2ab3e8cf90c5e57c1928a85 (patch)
treec7ebdcaed69bf744fb94c783101d9447c89cef54 /arch/x86/kernel/cpu/mcheck/mce_64.c
parent5b4408fdaa62474dd9485cddb9126370d90d4b82 (diff)
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: Andi Kleen <ak@linux.intel.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck/mce_64.c')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index 4e2b1bc5131..1db94c0d5aa 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -906,6 +906,27 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
906 cpu_clear(cpu, mce_device_initialized); 906 cpu_clear(cpu, mce_device_initialized);
907} 907}
908 908
909/* Make sure there are no machine checks on offlined CPUs. */
910static void __cpuexit mce_disable_cpu(void *h)
911{
912 int i;
913
914 if (!mce_available(&current_cpu_data))
915 return;
916 for (i = 0; i < banks; i++)
917 wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
918}
919
920static void __cpuexit mce_reenable_cpu(void *h)
921{
922 int i;
923
924 if (!mce_available(&current_cpu_data))
925 return;
926 for (i = 0; i < banks; i++)
927 wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]);
928}
929
909/* Get notified when a cpu comes on/off. Be hotplug friendly. */ 930/* Get notified when a cpu comes on/off. Be hotplug friendly. */
910static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, 931static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
911 unsigned long action, void *hcpu) 932 unsigned long action, void *hcpu)
@@ -929,11 +950,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
929 case CPU_DOWN_PREPARE: 950 case CPU_DOWN_PREPARE:
930 case CPU_DOWN_PREPARE_FROZEN: 951 case CPU_DOWN_PREPARE_FROZEN:
931 del_timer_sync(t); 952 del_timer_sync(t);
953 smp_call_function_single(cpu, mce_disable_cpu, NULL, 1);
932 break; 954 break;
933 case CPU_DOWN_FAILED: 955 case CPU_DOWN_FAILED:
934 case CPU_DOWN_FAILED_FROZEN: 956 case CPU_DOWN_FAILED_FROZEN:
935 t->expires = round_jiffies_relative(jiffies + next_interval); 957 t->expires = round_jiffies_relative(jiffies + next_interval);
936 add_timer_on(t, cpu); 958 add_timer_on(t, cpu);
959 smp_call_function_single(cpu, mce_reenable_cpu, NULL, 1);
937 break; 960 break;
938 } 961 }
939 return NOTIFY_OK; 962 return NOTIFY_OK;