From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932531AbVIHPcW (ORCPT ); Thu, 8 Sep 2005 11:32:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932532AbVIHPcW (ORCPT ); Thu, 8 Sep 2005 11:32:22 -0400 Received: from public.id2-vpn.continvity.gns.novell.com ([195.33.99.129]:50022 "EHLO emea1-mh.id2.novell.com") by vger.kernel.org with ESMTP id S932531AbVIHPcV (ORCPT ); Thu, 8 Sep 2005 11:32:21 -0400 Message-Id: <432075E502000078000244AE@emea1-mh.id2.novell.com> X-Mailer: Novell GroupWise Internet Agent 7.0 Date: Thu, 08 Sep 2005 17:33:25 +0200 From: "Jan Beulich" To: Subject: [PATCH] abstraction of i386 machine check handlers Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__Part87A5E9D5.0__=" Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__Part87A5E9D5.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline (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 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> 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