* [PATCH] abstraction of i386 machine check handlers
@ 2005-09-08 15:33 Jan Beulich
2005-09-08 15:37 ` Christoph Hellwig
2005-09-09 3:48 ` Andi Kleen
0 siblings, 2 replies; 3+ messages in thread
From: Jan Beulich @ 2005-09-08 15:33 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 11977 bytes --]
(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 <jbeulich@novell.com>
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 #2: linux-2.6.13-i386-machine-check.patch --]
[-- Type: application/octet-stream, Size: 11976 bytes --]
(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 <jbeulich@novell.com>
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");
+ }
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] abstraction of i386 machine check handlers
2005-09-08 15:33 [PATCH] abstraction of i386 machine check handlers Jan Beulich
@ 2005-09-08 15:37 ` Christoph Hellwig
2005-09-09 3:48 ` Andi Kleen
1 sibling, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2005-09-08 15:37 UTC (permalink / raw)
To: Jan Beulich; +Cc: linux-kernel
On Thu, Sep 08, 2005 at 05:33:25PM +0200, Jan Beulich wrote:
> -static fastcall void k7_machine_check(struct pt_regs * regs, long
> error_code)
> +static MCE_HANDLER(k7)
such obsfucation is a big no-way.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] abstraction of i386 machine check handlers
2005-09-08 15:33 [PATCH] abstraction of i386 machine check handlers Jan Beulich
2005-09-08 15:37 ` Christoph Hellwig
@ 2005-09-09 3:48 ` Andi Kleen
1 sibling, 0 replies; 3+ messages in thread
From: Andi Kleen @ 2005-09-09 3:48 UTC (permalink / raw)
To: Jan Beulich; +Cc: linux-kernel
"Jan Beulich" <JBeulich@novell.com> writes:
> (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.
Quite ugly.
How about just adding die notifiers there instead and then hooking
them?
-Andi
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-09-09 3:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-08 15:33 [PATCH] abstraction of i386 machine check handlers Jan Beulich
2005-09-08 15:37 ` Christoph Hellwig
2005-09-09 3:48 ` Andi Kleen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®