(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
- Follow-Ups:
- Re: [PATCH] abstraction of i386 machine check handlers
- From: Andi Kleen <[email protected]>
- Re: [PATCH] abstraction of i386 machine check handlers
- From: Christoph Hellwig <[email protected]>
- Re: [PATCH] abstraction of i386 machine check handlers
- Prev by Date: [PATCH] fix i386 init initializers
- Next by Date: [PATCH] vm: kswapd use pgdat
- Previous by thread: [PATCH] fix i386 init initializers
- Next by thread: Re: [PATCH] abstraction of i386 machine check handlers
- Index(es):