[PATCH] abstraction of i386 machine check handlers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(Note: Patch also attached because the inline version is certain to get
line wrapped.)

This adjusts the i386 machine check infrastructure so that replacing
the
underlying exception handling code can be done by adjusting just a
single
definition rather than many different files.

Signed-off-by: Jan Beulich <[email protected]>

diff -Npru 2.6.13/arch/i386/kernel/cpu/mcheck/k7.c
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/k7.c
--- 2.6.13/arch/i386/kernel/cpu/mcheck/k7.c	2005-08-29
01:41:01.000000000 +0200
+++
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/k7.c	2005-09-01
11:59:55.000000000 +0200
@@ -18,7 +18,7 @@
 #include "mce.h"
 
 /* Machine Check Handler For AMD Athlon/Duron */
-static fastcall void k7_machine_check(struct pt_regs * regs, long
error_code)
+static MCE_HANDLER(k7)
 {
 	int recover=1;
 	u32 alow, ahigh, high, low;
@@ -65,33 +65,33 @@ static fastcall void k7_machine_check(st
 	printk (KERN_EMERG "Attempting to continue.\n");
 	mcgstl &= ~(1<<2);
 	wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
+	return MCE_HANDLED;
 }
 
 
 /* AMD K7 machine check is Intel like */
 void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
 {
-	u32 l, h;
-	int i;
-
-	machine_check_vector = k7_machine_check;
-	wmb();
+	if (mce_register_handler(k7_machine_check) == 0) {
+		u32 l, h;
+		int i;
+
+		printk (KERN_INFO "Intel machine check architecture
supported.\n");
+		rdmsr (MSR_IA32_MCG_CAP, l, h);
+		if (l & (1<<8))	/* Control register present ? */
+			wrmsr (MSR_IA32_MCG_CTL, 0xffffffff,
0xffffffff);
+		nr_mce_banks = l & 0xff;
+
+		/* Clear status for MC index 0 separately, we don't
touch CTL,
+		 * as some Athlons cause spurious MCEs when its enabled.
*/
+		wrmsr (MSR_IA32_MC0_STATUS, 0x0, 0x0);
+		for (i=1; i<nr_mce_banks; i++) {
+			wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff,
0xffffffff);
+			wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+		}
 
-	printk (KERN_INFO "Intel machine check architecture
supported.\n");
-	rdmsr (MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<8))	/* Control register present ? */
-		wrmsr (MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-	nr_mce_banks = l & 0xff;
-
-	/* Clear status for MC index 0 separately, we don't touch CTL,
-	 * as some Athlons cause spurious MCEs when its enabled. */
-	wrmsr (MSR_IA32_MC0_STATUS, 0x0, 0x0);
-	for (i=1; i<nr_mce_banks; i++) {
-		wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-		wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+		set_in_cr4 (X86_CR4_MCE);
+		printk (KERN_INFO "Intel machine check reporting enabled
on CPU#%d.\n",
+			smp_processor_id());
 	}
-
-	set_in_cr4 (X86_CR4_MCE);
-	printk (KERN_INFO "Intel machine check reporting enabled on
CPU#%d.\n",
-		smp_processor_id());
 }
diff -Npru 2.6.13/arch/i386/kernel/cpu/mcheck/mce.h
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/mce.h
--- 2.6.13/arch/i386/kernel/cpu/mcheck/mce.h	2005-08-29
01:41:01.000000000 +0200
+++
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/mce.h	2005-09-01
14:04:54.000000000 +0200
@@ -8,6 +8,13 @@ void winchip_mcheck_init(struct cpuinfo_
 
 /* Call the installed machine check handler for this CPU setup. */
 extern fastcall void (*machine_check_vector)(struct pt_regs *, long
error_code);
+static inline int mce_register_handler(fastcall void (*handler)(struct
pt_regs *, long)) {
+	machine_check_vector = handler;
+	wmb();
+	return 0;
+}
+# define MCE_HANDLER(name) fastcall void name##_machine_check(struct
pt_regs *regs, long error_code)
+# define MCE_HANDLED
 
 extern int mce_disabled __initdata;
 extern int nr_mce_banks;
diff -Npru 2.6.13/arch/i386/kernel/cpu/mcheck/p4.c
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/p4.c
--- 2.6.13/arch/i386/kernel/cpu/mcheck/p4.c	2005-08-29
01:41:01.000000000 +0200
+++
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/p4.c	2005-09-01
12:02:50.000000000 +0200
@@ -159,7 +159,7 @@ done:
 	return mce_num_extended_msrs;
 }
 
-static fastcall void intel_machine_check(struct pt_regs * regs, long
error_code)
+static MCE_HANDLER(intel)
 {
 	int recover=1;
 	u32 alow, ahigh, high, low;
@@ -229,43 +229,43 @@ static fastcall void intel_machine_check
 	}
 	mcgstl &= ~(1<<2);
 	wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
+	return MCE_HANDLED;
 }
 
 
 void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
 {
-	u32 l, h;
-	int i;
+	if (mce_register_handler(intel_machine_check) == 0) {
+		u32 l, h;
+		int i;
 	
-	machine_check_vector = intel_machine_check;
-	wmb();
-
-	printk (KERN_INFO "Intel machine check architecture
supported.\n");
-	rdmsr (MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<8))	/* Control register present ? */
-		wrmsr (MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-	nr_mce_banks = l & 0xff;
-
-	for (i=0; i<nr_mce_banks; i++) {
-		wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-		wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-	}
+		printk (KERN_INFO "Intel machine check architecture
supported.\n");
+		rdmsr (MSR_IA32_MCG_CAP, l, h);
+		if (l & (1<<8))	/* Control register present ? */
+			wrmsr (MSR_IA32_MCG_CTL, 0xffffffff,
0xffffffff);
+		nr_mce_banks = l & 0xff;
+
+		for (i=0; i<nr_mce_banks; i++) {
+			wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff,
0xffffffff);
+			wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+		}
 
-	set_in_cr4 (X86_CR4_MCE);
-	printk (KERN_INFO "Intel machine check reporting enabled on
CPU#%d.\n",
-		smp_processor_id());
-
-	/* Check for P4/Xeon extended MCE MSRs */
-	rdmsr (MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<9))	{/* MCG_EXT_P */
-		mce_num_extended_msrs = (l >> 16) & 0xff;
-		printk (KERN_INFO "CPU%d: Intel P4/Xeon Extended MCE
MSRs (%d)"
-				" available\n",
-			smp_processor_id(), mce_num_extended_msrs);
+		set_in_cr4 (X86_CR4_MCE);
+		printk (KERN_INFO "Intel machine check reporting enabled
on CPU#%d.\n",
+			smp_processor_id());
+
+		/* Check for P4/Xeon extended MCE MSRs */
+		rdmsr (MSR_IA32_MCG_CAP, l, h);
+		if (l & (1<<9))	{/* MCG_EXT_P */
+			mce_num_extended_msrs = (l >> 16) & 0xff;
+			printk (KERN_INFO "CPU%d: Intel P4/Xeon Extended
MCE MSRs (%d)"
+					" available\n",
+				smp_processor_id(),
mce_num_extended_msrs);
 
 #ifdef CONFIG_X86_MCE_P4THERMAL
-		/* Check for P4/Xeon Thermal monitor */
-		intel_init_thermal(c);
+			/* Check for P4/Xeon Thermal monitor */
+			intel_init_thermal(c);
 #endif
+		}
 	}
 }
diff -Npru 2.6.13/arch/i386/kernel/cpu/mcheck/p5.c
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/p5.c
--- 2.6.13/arch/i386/kernel/cpu/mcheck/p5.c	2005-08-29
01:41:01.000000000 +0200
+++
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/p5.c	2005-09-01
12:04:56.000000000 +0200
@@ -17,7 +17,7 @@
 #include "mce.h"
 
 /* Machine check handler for Pentium class Intel */
-static fastcall void pentium_machine_check(struct pt_regs * regs, long
error_code)
+static MCE_HANDLER(pentium)
 {
 	u32 loaddr, hi, lotype;
 	rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
@@ -26,29 +26,30 @@ static fastcall void pentium_machine_che
 	if(lotype&(1<<5))
 		printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU
on fire ?).\n", smp_processor_id());
 	add_taint(TAINT_MACHINE_CHECK);
+	return MCE_HANDLED;
 }
 
 /* Set up machine check reporting for processors with Intel style MCE
*/
 void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
 {
-	u32 l, h;
-	
-	/*Check for MCE support */
+	/* Check for MCE support */
 	if( !cpu_has(c, X86_FEATURE_MCE) )
 		return;	
 
 	/* Default P5 to off as its often misconnected */
 	if(mce_disabled != -1)
 		return;
-	machine_check_vector = pentium_machine_check;
-	wmb();
 
-	/* Read registers before enabling */
-	rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
-	rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
-	printk(KERN_INFO "Intel old style machine check architecture
supported.\n");
-
- 	/* Enable MCE */
-	set_in_cr4(X86_CR4_MCE);
-	printk(KERN_INFO "Intel old style machine check reporting
enabled on CPU#%d.\n", smp_processor_id());
+	if (mce_register_handler(pentium_machine_check) == 0) {
+		u32 l, h;
+
+		/* Read registers before enabling */
+		rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
+		rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
+		printk(KERN_INFO "Intel old style machine check
architecture supported.\n");
+
+	 	/* Enable MCE */
+		set_in_cr4(X86_CR4_MCE);
+		printk(KERN_INFO "Intel old style machine check
reporting enabled on CPU#%d.\n", smp_processor_id());
+	}
 }
diff -Npru 2.6.13/arch/i386/kernel/cpu/mcheck/p6.c
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/p6.c
--- 2.6.13/arch/i386/kernel/cpu/mcheck/p6.c	2005-08-29
01:41:01.000000000 +0200
+++
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/p6.c	2005-09-01
12:05:46.000000000 +0200
@@ -17,7 +17,7 @@
 #include "mce.h"
 
 /* Machine Check Handler For PII/PIII */
-static fastcall void intel_machine_check(struct pt_regs * regs, long
error_code)
+static MCE_HANDLER(intel)
 {
 	int recover=1;
 	u32 alow, ahigh, high, low;
@@ -77,14 +77,12 @@ static fastcall void intel_machine_check
 	}
 	mcgstl &= ~(1<<2);
 	wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
+	return MCE_HANDLED;
 }
 
 /* Set up machine check reporting for processors with Intel style MCE
*/
 void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
 {
-	u32 l, h;
-	int i;
-	
 	/* Check for MCE support */
 	if (!cpu_has(c, X86_FEATURE_MCE))
 		return;
@@ -94,22 +92,24 @@ void __devinit intel_p6_mcheck_init(stru
 		return;
 
 	/* Ok machine check is available */
-	machine_check_vector = intel_machine_check;
-	wmb();
+	if (mce_register_handler(intel_machine_check) == 0) {
+		u32 l, h;
+		int i;
+
+		printk (KERN_INFO "Intel machine check architecture
supported.\n");
+		rdmsr (MSR_IA32_MCG_CAP, l, h);
+		if (l & (1<<8))	/* Control register present ? */
+			wrmsr(MSR_IA32_MCG_CTL, 0xffffffff,
0xffffffff);
+		nr_mce_banks = l & 0xff;
+
+		/* Don't enable bank 0 on intel P6 cores, it goes bang
quickly. */
+		for (i=1; i<nr_mce_banks; i++) {
+			wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff,
0xffffffff);
+			wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+		}
 
-	printk (KERN_INFO "Intel machine check architecture
supported.\n");
-	rdmsr (MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<8))	/* Control register present ? */
-		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-	nr_mce_banks = l & 0xff;
-
-	/* Don't enable bank 0 on intel P6 cores, it goes bang quickly.
*/
-	for (i=1; i<nr_mce_banks; i++) {
-		wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-		wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
+		set_in_cr4 (X86_CR4_MCE);
+		printk (KERN_INFO "Intel machine check reporting enabled
on CPU#%d.\n",
+			smp_processor_id());
 	}
-
-	set_in_cr4 (X86_CR4_MCE);
-	printk (KERN_INFO "Intel machine check reporting enabled on
CPU#%d.\n",
-		smp_processor_id());
 }
diff -Npru 2.6.13/arch/i386/kernel/cpu/mcheck/winchip.c
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/winchip.c
--- 2.6.13/arch/i386/kernel/cpu/mcheck/winchip.c	2005-08-29
01:41:01.000000000 +0200
+++
2.6.13-i386-machine-check/arch/i386/kernel/cpu/mcheck/winchip.c	2005-09-01
12:07:29.000000000 +0200
@@ -16,22 +16,24 @@
 #include "mce.h"
 
 /* Machine check handler for WinChip C6 */
-static fastcall void winchip_machine_check(struct pt_regs * regs, long
error_code)
+static MCE_HANDLER(winchip)
 {
 	printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
 	add_taint(TAINT_MACHINE_CHECK);
+	return MCE_HANDLED;
 }
 
 /* Set up machine check reporting on the Winchip C6 series */
 void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
 {
-	u32 lo, hi;
-	machine_check_vector = winchip_machine_check;
-	wmb();
-	rdmsr(MSR_IDT_FCR1, lo, hi);
-	lo|= (1<<2);	/* Enable EIERRINT (int 18 MCE) */
-	lo&= ~(1<<4);	/* Enable MCE */
-	wrmsr(MSR_IDT_FCR1, lo, hi);
-	set_in_cr4(X86_CR4_MCE);
-	printk(KERN_INFO "Winchip machine check reporting enabled on
CPU#0.\n");
+	if (mce_register_handler(winchip_machine_check) == 0) {
+		u32 lo, hi;
+
+		rdmsr(MSR_IDT_FCR1, lo, hi);
+		lo|= (1<<2);	/* Enable EIERRINT (int 18 MCE) */
+		lo&= ~(1<<4);	/* Enable MCE */
+		wrmsr(MSR_IDT_FCR1, lo, hi);
+		set_in_cr4(X86_CR4_MCE);
+		printk(KERN_INFO "Winchip machine check reporting
enabled on CPU#0.\n");
+	}
 }

Attachment: linux-2.6.13-i386-machine-check.patch
Description: Binary data


[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux