Commit 5bb38adcb54cf7192b154368ad62982caa11ca0b
Committed by
H. Peter Anvin
1 parent
bab9bc6583
Exists in
master
and in
4 other branches
x86: mce: Remove old i386 machine check code
As announced in feature-remove-schedule.txt remove CONFIG_X86_OLD_MCE This patch only removes code. The ancient machine check code for very old systems that are not supported by CONFIG_X86_NEW_MCE is still kept. Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Showing 9 changed files with 2 additions and 603 deletions Side-by-side Diff
Documentation/feature-removal-schedule.txt
... | ... | @@ -444,14 +444,4 @@ |
444 | 444 | When: 2.6.33 |
445 | 445 | Why: Should be implemented in userspace, policy daemon. |
446 | 446 | Who: Johannes Berg <johannes@sipsolutions.net> |
447 | - | |
448 | ----------------------------- | |
449 | - | |
450 | -What: CONFIG_X86_OLD_MCE | |
451 | -When: 2.6.32 | |
452 | -Why: Remove the old legacy 32bit machine check code. This has been | |
453 | - superseded by the newer machine check code from the 64bit port, | |
454 | - but the old version has been kept around for easier testing. Note this | |
455 | - doesn't impact the old P5 and WinChip machine check handlers. | |
456 | -Who: Andi Kleen <andi@firstfloor.org> |
arch/x86/Kconfig
... | ... | @@ -781,21 +781,10 @@ |
781 | 781 | The action the kernel takes depends on the severity of the problem, |
782 | 782 | ranging from warning messages to halting the machine. |
783 | 783 | |
784 | -config X86_OLD_MCE | |
785 | - depends on X86_32 && X86_MCE | |
786 | - bool "Use legacy machine check code (will go away)" | |
787 | - default n | |
788 | - select X86_ANCIENT_MCE | |
789 | - ---help--- | |
790 | - Use the old i386 machine check code. This is merely intended for | |
791 | - testing in a transition period. Try this if you run into any machine | |
792 | - check related software problems, but report the problem to | |
793 | - linux-kernel. When in doubt say no. | |
794 | - | |
795 | 784 | config X86_NEW_MCE |
796 | 785 | depends on X86_MCE |
797 | 786 | bool |
798 | - default y if (!X86_OLD_MCE && X86_32) || X86_64 | |
787 | + default y | |
799 | 788 | |
800 | 789 | config X86_MCE_INTEL |
801 | 790 | def_bool y |
802 | 791 | |
... | ... | @@ -835,29 +824,9 @@ |
835 | 824 | If you don't know what a machine check is and you don't do kernel |
836 | 825 | QA it is safe to say n. |
837 | 826 | |
838 | -config X86_MCE_NONFATAL | |
839 | - tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" | |
840 | - depends on X86_OLD_MCE | |
841 | - ---help--- | |
842 | - Enabling this feature starts a timer that triggers every 5 seconds which | |
843 | - will look at the machine check registers to see if anything happened. | |
844 | - Non-fatal problems automatically get corrected (but still logged). | |
845 | - Disable this if you don't want to see these messages. | |
846 | - Seeing the messages this option prints out may be indicative of dying | |
847 | - or out-of-spec (ie, overclocked) hardware. | |
848 | - This option only does something on certain CPUs. | |
849 | - (AMD Athlon/Duron and Intel Pentium 4) | |
850 | - | |
851 | -config X86_MCE_P4THERMAL | |
852 | - bool "check for P4 thermal throttling interrupt." | |
853 | - depends on X86_OLD_MCE && X86_MCE && (X86_UP_APIC || SMP) | |
854 | - ---help--- | |
855 | - Enabling this feature will cause a message to be printed when the P4 | |
856 | - enters thermal throttling. | |
857 | - | |
858 | 827 | config X86_THERMAL_VECTOR |
859 | 828 | def_bool y |
860 | - depends on X86_MCE_P4THERMAL || X86_MCE_INTEL | |
829 | + depends on X86_MCE_INTEL | |
861 | 830 | |
862 | 831 | config VM86 |
863 | 832 | bool "Enable VM86 support" if EMBEDDED |
arch/x86/include/asm/mce.h
... | ... | @@ -115,13 +115,6 @@ |
115 | 115 | static inline void mcheck_init(struct cpuinfo_x86 *c) {} |
116 | 116 | #endif |
117 | 117 | |
118 | -#ifdef CONFIG_X86_OLD_MCE | |
119 | -extern int nr_mce_banks; | |
120 | -void amd_mcheck_init(struct cpuinfo_x86 *c); | |
121 | -void intel_p4_mcheck_init(struct cpuinfo_x86 *c); | |
122 | -void intel_p6_mcheck_init(struct cpuinfo_x86 *c); | |
123 | -#endif | |
124 | - | |
125 | 118 | #ifdef CONFIG_X86_ANCIENT_MCE |
126 | 119 | void intel_p5_mcheck_init(struct cpuinfo_x86 *c); |
127 | 120 | void winchip_mcheck_init(struct cpuinfo_x86 *c); |
128 | 121 | |
... | ... | @@ -208,11 +201,7 @@ |
208 | 201 | |
209 | 202 | void intel_init_thermal(struct cpuinfo_x86 *c); |
210 | 203 | |
211 | -#ifdef CONFIG_X86_NEW_MCE | |
212 | 204 | void mce_log_therm_throt_event(__u64 status); |
213 | -#else | |
214 | -static inline void mce_log_therm_throt_event(__u64 status) {} | |
215 | -#endif | |
216 | 205 | |
217 | 206 | #endif /* __KERNEL__ */ |
218 | 207 | #endif /* _ASM_X86_MCE_H */ |
arch/x86/kernel/cpu/mcheck/Makefile
1 | 1 | obj-y = mce.o |
2 | 2 | |
3 | 3 | obj-$(CONFIG_X86_NEW_MCE) += mce-severity.o |
4 | -obj-$(CONFIG_X86_OLD_MCE) += k7.o p4.o p6.o | |
5 | 4 | obj-$(CONFIG_X86_ANCIENT_MCE) += winchip.o p5.o |
6 | 5 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o |
7 | 6 | obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o |
8 | -obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o | |
9 | 7 | obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o |
10 | 8 | obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o |
11 | 9 |
arch/x86/kernel/cpu/mcheck/k7.c
1 | -/* | |
2 | - * Athlon specific Machine Check Exception Reporting | |
3 | - * (C) Copyright 2002 Dave Jones <davej@redhat.com> | |
4 | - */ | |
5 | -#include <linux/interrupt.h> | |
6 | -#include <linux/kernel.h> | |
7 | -#include <linux/types.h> | |
8 | -#include <linux/init.h> | |
9 | -#include <linux/smp.h> | |
10 | - | |
11 | -#include <asm/processor.h> | |
12 | -#include <asm/system.h> | |
13 | -#include <asm/mce.h> | |
14 | -#include <asm/msr.h> | |
15 | - | |
16 | -/* Machine Check Handler For AMD Athlon/Duron: */ | |
17 | -static void k7_machine_check(struct pt_regs *regs, long error_code) | |
18 | -{ | |
19 | - u32 alow, ahigh, high, low; | |
20 | - u32 mcgstl, mcgsth; | |
21 | - int recover = 1; | |
22 | - int i; | |
23 | - | |
24 | - rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); | |
25 | - if (mcgstl & (1<<0)) /* Recoverable ? */ | |
26 | - recover = 0; | |
27 | - | |
28 | - printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", | |
29 | - smp_processor_id(), mcgsth, mcgstl); | |
30 | - | |
31 | - for (i = 1; i < nr_mce_banks; i++) { | |
32 | - rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); | |
33 | - if (high & (1<<31)) { | |
34 | - char misc[20]; | |
35 | - char addr[24]; | |
36 | - | |
37 | - misc[0] = '\0'; | |
38 | - addr[0] = '\0'; | |
39 | - | |
40 | - if (high & (1<<29)) | |
41 | - recover |= 1; | |
42 | - if (high & (1<<25)) | |
43 | - recover |= 2; | |
44 | - high &= ~(1<<31); | |
45 | - | |
46 | - if (high & (1<<27)) { | |
47 | - rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); | |
48 | - snprintf(misc, 20, "[%08x%08x]", ahigh, alow); | |
49 | - } | |
50 | - if (high & (1<<26)) { | |
51 | - rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); | |
52 | - snprintf(addr, 24, " at %08x%08x", ahigh, alow); | |
53 | - } | |
54 | - | |
55 | - printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", | |
56 | - smp_processor_id(), i, high, low, misc, addr); | |
57 | - | |
58 | - /* Clear it: */ | |
59 | - wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); | |
60 | - /* Serialize: */ | |
61 | - wmb(); | |
62 | - add_taint(TAINT_MACHINE_CHECK); | |
63 | - } | |
64 | - } | |
65 | - | |
66 | - if (recover & 2) | |
67 | - panic("CPU context corrupt"); | |
68 | - if (recover & 1) | |
69 | - panic("Unable to continue"); | |
70 | - | |
71 | - printk(KERN_EMERG "Attempting to continue.\n"); | |
72 | - | |
73 | - mcgstl &= ~(1<<2); | |
74 | - wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); | |
75 | -} | |
76 | - | |
77 | - | |
78 | -/* AMD K7 machine check is Intel like: */ | |
79 | -void amd_mcheck_init(struct cpuinfo_x86 *c) | |
80 | -{ | |
81 | - u32 l, h; | |
82 | - int i; | |
83 | - | |
84 | - if (!cpu_has(c, X86_FEATURE_MCE)) | |
85 | - return; | |
86 | - | |
87 | - machine_check_vector = k7_machine_check; | |
88 | - /* Make sure the vector pointer is visible before we enable MCEs: */ | |
89 | - wmb(); | |
90 | - | |
91 | - printk(KERN_INFO "Intel machine check architecture supported.\n"); | |
92 | - | |
93 | - rdmsr(MSR_IA32_MCG_CAP, l, h); | |
94 | - if (l & (1<<8)) /* Control register present ? */ | |
95 | - wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); | |
96 | - nr_mce_banks = l & 0xff; | |
97 | - | |
98 | - /* | |
99 | - * Clear status for MC index 0 separately, we don't touch CTL, | |
100 | - * as some K7 Athlons cause spurious MCEs when its enabled: | |
101 | - */ | |
102 | - if (boot_cpu_data.x86 == 6) { | |
103 | - wrmsr(MSR_IA32_MC0_STATUS, 0x0, 0x0); | |
104 | - i = 1; | |
105 | - } else | |
106 | - i = 0; | |
107 | - | |
108 | - for (; i < nr_mce_banks; i++) { | |
109 | - wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff); | |
110 | - wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0); | |
111 | - } | |
112 | - | |
113 | - set_in_cr4(X86_CR4_MCE); | |
114 | - printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", | |
115 | - smp_processor_id()); | |
116 | -} |
arch/x86/kernel/cpu/mcheck/mce.c
... | ... | @@ -58,8 +58,6 @@ |
58 | 58 | |
59 | 59 | int mce_disabled __read_mostly; |
60 | 60 | |
61 | -#ifdef CONFIG_X86_NEW_MCE | |
62 | - | |
63 | 61 | #define MISC_MCELOG_MINOR 227 |
64 | 62 | |
65 | 63 | #define SPINUNIT 100 /* 100ns */ |
... | ... | @@ -1992,51 +1990,6 @@ |
1992 | 1990 | } |
1993 | 1991 | |
1994 | 1992 | device_initcall(mce_init_device); |
1995 | - | |
1996 | -#else /* CONFIG_X86_OLD_MCE: */ | |
1997 | - | |
1998 | -int nr_mce_banks; | |
1999 | -EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ | |
2000 | - | |
2001 | -/* This has to be run for each processor */ | |
2002 | -void mcheck_init(struct cpuinfo_x86 *c) | |
2003 | -{ | |
2004 | - if (mce_disabled) | |
2005 | - return; | |
2006 | - | |
2007 | - switch (c->x86_vendor) { | |
2008 | - case X86_VENDOR_AMD: | |
2009 | - amd_mcheck_init(c); | |
2010 | - break; | |
2011 | - | |
2012 | - case X86_VENDOR_INTEL: | |
2013 | - if (c->x86 == 5) | |
2014 | - intel_p5_mcheck_init(c); | |
2015 | - if (c->x86 == 6) | |
2016 | - intel_p6_mcheck_init(c); | |
2017 | - if (c->x86 == 15) | |
2018 | - intel_p4_mcheck_init(c); | |
2019 | - break; | |
2020 | - | |
2021 | - case X86_VENDOR_CENTAUR: | |
2022 | - if (c->x86 == 5) | |
2023 | - winchip_mcheck_init(c); | |
2024 | - break; | |
2025 | - | |
2026 | - default: | |
2027 | - break; | |
2028 | - } | |
2029 | - printk(KERN_INFO "mce: CPU supports %d MCE banks\n", nr_mce_banks); | |
2030 | -} | |
2031 | - | |
2032 | -static int __init mcheck_enable(char *str) | |
2033 | -{ | |
2034 | - mce_p5_enabled = 1; | |
2035 | - return 1; | |
2036 | -} | |
2037 | -__setup("mce", mcheck_enable); | |
2038 | - | |
2039 | -#endif /* CONFIG_X86_OLD_MCE */ | |
2040 | 1993 | |
2041 | 1994 | /* |
2042 | 1995 | * Old style boot options parsing. Only for compatibility. |
arch/x86/kernel/cpu/mcheck/non-fatal.c
1 | -/* | |
2 | - * Non Fatal Machine Check Exception Reporting | |
3 | - * | |
4 | - * (C) Copyright 2002 Dave Jones. <davej@redhat.com> | |
5 | - * | |
6 | - * This file contains routines to check for non-fatal MCEs every 15s | |
7 | - * | |
8 | - */ | |
9 | -#include <linux/interrupt.h> | |
10 | -#include <linux/workqueue.h> | |
11 | -#include <linux/jiffies.h> | |
12 | -#include <linux/kernel.h> | |
13 | -#include <linux/module.h> | |
14 | -#include <linux/types.h> | |
15 | -#include <linux/init.h> | |
16 | -#include <linux/smp.h> | |
17 | - | |
18 | -#include <asm/processor.h> | |
19 | -#include <asm/system.h> | |
20 | -#include <asm/mce.h> | |
21 | -#include <asm/msr.h> | |
22 | - | |
23 | -static int firstbank; | |
24 | - | |
25 | -#define MCE_RATE (15*HZ) /* timer rate is 15s */ | |
26 | - | |
27 | -static void mce_checkregs(void *info) | |
28 | -{ | |
29 | - u32 low, high; | |
30 | - int i; | |
31 | - | |
32 | - for (i = firstbank; i < nr_mce_banks; i++) { | |
33 | - rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); | |
34 | - | |
35 | - if (!(high & (1<<31))) | |
36 | - continue; | |
37 | - | |
38 | - printk(KERN_INFO "MCE: The hardware reports a non fatal, " | |
39 | - "correctable incident occurred on CPU %d.\n", | |
40 | - smp_processor_id()); | |
41 | - | |
42 | - printk(KERN_INFO "Bank %d: %08x%08x\n", i, high, low); | |
43 | - | |
44 | - /* | |
45 | - * Scrub the error so we don't pick it up in MCE_RATE | |
46 | - * seconds time: | |
47 | - */ | |
48 | - wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); | |
49 | - | |
50 | - /* Serialize: */ | |
51 | - wmb(); | |
52 | - add_taint(TAINT_MACHINE_CHECK); | |
53 | - } | |
54 | -} | |
55 | - | |
56 | -static void mce_work_fn(struct work_struct *work); | |
57 | -static DECLARE_DELAYED_WORK(mce_work, mce_work_fn); | |
58 | - | |
59 | -static void mce_work_fn(struct work_struct *work) | |
60 | -{ | |
61 | - on_each_cpu(mce_checkregs, NULL, 1); | |
62 | - schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE)); | |
63 | -} | |
64 | - | |
65 | -static int __init init_nonfatal_mce_checker(void) | |
66 | -{ | |
67 | - struct cpuinfo_x86 *c = &boot_cpu_data; | |
68 | - | |
69 | - /* Check for MCE support */ | |
70 | - if (!cpu_has(c, X86_FEATURE_MCE)) | |
71 | - return -ENODEV; | |
72 | - | |
73 | - /* Check for PPro style MCA */ | |
74 | - if (!cpu_has(c, X86_FEATURE_MCA)) | |
75 | - return -ENODEV; | |
76 | - | |
77 | - /* Some Athlons misbehave when we frob bank 0 */ | |
78 | - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | |
79 | - boot_cpu_data.x86 == 6) | |
80 | - firstbank = 1; | |
81 | - else | |
82 | - firstbank = 0; | |
83 | - | |
84 | - /* | |
85 | - * Check for non-fatal errors every MCE_RATE s | |
86 | - */ | |
87 | - schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE)); | |
88 | - printk(KERN_INFO "Machine check exception polling timer started.\n"); | |
89 | - | |
90 | - return 0; | |
91 | -} | |
92 | -module_init(init_nonfatal_mce_checker); | |
93 | - | |
94 | -MODULE_LICENSE("GPL"); |
arch/x86/kernel/cpu/mcheck/p4.c
1 | -/* | |
2 | - * P4 specific Machine Check Exception Reporting | |
3 | - */ | |
4 | -#include <linux/kernel.h> | |
5 | -#include <linux/types.h> | |
6 | -#include <linux/init.h> | |
7 | -#include <linux/smp.h> | |
8 | - | |
9 | -#include <asm/processor.h> | |
10 | -#include <asm/mce.h> | |
11 | -#include <asm/msr.h> | |
12 | - | |
13 | -/* as supported by the P4/Xeon family */ | |
14 | -struct intel_mce_extended_msrs { | |
15 | - u32 eax; | |
16 | - u32 ebx; | |
17 | - u32 ecx; | |
18 | - u32 edx; | |
19 | - u32 esi; | |
20 | - u32 edi; | |
21 | - u32 ebp; | |
22 | - u32 esp; | |
23 | - u32 eflags; | |
24 | - u32 eip; | |
25 | - /* u32 *reserved[]; */ | |
26 | -}; | |
27 | - | |
28 | -static int mce_num_extended_msrs; | |
29 | - | |
30 | -/* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */ | |
31 | -static void intel_get_extended_msrs(struct intel_mce_extended_msrs *r) | |
32 | -{ | |
33 | - u32 h; | |
34 | - | |
35 | - rdmsr(MSR_IA32_MCG_EAX, r->eax, h); | |
36 | - rdmsr(MSR_IA32_MCG_EBX, r->ebx, h); | |
37 | - rdmsr(MSR_IA32_MCG_ECX, r->ecx, h); | |
38 | - rdmsr(MSR_IA32_MCG_EDX, r->edx, h); | |
39 | - rdmsr(MSR_IA32_MCG_ESI, r->esi, h); | |
40 | - rdmsr(MSR_IA32_MCG_EDI, r->edi, h); | |
41 | - rdmsr(MSR_IA32_MCG_EBP, r->ebp, h); | |
42 | - rdmsr(MSR_IA32_MCG_ESP, r->esp, h); | |
43 | - rdmsr(MSR_IA32_MCG_EFLAGS, r->eflags, h); | |
44 | - rdmsr(MSR_IA32_MCG_EIP, r->eip, h); | |
45 | -} | |
46 | - | |
47 | -static void intel_machine_check(struct pt_regs *regs, long error_code) | |
48 | -{ | |
49 | - u32 alow, ahigh, high, low; | |
50 | - u32 mcgstl, mcgsth; | |
51 | - int recover = 1; | |
52 | - int i; | |
53 | - | |
54 | - rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); | |
55 | - if (mcgstl & (1<<0)) /* Recoverable ? */ | |
56 | - recover = 0; | |
57 | - | |
58 | - printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", | |
59 | - smp_processor_id(), mcgsth, mcgstl); | |
60 | - | |
61 | - if (mce_num_extended_msrs > 0) { | |
62 | - struct intel_mce_extended_msrs dbg; | |
63 | - | |
64 | - intel_get_extended_msrs(&dbg); | |
65 | - | |
66 | - printk(KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n" | |
67 | - "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n" | |
68 | - "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n", | |
69 | - smp_processor_id(), dbg.eip, dbg.eflags, | |
70 | - dbg.eax, dbg.ebx, dbg.ecx, dbg.edx, | |
71 | - dbg.esi, dbg.edi, dbg.ebp, dbg.esp); | |
72 | - } | |
73 | - | |
74 | - for (i = 0; i < nr_mce_banks; i++) { | |
75 | - rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); | |
76 | - if (high & (1<<31)) { | |
77 | - char misc[20]; | |
78 | - char addr[24]; | |
79 | - | |
80 | - misc[0] = addr[0] = '\0'; | |
81 | - if (high & (1<<29)) | |
82 | - recover |= 1; | |
83 | - if (high & (1<<25)) | |
84 | - recover |= 2; | |
85 | - high &= ~(1<<31); | |
86 | - if (high & (1<<27)) { | |
87 | - rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); | |
88 | - snprintf(misc, 20, "[%08x%08x]", ahigh, alow); | |
89 | - } | |
90 | - if (high & (1<<26)) { | |
91 | - rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); | |
92 | - snprintf(addr, 24, " at %08x%08x", ahigh, alow); | |
93 | - } | |
94 | - printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", | |
95 | - smp_processor_id(), i, high, low, misc, addr); | |
96 | - } | |
97 | - } | |
98 | - | |
99 | - if (recover & 2) | |
100 | - panic("CPU context corrupt"); | |
101 | - if (recover & 1) | |
102 | - panic("Unable to continue"); | |
103 | - | |
104 | - printk(KERN_EMERG "Attempting to continue.\n"); | |
105 | - | |
106 | - /* | |
107 | - * Do not clear the MSR_IA32_MCi_STATUS if the error is not | |
108 | - * recoverable/continuable.This will allow BIOS to look at the MSRs | |
109 | - * for errors if the OS could not log the error. | |
110 | - */ | |
111 | - for (i = 0; i < nr_mce_banks; i++) { | |
112 | - u32 msr; | |
113 | - msr = MSR_IA32_MC0_STATUS+i*4; | |
114 | - rdmsr(msr, low, high); | |
115 | - if (high&(1<<31)) { | |
116 | - /* Clear it */ | |
117 | - wrmsr(msr, 0UL, 0UL); | |
118 | - /* Serialize */ | |
119 | - wmb(); | |
120 | - add_taint(TAINT_MACHINE_CHECK); | |
121 | - } | |
122 | - } | |
123 | - mcgstl &= ~(1<<2); | |
124 | - wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); | |
125 | -} | |
126 | - | |
127 | -void intel_p4_mcheck_init(struct cpuinfo_x86 *c) | |
128 | -{ | |
129 | - u32 l, h; | |
130 | - int i; | |
131 | - | |
132 | - machine_check_vector = intel_machine_check; | |
133 | - wmb(); | |
134 | - | |
135 | - printk(KERN_INFO "Intel machine check architecture supported.\n"); | |
136 | - rdmsr(MSR_IA32_MCG_CAP, l, h); | |
137 | - if (l & (1<<8)) /* Control register present ? */ | |
138 | - wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); | |
139 | - nr_mce_banks = l & 0xff; | |
140 | - | |
141 | - for (i = 0; i < nr_mce_banks; i++) { | |
142 | - wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff); | |
143 | - wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0); | |
144 | - } | |
145 | - | |
146 | - set_in_cr4(X86_CR4_MCE); | |
147 | - printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", | |
148 | - smp_processor_id()); | |
149 | - | |
150 | - /* Check for P4/Xeon extended MCE MSRs */ | |
151 | - rdmsr(MSR_IA32_MCG_CAP, l, h); | |
152 | - if (l & (1<<9)) {/* MCG_EXT_P */ | |
153 | - mce_num_extended_msrs = (l >> 16) & 0xff; | |
154 | - printk(KERN_INFO "CPU%d: Intel P4/Xeon Extended MCE MSRs (%d)" | |
155 | - " available\n", | |
156 | - smp_processor_id(), mce_num_extended_msrs); | |
157 | - | |
158 | -#ifdef CONFIG_X86_MCE_P4THERMAL | |
159 | - /* Check for P4/Xeon Thermal monitor */ | |
160 | - intel_init_thermal(c); | |
161 | -#endif | |
162 | - } | |
163 | -} |
arch/x86/kernel/cpu/mcheck/p6.c
1 | -/* | |
2 | - * P6 specific Machine Check Exception Reporting | |
3 | - * (C) Copyright 2002 Alan Cox <alan@lxorguk.ukuu.org.uk> | |
4 | - */ | |
5 | -#include <linux/interrupt.h> | |
6 | -#include <linux/kernel.h> | |
7 | -#include <linux/types.h> | |
8 | -#include <linux/init.h> | |
9 | -#include <linux/smp.h> | |
10 | - | |
11 | -#include <asm/processor.h> | |
12 | -#include <asm/system.h> | |
13 | -#include <asm/mce.h> | |
14 | -#include <asm/msr.h> | |
15 | - | |
16 | -/* Machine Check Handler For PII/PIII */ | |
17 | -static void intel_machine_check(struct pt_regs *regs, long error_code) | |
18 | -{ | |
19 | - u32 alow, ahigh, high, low; | |
20 | - u32 mcgstl, mcgsth; | |
21 | - int recover = 1; | |
22 | - int i; | |
23 | - | |
24 | - rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); | |
25 | - if (mcgstl & (1<<0)) /* Recoverable ? */ | |
26 | - recover = 0; | |
27 | - | |
28 | - printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", | |
29 | - smp_processor_id(), mcgsth, mcgstl); | |
30 | - | |
31 | - for (i = 0; i < nr_mce_banks; i++) { | |
32 | - rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); | |
33 | - if (high & (1<<31)) { | |
34 | - char misc[20]; | |
35 | - char addr[24]; | |
36 | - | |
37 | - misc[0] = '\0'; | |
38 | - addr[0] = '\0'; | |
39 | - | |
40 | - if (high & (1<<29)) | |
41 | - recover |= 1; | |
42 | - if (high & (1<<25)) | |
43 | - recover |= 2; | |
44 | - high &= ~(1<<31); | |
45 | - | |
46 | - if (high & (1<<27)) { | |
47 | - rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); | |
48 | - snprintf(misc, 20, "[%08x%08x]", ahigh, alow); | |
49 | - } | |
50 | - if (high & (1<<26)) { | |
51 | - rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); | |
52 | - snprintf(addr, 24, " at %08x%08x", ahigh, alow); | |
53 | - } | |
54 | - | |
55 | - printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", | |
56 | - smp_processor_id(), i, high, low, misc, addr); | |
57 | - } | |
58 | - } | |
59 | - | |
60 | - if (recover & 2) | |
61 | - panic("CPU context corrupt"); | |
62 | - if (recover & 1) | |
63 | - panic("Unable to continue"); | |
64 | - | |
65 | - printk(KERN_EMERG "Attempting to continue.\n"); | |
66 | - /* | |
67 | - * Do not clear the MSR_IA32_MCi_STATUS if the error is not | |
68 | - * recoverable/continuable.This will allow BIOS to look at the MSRs | |
69 | - * for errors if the OS could not log the error: | |
70 | - */ | |
71 | - for (i = 0; i < nr_mce_banks; i++) { | |
72 | - unsigned int msr; | |
73 | - | |
74 | - msr = MSR_IA32_MC0_STATUS+i*4; | |
75 | - rdmsr(msr, low, high); | |
76 | - if (high & (1<<31)) { | |
77 | - /* Clear it: */ | |
78 | - wrmsr(msr, 0UL, 0UL); | |
79 | - /* Serialize: */ | |
80 | - wmb(); | |
81 | - add_taint(TAINT_MACHINE_CHECK); | |
82 | - } | |
83 | - } | |
84 | - mcgstl &= ~(1<<2); | |
85 | - wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); | |
86 | -} | |
87 | - | |
88 | -/* Set up machine check reporting for processors with Intel style MCE: */ | |
89 | -void intel_p6_mcheck_init(struct cpuinfo_x86 *c) | |
90 | -{ | |
91 | - u32 l, h; | |
92 | - int i; | |
93 | - | |
94 | - /* Check for MCE support */ | |
95 | - if (!cpu_has(c, X86_FEATURE_MCE)) | |
96 | - return; | |
97 | - | |
98 | - /* Check for PPro style MCA */ | |
99 | - if (!cpu_has(c, X86_FEATURE_MCA)) | |
100 | - return; | |
101 | - | |
102 | - /* Ok machine check is available */ | |
103 | - machine_check_vector = intel_machine_check; | |
104 | - /* Make sure the vector pointer is visible before we enable MCEs: */ | |
105 | - wmb(); | |
106 | - | |
107 | - printk(KERN_INFO "Intel machine check architecture supported.\n"); | |
108 | - rdmsr(MSR_IA32_MCG_CAP, l, h); | |
109 | - if (l & (1<<8)) /* Control register present ? */ | |
110 | - wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); | |
111 | - nr_mce_banks = l & 0xff; | |
112 | - | |
113 | - /* | |
114 | - * Following the example in IA-32 SDM Vol 3: | |
115 | - * - MC0_CTL should not be written | |
116 | - * - Status registers on all banks should be cleared on reset | |
117 | - */ | |
118 | - for (i = 1; i < nr_mce_banks; i++) | |
119 | - wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff); | |
120 | - | |
121 | - for (i = 0; i < nr_mce_banks; i++) | |
122 | - wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0); | |
123 | - | |
124 | - set_in_cr4(X86_CR4_MCE); | |
125 | - printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", | |
126 | - smp_processor_id()); | |
127 | -} |