aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-07-23 05:57:45 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:44:49 -0400
commit696e409dbd1ce325129c5030267365619364dfa0 (patch)
treea47bb1c8513ed35adebf60281d190cb68a343a95
parent41fcb7feed70d8076f1591664314ca172fcdff7b (diff)
edac_mce: Add an interface driver to report mce errors via edac
edac_mce module is an interface module that gets mcelog data and forwards to any registered edac module that expects to receive data via mce. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c10
-rw-r--r--drivers/edac/Kconfig8
-rw-r--r--drivers/edac/Makefile1
-rw-r--r--drivers/edac/edac_mce.c58
-rw-r--r--include/linux/edac_mce.h31
5 files changed, 107 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 8a6f0afa767e..6585ff07ddf5 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -36,6 +36,7 @@
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/mm.h> 37#include <linux/mm.h>
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/edac_mce.h>
39 40
40#include <asm/processor.h> 41#include <asm/processor.h>
41#include <asm/hw_irq.h> 42#include <asm/hw_irq.h>
@@ -169,6 +170,15 @@ void mce_log(struct mce *mce)
169 entry = rcu_dereference_check_mce(mcelog.next); 170 entry = rcu_dereference_check_mce(mcelog.next);
170 for (;;) { 171 for (;;) {
171 /* 172 /*
173 * If edac_mce is enabled, it will check the error type
174 * and will process it, if it is a known error.
175 * Otherwise, the error will be sent through mcelog
176 * interface
177 */
178 if (edac_mce_parse(mce))
179 return;
180
181 /*
172 * When the buffer fills up discard new entries. 182 * When the buffer fills up discard new entries.
173 * Assume that the earlier errors are the more 183 * Assume that the earlier errors are the more
174 * interesting ones: 184 * interesting ones:
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 391ddbfb2a34..5b7fbc5aec87 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -69,6 +69,9 @@ config EDAC_MM_EDAC
69 occurred so that a particular failing memory module can be 69 occurred so that a particular failing memory module can be
70 replaced. If unsure, select 'Y'. 70 replaced. If unsure, select 'Y'.
71 71
72config EDAC_MCE
73 tristate
74
72config EDAC_AMD64 75config EDAC_AMD64
73 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" 76 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
74 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE 77 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
@@ -169,9 +172,12 @@ config EDAC_I5400
169config EDAC_I7CORE 172config EDAC_I7CORE
170 tristate "Intel i7 Core (Nehalem) processors" 173 tristate "Intel i7 Core (Nehalem) processors"
171 depends on EDAC_MM_EDAC && PCI && X86 174 depends on EDAC_MM_EDAC && PCI && X86
175 select EDAC_MCE
172 help 176 help
173 Support for error detection and correction the Intel 177 Support for error detection and correction the Intel
174 i7 Core (Nehalem) Integrated Memory Controller 178 i7 Core (Nehalem) Integrated Memory Controller that exists on
179 newer processors like i7 Core, i7 Core Extreme, Xeon 35xx
180 and Xeon 55xx processors.
175 181
176config EDAC_I82860 182config EDAC_I82860
177 tristate "Intel 82860" 183 tristate "Intel 82860"
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index b9996195b233..ca6b1bb24ccc 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -8,6 +8,7 @@
8 8
9obj-$(CONFIG_EDAC) := edac_stub.o 9obj-$(CONFIG_EDAC) := edac_stub.o
10obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o 10obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
11obj-$(CONFIG_EDAC_MCE) += edac_mce.o
11 12
12edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o 13edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
13edac_core-objs += edac_module.o edac_device_sysfs.o 14edac_core-objs += edac_module.o edac_device_sysfs.o
diff --git a/drivers/edac/edac_mce.c b/drivers/edac/edac_mce.c
new file mode 100644
index 000000000000..b1efa8e51921
--- /dev/null
+++ b/drivers/edac/edac_mce.c
@@ -0,0 +1,58 @@
1/* Provides edac interface to mcelog events
2 *
3 * This file may be distributed under the terms of the
4 * GNU General Public License version 2.
5 *
6 * Copyright (c) 2009 by:
7 * Mauro Carvalho Chehab <mchehab@redhat.com>
8 *
9 * Red Hat Inc. http://www.redhat.com
10 */
11
12#include <linux/module.h>
13#include <linux/edac_mce.h>
14#include <asm/mce.h>
15
16int edac_mce_enabled;
17EXPORT_SYMBOL_GPL(edac_mce_enabled);
18
19
20/*
21 * Extension interface
22 */
23
24static LIST_HEAD(edac_mce_list);
25static DEFINE_MUTEX(edac_mce_lock);
26
27int edac_mce_register(struct edac_mce *edac_mce)
28{
29 mutex_lock(&edac_mce_lock);
30 list_add_tail(&edac_mce->list, &edac_mce_list);
31 mutex_unlock(&edac_mce_lock);
32 return 0;
33}
34EXPORT_SYMBOL(edac_mce_register);
35
36void edac_mce_unregister(struct edac_mce *edac_mce)
37{
38 mutex_lock(&edac_mce_lock);
39 list_del(&edac_mce->list);
40 mutex_unlock(&edac_mce_lock);
41}
42EXPORT_SYMBOL(edac_mce_unregister);
43
44
45
46int edac_mce_queue(struct mce *mce)
47{
48 struct edac_mce *edac_mce;
49
50 list_for_each_entry(edac_mce, &edac_mce_list, list) {
51 if (edac_mce->check_error(edac_mce->priv, mce))
52 return 1;
53 }
54
55 /* Nobody queued the error */
56 return 0;
57}
58EXPORT_SYMBOL_GPL(edac_mce_queue);
diff --git a/include/linux/edac_mce.h b/include/linux/edac_mce.h
new file mode 100644
index 000000000000..f974fc035363
--- /dev/null
+++ b/include/linux/edac_mce.h
@@ -0,0 +1,31 @@
1/* Provides edac interface to mcelog events
2 *
3 * This file may be distributed under the terms of the
4 * GNU General Public License version 2.
5 *
6 * Copyright (c) 2009 by:
7 * Mauro Carvalho Chehab <mchehab@redhat.com>
8 *
9 * Red Hat Inc. http://www.redhat.com
10 */
11
12#if defined(CONFIG_EDAC_MCE) || \
13 (defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE))
14
15#include <asm/mce.h>
16#include <linux/list.h>
17
18struct edac_mce {
19 struct list_head list;
20
21 void *priv;
22 int (*check_error)(void *priv, struct mce *mce);
23};
24
25int edac_mce_register(struct edac_mce *edac_mce);
26void edac_mce_unregister(struct edac_mce *edac_mce);
27int edac_mce_parse(struct mce *mce);
28
29#else
30#define edac_mce_parse(mce) (0)
31#endif