Skip to contentSkip to conversation

Updates to the x86 machine check unification

PATCH Applied Andi Kleen 2 participants 6 messages Aug 5, 2008 – Aug 8, 2008

Subsystems (2)
lore
Share & tools
lore

Andi Kleen

author
#0 lore raw

cover Updates to the x86 machine check unification

Should be applied to the respective x86 topic branch.

- Fix Intel thermal handling broken in earlier merge
- Add old code to the deprecation schedule
- Fix a long standing bug in thermal interrupt handling after suspend to ram
- Revert older bogus patch

-Andi

author
#1 lore raw

PATCH 1/4 MCE: Fix ifdefs for Intel thermal handler

I forgot to switch over some ifdefs during the machine check unification. This broke the Intel thermal handler on 32bit with the new machine check code. Fix this.

This patch should be ideally folded into the earlier conversion one ("Use 64bit machine check code on 32bit")

arch/x86/kernel/apic_32.c +4 -4
Index: linux/arch/x86/kernel/apic_32.c
===================================================================
@@ -700,7 +700,7 @@ void clear_local_APIC(void)
 	}
 
 	/* lets not touch this if we didn't frob it */
-#ifdef CONFIG_X86_MCE_P4THERMAL
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
 	if (maxlvt >= 5) {
 		v = apic_read(APIC_LVTTHMR);
 		apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED);
@@ -717,7 +717,7 @@ void clear_local_APIC(void)
 	if (maxlvt >= 4)
 		apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
 
-#ifdef CONFIG_X86_MCE_P4THERMAL
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
 	if (maxlvt >= 5)
 		apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED);
 #endif
@@ -1377,7 +1377,7 @@ void __init apic_intr_init(void)
 	set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
 
 	/* thermal monitor LVT interrupt */
-#ifdef CONFIG_X86_MCE_P4THERMAL
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
 	set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
 #endif
 }
@@ -1595,7 +1595,7 @@ static int lapic_suspend(struct sys_devi
 	apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
 	apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
 	apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
-#ifdef CONFIG_X86_MCE_P4THERMAL
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
 	if (maxlvt >= 5)
 		apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
 #endif
include/asm-x86/mach-default/entry_arch.h +1 -1
Index: linux/include/asm-x86/mach-default/entry_arch.h
===================================================================
@@ -27,7 +27,7 @@ BUILD_INTERRUPT(apic_timer_interrupt,LOC
 BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
 BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
 
-#ifdef CONFIG_X86_MCE_P4THERMAL
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
 BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
 #endif
 
author
#2 lore raw

PATCH 2/4 MCE: Add old machine check code to feature-removal-schedule.txt

In reply to Andi Kleen
Documentation/feature-removal-schedule.txt +10 -0
Index: linux/Documentation/feature-removal-schedule.txt
===================================================================
@@ -321,3 +321,13 @@ Why:	This option was introduced just to
 	to keep working over the upgrade to 2.6.26. At the scheduled time of
 	removal fixed lm-sensors (2.x or 3.x) should be readily available.
 Who:	Rene Herman <[email protected]>
+
+----------------------------
+
+What:   CONFIG_X86_OLD_MCE
+When:	2.6.29
+Why:	Remove the old legacy 32bit machine check code. This has been superseded
+	by the 64bit machine check code, but the old version has been kept
+	around for easier testing. Note this doesn't impact the old P5 and WinChip
+	machine check handlers.
+Who:	Andi Kleen <[email protected]>
author
#3 lore raw

PATCH 3/4 MCE: Reinitialize per cpu features and ancient mces on resume

In reply to Andi Kleen

This fixes a long standing bug in the machine check code. On resume the boot CPU wouldn't get its vendor specific state like thermal handling reinitialized. This means the boot cpu wouldn't ever get any thermal events reported again. Also the newly added ancient CPUs have the same problem.

Call the respective initialization functions on resume.

arch/x86/kernel/cpu/mcheck/mce_64.c +2 -0
Index: linux/arch/x86/kernel/cpu/mcheck/mce_64.c
===================================================================
@@ -753,6 +753,8 @@ __setup("mce=", mcheck_enable);
 static int mce_resume(struct sys_device *dev)
 {
 	mce_init(NULL);
+	mce_ancient_init(&current_cpu_data);
+	mce_cpu_features(&current_cpu_data);
 	return 0;
 }
 
author
#4 lore raw

PATCH 4/4 MCE: Don't disable machine checks during code patching

In reply to Andi Kleen

This removes part of a a patch I added myself some time ago. After some consideration the patch was a bad idea. In particular it stopped machine check exceptions during code patching.

To quote the comment:

* MCEs only happen when something got corrupted and in this
* case we must do something about the corruption.
* Ignoring it is worse than a unlikely patching race.
* Also machine checks tend to be broadcast and if one CPU
* goes into machine check the others follow quickly, so we don't
* expect a machine check to cause undue problems during to code
* patching.

So undo the machine check related parts of 8f4e956b313dcccbc7be6f10808952345e3b638c NMIs are still disabled.

This only removes code, the only additions are a new comment.

---
 arch/x86/kernel/alternative.c       |   17 +++++++++++------
 arch/x86/kernel/cpu/mcheck/mce_32.c |   14 --------------
 arch/x86/kernel/cpu/mcheck/mce_64.c |   14 --------------
 include/asm-x86/mce.h               |    2 --
 4 files changed, 11 insertions(+), 36 deletions(-)
arch/x86/kernel/alternative.c +11 -6
Index: linux/arch/x86/kernel/alternative.c
===================================================================
@@ -424,9 +424,17 @@ void __init alternative_instructions(voi
 	   that might execute the to be patched code.
 	   Other CPUs are not running. */
 	stop_nmi();
-#ifdef CONFIG_X86_MCE
-	stop_mce();
-#endif
+
+	/*
+	 * Don't stop machine check exceptions while patching.
+	 * MCEs only happen when something got corrupted and in this
+	 * case we must do something about the corruption.
+	 * Ignoring it is worse than a unlikely patching race.
+	 * Also machine checks tend to be broadcast and if one CPU
+	 * goes into machine check the others follow quickly, so we don't
+	 * expect a machine check to cause undue problems during to code
+	 * patching.
+	 */
 
 	apply_alternatives(__alt_instructions, __alt_instructions_end);
 
@@ -466,9 +474,6 @@ void __init alternative_instructions(voi
 				(unsigned long)__smp_locks_end);
 
 	restart_nmi();
-#ifdef CONFIG_X86_MCE
-	restart_mce();
-#endif
 }
 
 /**
arch/x86/kernel/cpu/mcheck/mce_64.c +0 -14
Index: linux/arch/x86/kernel/cpu/mcheck/mce_64.c
===================================================================
@@ -699,20 +699,6 @@ static struct miscdevice mce_log_device 
 	&mce_chrdev_ops,
 };
 
-static unsigned long old_cr4 __initdata;
-
-void __init stop_mce(void)
-{
-	old_cr4 = read_cr4();
-	clear_in_cr4(X86_CR4_MCE);
-}
-
-void __init restart_mce(void)
-{
-	if (old_cr4 & X86_CR4_MCE)
-		set_in_cr4(X86_CR4_MCE);
-}
-
 /*
  * Old style boot options parsing. Only for compatibility.
  */
include/asm-x86/mce.h +0 -2
Index: linux/include/asm-x86/mce.h
===================================================================
@@ -113,8 +113,6 @@ extern void mcheck_init(struct cpuinfo_x
 #else
 #define mcheck_init(c) do { } while (0)
 #endif
-extern void stop_mce(void);
-extern void restart_mce(void);
 
 #endif /* __KERNEL__ */
 
arch/x86/kernel/cpu/mcheck/mce_32.c +0 -14
Index: linux/arch/x86/kernel/cpu/mcheck/mce_32.c
===================================================================
@@ -61,20 +61,6 @@ void mcheck_init(struct cpuinfo_x86 *c)
 	}
 }
 
-static unsigned long old_cr4 __initdata;
-
-void __init stop_mce(void)
-{
-	old_cr4 = read_cr4();
-	clear_in_cr4(X86_CR4_MCE);
-}
-
-void __init restart_mce(void)
-{
-	if (old_cr4 & X86_CR4_MCE)
-		set_in_cr4(X86_CR4_MCE);
-}
-
 static int __init mcheck_disable(char *str)
 {
 	mce_disabled = 1;
#5 lore raw
In reply to Andi Kleen
Quoted 8 lines · Andi Kleen

Should be applied to the respective x86 topic branch.

- Fix Intel thermal handling broken in earlier merge
- Add old code to the deprecation schedule
- Fix a long standing bug in thermal interrupt handling after suspend to ram
- Revert older bogus patch

Applied to tip:x86/unify-mce, thanks.

-hpa