aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig5
-rw-r--r--arch/x86/include/asm/mce.h2
-rw-r--r--arch/x86/kernel/cpu/mcheck/Makefile1
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c15
-rw-r--r--arch/x86/kernel/cpu/mcheck/threshold.c24
5 files changed, 38 insertions, 9 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9c39095b33fc..52d7013785fe 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -751,6 +751,11 @@ config X86_MCE_AMD
751 Additional support for AMD specific MCE features such as 751 Additional support for AMD specific MCE features such as
752 the DRAM Error Threshold. 752 the DRAM Error Threshold.
753 753
754config X86_MCE_THRESHOLD
755 depends on X86_MCE_AMD || X86_MCE_INTEL
756 bool
757 default y
758
754config X86_MCE_NONFATAL 759config X86_MCE_NONFATAL
755 tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" 760 tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
756 depends on X86_32 && X86_MCE 761 depends on X86_32 && X86_MCE
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 39136c497c5e..125cd8714622 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -135,5 +135,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
135#define mcheck_init(c) do { } while (0) 135#define mcheck_init(c) do { } while (0)
136#endif 136#endif
137 137
138extern void (*mce_threshold_vector)(void);
139
138#endif /* __KERNEL__ */ 140#endif /* __KERNEL__ */
139#endif /* _ASM_X86_MCE_H */ 141#endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile
index d7d2323bbb69..b2f89829bbe8 100644
--- a/arch/x86/kernel/cpu/mcheck/Makefile
+++ b/arch/x86/kernel/cpu/mcheck/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o
4obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o 4obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o
5obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o 5obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o
6obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o 6obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o
7obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index e82c8208b81e..49705be98209 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -79,6 +79,8 @@ static unsigned char shared_bank[NR_BANKS] = {
79 79
80static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ 80static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
81 81
82static void amd_threshold_interrupt(void);
83
82/* 84/*
83 * CPU Initialization 85 * CPU Initialization
84 */ 86 */
@@ -174,6 +176,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
174 tr.reset = 0; 176 tr.reset = 0;
175 tr.old_limit = 0; 177 tr.old_limit = 0;
176 threshold_restart_bank(&tr); 178 threshold_restart_bank(&tr);
179
180 mce_threshold_vector = amd_threshold_interrupt;
177 } 181 }
178 } 182 }
179} 183}
@@ -187,16 +191,12 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
187 * the interrupt goes off when error_count reaches threshold_limit. 191 * the interrupt goes off when error_count reaches threshold_limit.
188 * the handler will simply log mcelog w/ software defined bank number. 192 * the handler will simply log mcelog w/ software defined bank number.
189 */ 193 */
190asmlinkage void mce_threshold_interrupt(void) 194static void amd_threshold_interrupt(void)
191{ 195{
192 unsigned int bank, block; 196 unsigned int bank, block;
193 struct mce m; 197 struct mce m;
194 u32 low = 0, high = 0, address = 0; 198 u32 low = 0, high = 0, address = 0;
195 199
196 ack_APIC_irq();
197 exit_idle();
198 irq_enter();
199
200 mce_setup(&m); 200 mce_setup(&m);
201 201
202 /* assume first bank caused it */ 202 /* assume first bank caused it */
@@ -241,13 +241,10 @@ asmlinkage void mce_threshold_interrupt(void)
241 + bank * NR_BLOCKS 241 + bank * NR_BLOCKS
242 + block; 242 + block;
243 mce_log(&m); 243 mce_log(&m);
244 goto out; 244 return;
245 } 245 }
246 } 246 }
247 } 247 }
248out:
249 inc_irq_stat(irq_threshold_count);
250 irq_exit();
251} 248}
252 249
253/* 250/*
diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c
new file mode 100644
index 000000000000..4319142413d7
--- /dev/null
+++ b/arch/x86/kernel/cpu/mcheck/threshold.c
@@ -0,0 +1,24 @@
1/* Common corrected MCE threshold handler code */
2#include <linux/kernel.h>
3#include <linux/interrupt.h>
4#include <asm/mce.h>
5#include <asm/irq_vectors.h>
6#include <asm/idle.h>
7
8static void default_threshold_interrupt(void)
9{
10 printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n",
11 THRESHOLD_APIC_VECTOR);
12}
13
14void (*mce_threshold_vector)(void) = default_threshold_interrupt;
15
16asmlinkage void mce_threshold_interrupt(void)
17{
18 ack_APIC_irq();
19 exit_idle();
20 irq_enter();
21 inc_irq_stat(irq_threshold_count);
22 mce_threshold_vector();
23 irq_exit();
24}