mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH 0/20 v2] marry mcheck to EDAC
@ 2009-07-28 15:06 Borislav Petkov
  2009-07-28 15:06 ` [PATCH 01/20] topology: introduce cpu_node information for multi-node processors Borislav Petkov
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

Hi,

this is the second version of the mcheck/EDAC marriage patches. Changes
from the first version include:

* MCE decoding has moved into the EDAC core and is being unconditionally
enabled on AMD hardware when EDAC is compiled in.

* The amd64_edac module registers a bus error handler with the EDAC MCE
code which does the additional decoding of bank 4 errors (CECC/UECCs)
and mapping to DIMMs.

I've also added the topology patches by Andreas for reference here.
amd64_edac needs the node id (cpuinfo_x86.cpu_node_id) an MCE has
happened on (and thus the respective memory controller) in order to get
that node's DRAM configuration before further decoding any error info.

As always, give them a good critical look and let me know of any issues.

 arch/x86/kernel/cpu/mcheck/mce.c    |   12 +-
 drivers/edac/Makefile               |    6 +-
 drivers/edac/amd64_edac.c           |  324 +++++++++-------------------
 drivers/edac/amd64_edac.h           |   71 +------
 drivers/edac/amd64_edac_dbg.c       |    2 +-
 drivers/edac/amd64_edac_err_types.c |  161 --------------
 drivers/edac/edac_mce_amd.c         |  412 +++++++++++++++++++++++++++++++++++
 drivers/edac/edac_mce_amd.h         |   68 ++++++
 8 files changed, 604 insertions(+), 452 deletions(-)

-- 
Thanks,
  Boris.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/20] topology: introduce cpu_node information for multi-node processors
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 02/20] x86: provide CPU topology " Borislav Petkov
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andreas Herrmann

From: Andreas Herrmann <andreas.herrmann3@amd.com>

New topology attributes are
- cpu_node_id (id of the internal node)
- cpu_node_siblings and cpu_node_siblings_list
  (siblings on the same internal node)

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
---
 drivers/base/topology.c  |   10 ++++++++++
 include/linux/topology.h |    9 +++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index bf6b132..1e35a43 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -103,6 +103,9 @@ static ssize_t show_##name##_list(struct sys_device *dev,		\
 define_id_show_func(physical_package_id);
 define_one_ro(physical_package_id);
 
+define_id_show_func(cpu_node_id);
+define_one_ro(cpu_node_id);
+
 define_id_show_func(core_id);
 define_one_ro(core_id);
 
@@ -110,6 +113,10 @@ define_siblings_show_func(thread_cpumask);
 define_one_ro_named(thread_siblings, show_thread_cpumask);
 define_one_ro_named(thread_siblings_list, show_thread_cpumask_list);
 
+define_siblings_show_func(cpu_node_cpumask);
+define_one_ro_named(cpu_node_siblings, show_cpu_node_cpumask);
+define_one_ro_named(cpu_node_siblings_list, show_cpu_node_cpumask_list);
+
 define_siblings_show_func(core_cpumask);
 define_one_ro_named(core_siblings, show_core_cpumask);
 define_one_ro_named(core_siblings_list, show_core_cpumask_list);
@@ -119,6 +126,9 @@ static struct attribute *default_attrs[] = {
 	&attr_core_id.attr,
 	&attr_thread_siblings.attr,
 	&attr_thread_siblings_list.attr,
+	&attr_cpu_node_id.attr,
+	&attr_cpu_node_siblings.attr,
+	&attr_cpu_node_siblings_list.attr,
 	&attr_core_siblings.attr,
 	&attr_core_siblings_list.attr,
 	NULL
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 7402c1a..976a130 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -180,6 +180,9 @@ int arch_update_cpu_topology(void);
 #ifndef topology_physical_package_id
 #define topology_physical_package_id(cpu)	((void)(cpu), -1)
 #endif
+#ifndef topology_cpu_node_id
+#define topology_cpu_node_id(cpu)		((void)(cpu), 0)
+#endif
 #ifndef topology_core_id
 #define topology_core_id(cpu)			((void)(cpu), 0)
 #endif
@@ -189,12 +192,18 @@ int arch_update_cpu_topology(void);
 #ifndef topology_core_siblings
 #define topology_core_siblings(cpu)		cpumask_of_cpu(cpu)
 #endif
+#ifndef topology_cpu_node_siblings
+#define topology_cpu_node_siblings(cpu)		topology_core_siblings(cpu)
+#endif
 #ifndef topology_thread_cpumask
 #define topology_thread_cpumask(cpu)		cpumask_of(cpu)
 #endif
 #ifndef topology_core_cpumask
 #define topology_core_cpumask(cpu)		cpumask_of(cpu)
 #endif
+#ifndef topology_cpu_node_cpumask
+#define topology_cpu_node_cpumask(cpu)		topology_core_cpumask(cpu)
+#endif
 
 /* Returns the number of the current Node. */
 #ifndef numa_node_id
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 02/20] x86: provide CPU topology information for multi-node processors
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
  2009-07-28 15:06 ` [PATCH 01/20] topology: introduce cpu_node information for multi-node processors Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 03/20] x86: add cpu_node topology detection for AMD Magny-Cours Borislav Petkov
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andreas Herrmann

From: Andreas Herrmann <andreas.herrmann3@amd.com>

Provide topology_cpu_node_id, topology_cpu_node_mask and cpu_node_map.
CPUs with matching phys_proc_id and cpu_node_id belong to the same
cpu_node.

Also, use a cpuinfo_x86 ptr in the second loop too instead of deref-fing
cpu_info each time.

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/include/asm/processor.h |    2 ++
 arch/x86/include/asm/smp.h       |    6 ++++++
 arch/x86/include/asm/topology.h  |    2 ++
 arch/x86/kernel/cpu/common.c     |    2 ++
 arch/x86/kernel/cpu/proc.c       |    1 +
 arch/x86/kernel/smpboot.c        |   20 ++++++++++++++++----
 6 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c776826..74d9258 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -106,6 +106,8 @@ struct cpuinfo_x86 {
 	u16			booted_cores;
 	/* Physical processor id: */
 	u16			phys_proc_id;
+	/* Node id in case of multi-node processor: */
+	u16			cpu_node_id;
 	/* Core id: */
 	u16			cpu_core_id;
 	/* Index into per_cpu list: */
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 6a84ed1..aad37c6 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -22,6 +22,7 @@ extern int smp_num_siblings;
 extern unsigned int num_processors;
 
 DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_node_map);
 DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
 DECLARE_PER_CPU(u16, cpu_llc_id);
 DECLARE_PER_CPU(int, cpu_number);
@@ -31,6 +32,11 @@ static inline struct cpumask *cpu_sibling_mask(int cpu)
 	return per_cpu(cpu_sibling_map, cpu);
 }
 
+static inline struct cpumask *cpu_node_mask(int cpu)
+{
+	return per_cpu(cpu_node_map, cpu);
+}
+
 static inline struct cpumask *cpu_core_mask(int cpu)
 {
 	return per_cpu(cpu_core_map, cpu);
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 066ef59..9eddb69 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -190,6 +190,8 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu);
 #define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
 #define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
 #define topology_thread_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))
+#define topology_cpu_node_id(cpu)		(cpu_data(cpu).cpu_node_id)
+#define topology_cpu_node_cpumask(cpu)		(per_cpu(cpu_node_map, cpu))
 
 /* indicates that pointers to the topology cpumask_t maps are valid */
 #define arch_provides_topology_pointers		yes
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f1961c0..60db9b5 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -478,6 +478,8 @@ out:
 	if ((c->x86_max_cores * smp_num_siblings) > 1) {
 		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
 		       c->phys_proc_id);
+		printk(KERN_INFO  "CPU: Processor Node ID: %d\n",
+		       c->cpu_node_id);
 		printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
 		       c->cpu_core_id);
 	}
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index d5e3039..ff539c1 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -15,6 +15,7 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
 		seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
 		seq_printf(m, "siblings\t: %d\n",
 			   cpumask_weight(cpu_core_mask(cpu)));
+		seq_printf(m, "node id\t\t: %d\n", c->cpu_node_id);
 		seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
 		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
 		seq_printf(m, "apicid\t\t: %d\n", c->apicid);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 2fecda6..d138c4e 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -108,6 +108,10 @@ EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
 DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
 EXPORT_PER_CPU_SYMBOL(cpu_core_map);
 
+/* representing node silbings on multi-node CPU */
+DEFINE_PER_CPU(cpumask_var_t, cpu_node_map);
+EXPORT_PER_CPU_SYMBOL(cpu_node_map);
+
 /* Per CPU bogomips and other parameters */
 DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
@@ -396,12 +400,19 @@ void __cpuinit set_cpu_sibling_map(int cpu)
 	}
 
 	for_each_cpu(i, cpu_sibling_setup_mask) {
+		struct cpuinfo_x86 *o = &cpu_data(i);
+
 		if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
 		    per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
 			cpumask_set_cpu(i, c->llc_shared_map);
-			cpumask_set_cpu(cpu, cpu_data(i).llc_shared_map);
+			cpumask_set_cpu(cpu, o->llc_shared_map);
+		}
+		if ((c->phys_proc_id == o->phys_proc_id) &&
+		    (c->cpu_node_id == o->cpu_node_id)) {
+			cpumask_set_cpu(i, cpu_node_mask(cpu));
+			cpumask_set_cpu(cpu, cpu_node_mask(i));
 		}
-		if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
+		if (c->phys_proc_id == o->phys_proc_id) {
 			cpumask_set_cpu(i, cpu_core_mask(cpu));
 			cpumask_set_cpu(cpu, cpu_core_mask(i));
 			/*
@@ -419,9 +430,9 @@ void __cpuinit set_cpu_sibling_map(int cpu)
 				 * the other cpus in this package
 				 */
 				if (i != cpu)
-					cpu_data(i).booted_cores++;
+					o->booted_cores++;
 			} else if (i != cpu && !c->booted_cores)
-				c->booted_cores = cpu_data(i).booted_cores;
+				c->booted_cores = o->booted_cores;
 		}
 	}
 }
@@ -1220,6 +1231,7 @@ static void remove_siblinginfo(int cpu)
 	cpumask_clear(cpu_sibling_mask(cpu));
 	cpumask_clear(cpu_core_mask(cpu));
 	c->phys_proc_id = 0;
+	c->cpu_node_id = 0;
 	c->cpu_core_id = 0;
 	cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
 }
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 03/20] x86: add cpu_node topology detection for AMD Magny-Cours
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
  2009-07-28 15:06 ` [PATCH 01/20] topology: introduce cpu_node information for multi-node processors Borislav Petkov
  2009-07-28 15:06 ` [PATCH 02/20] x86: provide CPU topology " Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 04/20] x86: cacheinfo: fixup L3 cache information " Borislav Petkov
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andreas Herrmann

From: Andreas Herrmann <andreas.herrmann3@amd.com>

This adapts CPU topology detection for AMD Magny-Cours.

Here is example output from two cores on same package but different
internal cpu_nodes:

/sys/devices/system/cpu/cpu5:
  physical_package_id        : 0
  core_id                    : 5
  thread_siblings            : 00000020
  thread_siblings_list       : 5
  cpu_node_id                : 0
  cpu_node_siblings          : 0000003f
  cpu_node_siblings_list     : 0-5
  core_siblings              : 00000fff
  core_siblings_list         : 0-11
/sys/devices/system/cpu/cpu6:
  physical_package_id        : 0
  core_id                    : 0
  thread_siblings            : 00000040
  thread_siblings_list       : 6
  cpu_node_id                : 1
  cpu_node_siblings          : 00000fc0
  cpu_node_siblings_list     : 6-11
  core_siblings              : 00000fff
  core_siblings_list         : 0-11

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
---
 arch/x86/include/asm/cpufeature.h |    1 +
 arch/x86/kernel/cpu/amd.c         |   59 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 4a28d22..847fee6 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -95,6 +95,7 @@
 #define X86_FEATURE_NONSTOP_TSC	(3*32+24) /* TSC does not stop in C states */
 #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
 #define X86_FEATURE_EXTD_APICID	(3*32+26) /* has extended APICID (8 bits) */
+#define X86_FEATURE_AMD_DCM     (3*32+27) /* multi-node processor */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index e2485b0..d90abeb 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -251,6 +251,56 @@ static int __cpuinit nearby_node(int apicid)
 #endif
 
 /*
+ * Fixup core topology information for AMD multi-node processors.
+ * Assumption 1: Number of cores in each internal node is the same.
+ * Assumption 2: Mixed systems with both single-node and dual-node
+ *               processors are not supported.
+ */
+static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
+{
+	u32 t, cpn;
+	u8 n;
+
+	/* fixup topology information only once for a core */
+	if (cpu_has(c, X86_FEATURE_AMD_DCM))
+		return;
+
+	/* check for multi-node processor on boot cpu */
+	t = read_pci_config(0, 24, 3, 0xe8);
+	if (!(t & (1 << 29)))
+		return;
+
+	set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+
+	/* cores per node: each internal node has half the number of cores */
+	cpn = c->x86_max_cores >> 1;
+
+	/* even-numbered NB_id of this dual-node processor */
+	n = c->phys_proc_id << 1;
+
+	/*
+	 * determine internal node id and assign cores fifty-fifty to
+	 * each node of the dual-node processor
+	 */
+	t = read_pci_config(0, 24 + n, 3, 0xe8);
+	n = (t>>30) & 0x3;
+	if (n == 0) {
+		if (c->cpu_core_id < cpn)
+			c->cpu_node_id = 0;
+		else
+			c->cpu_node_id = 1;
+	} else {
+		if (c->cpu_core_id < cpn)
+			c->cpu_node_id = 1;
+		else
+			c->cpu_node_id = 0;
+	}
+
+	 /* fixup core id to be in range from 0 to cpn */
+	c->cpu_core_id = c->cpu_core_id % cpn;
+}
+
+/*
  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
  * Assumes number of cores is a power of two.
  */
@@ -267,6 +317,9 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
 	c->phys_proc_id = c->initial_apicid >> bits;
 	/* use socket ID also for last level cache */
 	per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+	/* fixup topology information on multi-node processors */
+	if ((c->x86 == 0x10) && (c->x86_model == 9))
+		amd_fixup_dcm(c);
 #endif
 }
 
@@ -277,7 +330,11 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
 	int node;
 	unsigned apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
 
-	node = c->phys_proc_id;
+	if (cpu_has(c, X86_FEATURE_AMD_DCM))
+		node = (c->phys_proc_id << 1) + c->cpu_node_id;
+	else
+		node = c->phys_proc_id;
+
 	if (apicid_to_node[apicid] != NUMA_NO_NODE)
 		node = apicid_to_node[apicid];
 	if (!node_online(node)) {
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 04/20] x86: cacheinfo: fixup L3 cache information for AMD Magny-Cours
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (2 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 03/20] x86: add cpu_node topology detection for AMD Magny-Cours Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 05/20] x86: mcheck: make use of cpu_node_mask instead of cpu_core_mask to support multi-node processors Borislav Petkov
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andreas Herrmann

From: Andreas Herrmann <andreas.herrmann3@amd.com>

L3 cache size, associativity and shared_cpu information need to be
adapted to show information for an internal node instead of the
entire physical package.

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 789efe2..3b54a1e 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -241,7 +241,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	case 0:
 		if (!l1->val)
 			return;
-		assoc = l1->assoc;
+		assoc = assocs[l1->assoc];
 		line_size = l1->line_size;
 		lines_per_tag = l1->lines_per_tag;
 		size_in_kb = l1->size_in_kb;
@@ -249,7 +249,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	case 2:
 		if (!l2.val)
 			return;
-		assoc = l2.assoc;
+		assoc = assocs[l2.assoc];
 		line_size = l2.line_size;
 		lines_per_tag = l2.lines_per_tag;
 		/* cpu_data has errata corrections for K7 applied */
@@ -258,10 +258,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	case 3:
 		if (!l3.val)
 			return;
-		assoc = l3.assoc;
+		assoc = assocs[l3.assoc];
 		line_size = l3.line_size;
 		lines_per_tag = l3.lines_per_tag;
 		size_in_kb = l3.size_encoded * 512;
+		if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
+			size_in_kb = size_in_kb >> 1;
+			assoc = assoc >> 1;
+		}
 		break;
 	default:
 		return;
@@ -278,10 +282,10 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
 
 
-	if (assoc == 0xf)
+	if (assoc == 0xffff)
 		eax->split.is_fully_associative = 1;
 	ebx->split.coherency_line_size = line_size - 1;
-	ebx->split.ways_of_associativity = assocs[assoc] - 1;
+	ebx->split.ways_of_associativity = assoc - 1;
 	ebx->split.physical_line_partition = lines_per_tag - 1;
 	ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
 		(ebx->split.ways_of_associativity + 1) - 1;
@@ -598,7 +602,11 @@ static void __cpuinit get_cpu_leaves(void *_retval)
 				cache_remove_shared_cpu_map(cpu, i);
 			break;
 		}
-		cache_shared_cpu_map_setup(cpu, j);
+		if (boot_cpu_has(X86_FEATURE_AMD_DCM))
+			cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
+				     topology_cpu_node_cpumask(cpu));
+		else
+			cache_shared_cpu_map_setup(cpu, j);
 	}
 }
 
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 05/20] x86: mcheck: make use of cpu_node_mask instead of cpu_core_mask to support multi-node processors
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (3 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 04/20] x86: cacheinfo: fixup L3 cache information " Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 06/20] EDAC: move MCE error descriptions to EDAC core Borislav Petkov
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andreas Herrmann

From: Andreas Herrmann <andreas.herrmann3@amd.com>

This fixes threshold_bank4 support.

We need to create symlinks for sibling shared banks to first core of
each internal node and not to first core of one internal node.

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
---
 arch/x86/kernel/cpu/mcheck/mce_amd.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index ddae216..595cbe5 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -494,7 +494,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 
 #ifdef CONFIG_SMP
 	if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {	/* symlink */
-		i = cpumask_first(cpu_core_mask(cpu));
+		i = cpumask_first(cpu_node_mask(cpu));
 
 		/* first core not up yet */
 		if (cpu_data(i).cpu_core_id)
@@ -514,7 +514,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 		if (err)
 			goto out;
 
-		cpumask_copy(b->cpus, cpu_core_mask(cpu));
+		cpumask_copy(b->cpus, cpu_node_mask(cpu));
 		per_cpu(threshold_banks, cpu)[bank] = b;
 
 		goto out;
@@ -539,7 +539,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 #ifndef CONFIG_SMP
 	cpumask_setall(b->cpus);
 #else
-	cpumask_copy(b->cpus, cpu_core_mask(cpu));
+	cpumask_copy(b->cpus, cpu_node_mask(cpu));
 #endif
 
 	per_cpu(threshold_banks, cpu)[bank] = b;
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 06/20] EDAC: move MCE error descriptions to EDAC core
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (4 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 05/20] x86: mcheck: make use of cpu_node_mask instead of cpu_core_mask to support multi-node processors Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 07/20] EDAC: beef up ErrorCodeExt error signatures Borislav Petkov
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

This is in preparation of adding AMD-specific MCE decoding functionality
to the EDAC core. The error decoding macros originate from the AMD64
EDAC driver albeit in a simplified and cleaned up version here.

While at it, add macros to generate the error description strings and
use them in the error type decoders directly which removes a bunch of
code and makes the decoding functions much more readable. Also, fix
strings and shorten macro names.

Remove superfluous htlink_msgs.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/Makefile               |    6 +-
 drivers/edac/amd64_edac.c           |  140 +++++++++++++++++-------------
 drivers/edac/amd64_edac.h           |   17 +----
 drivers/edac/amd64_edac_err_types.c |  161 -----------------------------------
 drivers/edac/edac_mce_amd.c         |  101 ++++++++++++++++++++++
 drivers/edac/edac_mce_amd.h         |   29 ++++++
 6 files changed, 214 insertions(+), 240 deletions(-)
 delete mode 100644 drivers/edac/amd64_edac_err_types.c
 create mode 100644 drivers/edac/edac_mce_amd.c
 create mode 100644 drivers/edac/edac_mce_amd.h

diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 98aa4a7..cfa033c 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -17,6 +17,10 @@ ifdef CONFIG_PCI
 edac_core-objs	+= edac_pci.o edac_pci_sysfs.o
 endif
 
+ifdef CONFIG_CPU_SUP_AMD
+edac_core-objs  += edac_mce_amd.o
+endif
+
 obj-$(CONFIG_EDAC_AMD76X)		+= amd76x_edac.o
 obj-$(CONFIG_EDAC_CPC925)		+= cpc925_edac.o
 obj-$(CONFIG_EDAC_I5000)		+= i5000_edac.o
@@ -32,7 +36,7 @@ obj-$(CONFIG_EDAC_X38)			+= x38_edac.o
 obj-$(CONFIG_EDAC_I82860)		+= i82860_edac.o
 obj-$(CONFIG_EDAC_R82600)		+= r82600_edac.o
 
-amd64_edac_mod-y :=  amd64_edac_err_types.o amd64_edac.o
+amd64_edac_mod-y := amd64_edac.o
 amd64_edac_mod-$(CONFIG_EDAC_DEBUG) += amd64_edac_dbg.o
 amd64_edac_mod-$(CONFIG_EDAC_AMD64_ERROR_INJECTION) += amd64_edac_inj.o
 
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 24964c1..7655ba1 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -19,6 +19,63 @@ static struct mem_ctl_info *mci_lookup[MAX_NUMNODES];
 static struct amd64_pvt *pvt_lookup[MAX_NUMNODES];
 
 /*
+ * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
+ * for DDR2 DRAM mapping.
+ */
+u32 revf_quad_ddr2_shift[] = {
+	0,	/* 0000b NULL DIMM (128mb) */
+	28,	/* 0001b 256mb */
+	29,	/* 0010b 512mb */
+	29,	/* 0011b 512mb */
+	29,	/* 0100b 512mb */
+	30,	/* 0101b 1gb */
+	30,	/* 0110b 1gb */
+	31,	/* 0111b 2gb */
+	31,	/* 1000b 2gb */
+	32,	/* 1001b 4gb */
+	32,	/* 1010b 4gb */
+	33,	/* 1011b 8gb */
+	0,	/* 1100b future */
+	0,	/* 1101b future */
+	0,	/* 1110b future */
+	0	/* 1111b future */
+};
+
+/*
+ * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing
+ * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
+ * or higher value'.
+ *
+ *FIXME: Produce a better mapping/linearisation.
+ */
+
+struct scrubrate scrubrates[] = {
+	{ 0x01, 1600000000UL},
+	{ 0x02, 800000000UL},
+	{ 0x03, 400000000UL},
+	{ 0x04, 200000000UL},
+	{ 0x05, 100000000UL},
+	{ 0x06, 50000000UL},
+	{ 0x07, 25000000UL},
+	{ 0x08, 12284069UL},
+	{ 0x09, 6274509UL},
+	{ 0x0A, 3121951UL},
+	{ 0x0B, 1560975UL},
+	{ 0x0C, 781440UL},
+	{ 0x0D, 390720UL},
+	{ 0x0E, 195300UL},
+	{ 0x0F, 97650UL},
+	{ 0x10, 48854UL},
+	{ 0x11, 24427UL},
+	{ 0x12, 12213UL},
+	{ 0x13, 6101UL},
+	{ 0x14, 3051UL},
+	{ 0x15, 1523UL},
+	{ 0x16, 761UL},
+	{ 0x00, 0UL},        /* scrubbing off */
+};
+
+/*
  * Memory scrubber control interface. For K8, memory scrubbing is handled by
  * hardware and can involve L2 cache, dcache as well as the main memory. With
  * F10, this is extended to L3 cache scrubbing on CPU models sporting that
@@ -1099,8 +1156,8 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 	u32 page, offset;
 
 	/* Extract the syndrome parts and form a 16-bit syndrome */
-	syndrome = EXTRACT_HIGH_SYNDROME(info->nbsl) << 8;
-	syndrome |= EXTRACT_LOW_SYNDROME(info->nbsh);
+	syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
+	syndrome |= LOW_SYNDROME(info->nbsh);
 
 	/* CHIPKILL enabled */
 	if (info->nbcfg & K8_NBCFG_CHIPKILL) {
@@ -1699,8 +1756,8 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 	if (csrow >= 0) {
 		error_address_to_page_and_offset(sys_addr, &page, &offset);
 
-		syndrome = EXTRACT_HIGH_SYNDROME(info->nbsl) << 8;
-		syndrome |= EXTRACT_LOW_SYNDROME(info->nbsh);
+		syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
+		syndrome |= LOW_SYNDROME(info->nbsh);
 
 		/*
 		 * Is CHIPKILL on? If so, then we can attempt to use the
@@ -2153,36 +2210,22 @@ static int amd64_get_error_info(struct mem_ctl_info *mci,
 static inline void amd64_decode_gart_tlb_error(struct mem_ctl_info *mci,
 					 struct amd64_error_info_regs *info)
 {
-	u32 err_code;
-	u32 ec_tt;		/* error code transaction type (2b) */
-	u32 ec_ll;		/* error code cache level (2b) */
-
-	err_code = EXTRACT_ERROR_CODE(info->nbsl);
-	ec_ll = EXTRACT_LL_CODE(err_code);
-	ec_tt = EXTRACT_TT_CODE(err_code);
+	u32 ec = ERROR_CODE(info->nbsl);
 
 	amd64_mc_printk(mci, KERN_ERR,
 		     "GART TLB event: transaction type(%s), "
-		     "cache level(%s)\n", tt_msgs[ec_tt], ll_msgs[ec_ll]);
+		     "cache level(%s)\n", TT_MSG(ec), LL_MSG(ec));
 }
 
 static inline void amd64_decode_mem_cache_error(struct mem_ctl_info *mci,
 				      struct amd64_error_info_regs *info)
 {
-	u32 err_code;
-	u32 ec_rrrr;		/* error code memory transaction (4b) */
-	u32 ec_tt;		/* error code transaction type (2b) */
-	u32 ec_ll;		/* error code cache level (2b) */
-
-	err_code = EXTRACT_ERROR_CODE(info->nbsl);
-	ec_ll = EXTRACT_LL_CODE(err_code);
-	ec_tt = EXTRACT_TT_CODE(err_code);
-	ec_rrrr = EXTRACT_RRRR_CODE(err_code);
+	u32 ec = ERROR_CODE(info->nbsl);
 
 	amd64_mc_printk(mci, KERN_ERR,
 		     "cache hierarchy error: memory transaction type(%s), "
 		     "transaction type(%s), cache level(%s)\n",
-		     rrrr_msgs[ec_rrrr], tt_msgs[ec_tt], ll_msgs[ec_ll]);
+		     RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
 }
 
 
@@ -2262,21 +2305,8 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
 static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 				   struct amd64_error_info_regs *info)
 {
-	u32 err_code, ext_ec;
-	u32 ec_pp;		/* error code participating processor (2p) */
-	u32 ec_to;		/* error code timed out (1b) */
-	u32 ec_rrrr;		/* error code memory transaction (4b) */
-	u32 ec_ii;		/* error code memory or I/O (2b) */
-	u32 ec_ll;		/* error code cache level (2b) */
-
-	ext_ec = EXTRACT_EXT_ERROR_CODE(info->nbsl);
-	err_code = EXTRACT_ERROR_CODE(info->nbsl);
-
-	ec_ll = EXTRACT_LL_CODE(err_code);
-	ec_ii = EXTRACT_II_CODE(err_code);
-	ec_rrrr = EXTRACT_RRRR_CODE(err_code);
-	ec_to = EXTRACT_TO_CODE(err_code);
-	ec_pp = EXTRACT_PP_CODE(err_code);
+	u32 ec  = ERROR_CODE(info->nbsl);
+	u32 xec = EXT_ERROR_CODE(info->nbsl);
 
 	amd64_mc_printk(mci, KERN_ERR,
 		"BUS ERROR:\n"
@@ -2284,20 +2314,17 @@ static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 		"  participating processor(%s)\n"
 		"  memory transaction type(%s)\n"
 		"  cache level(%s) Error Found by: %s\n",
-		to_msgs[ec_to],
-		ii_msgs[ec_ii],
-		pp_msgs[ec_pp],
-		rrrr_msgs[ec_rrrr],
-		ll_msgs[ec_ll],
+		TO_MSG(ec), II_MSG(ec), PP_MSG(ec), RRRR_MSG(ec), LL_MSG(ec),
 		(info->nbsh & K8_NBSH_ERR_SCRUBER) ?
 			"Scrubber" : "Normal Operation");
 
-	/* If this was an 'observed' error, early out */
-	if (ec_pp == K8_NBSL_PP_OBS)
-		return;		/* We aren't the node involved */
+
+	/* Bail early out if this was an 'observed' error */
+	if (PP(ec) == K8_NBSL_PP_OBS)
+		return;
 
 	/* Parse out the extended error code for ECC events */
-	switch (ext_ec) {
+	switch (xec) {
 	/* F10 changed to one Extended ECC error code */
 	case F10_NBSL_EXT_ERR_RES:		/* Reserved field */
 	case F10_NBSL_EXT_ERR_ECC:		/* F10 ECC ext err code */
@@ -2377,7 +2404,7 @@ int amd64_process_error_info(struct mem_ctl_info *mci,
 		(regs->nbsh & K8_NBSH_CORE3) ? "True" : "False");
 
 
-	err_code = EXTRACT_ERROR_CODE(regs->nbsl);
+	err_code = ERROR_CODE(regs->nbsl);
 
 	/* Determine which error type:
 	 *	1) GART errors - non-fatal, developmental events
@@ -2385,7 +2412,7 @@ int amd64_process_error_info(struct mem_ctl_info *mci,
 	 *	3) BUS errors
 	 *	4) Unknown error
 	 */
-	if (TEST_TLB_ERROR(err_code)) {
+	if (TLB_ERROR(err_code)) {
 		/*
 		 * GART errors are intended to help graphics driver developers
 		 * to detect bad GART PTEs. It is recommended by AMD to disable
@@ -2409,10 +2436,10 @@ int amd64_process_error_info(struct mem_ctl_info *mci,
 
 		debugf1("GART TLB error\n");
 		amd64_decode_gart_tlb_error(mci, info);
-	} else if (TEST_MEM_ERROR(err_code)) {
+	} else if (MEM_ERROR(err_code)) {
 		debugf1("Memory/Cache error\n");
 		amd64_decode_mem_cache_error(mci, info);
-	} else if (TEST_BUS_ERROR(err_code)) {
+	} else if (BUS_ERROR(err_code)) {
 		debugf1("Bus (Link/DRAM) error\n");
 		amd64_decode_bus_error(mci, info);
 	} else {
@@ -2422,21 +2449,10 @@ int amd64_process_error_info(struct mem_ctl_info *mci,
 			     err_code);
 	}
 
-	ext_ec = EXTRACT_EXT_ERROR_CODE(regs->nbsl);
+	ext_ec = EXT_ERROR_CODE(regs->nbsl);
 	amd64_mc_printk(mci, KERN_ERR,
 		"ExtErr=(0x%x) %s\n", ext_ec, ext_msgs[ext_ec]);
 
-	if (((ext_ec >= F10_NBSL_EXT_ERR_CRC &&
-			ext_ec <= F10_NBSL_EXT_ERR_TGT) ||
-			(ext_ec == F10_NBSL_EXT_ERR_RMW)) &&
-			EXTRACT_LDT_LINK(info->nbsh)) {
-
-		amd64_mc_printk(mci, KERN_ERR,
-			"Error on hypertransport link: %s\n",
-			htlink_msgs[
-			EXTRACT_LDT_LINK(info->nbsh)]);
-	}
-
 	/*
 	 * Check the UE bit of the NB status high register, if set generate some
 	 * logs. If NOT a GART error, then process the event as a NO-INFO event.
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index ba73015..1ddef8d 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -72,6 +72,7 @@
 #include <linux/edac.h>
 #include <asm/msr.h>
 #include "edac_core.h"
+#include "edac_mce_amd.h"
 
 #define amd64_printk(level, fmt, arg...) \
 	edac_printk(level, "amd64", fmt, ##arg)
@@ -303,9 +304,6 @@ enum {
 #define K8_NBSL				0x48
 
 
-#define EXTRACT_HIGH_SYNDROME(x)	(((x) >> 24) & 0xff)
-#define EXTRACT_EXT_ERROR_CODE(x)	(((x) >> 16) & 0x1f)
-
 /* Family F10h: Normalized Extended Error Codes */
 #define F10_NBSL_EXT_ERR_RES		0x0
 #define F10_NBSL_EXT_ERR_CRC		0x1
@@ -348,17 +346,6 @@ enum {
 #define K8_NBSL_EXT_ERR_CHIPKILL_ECC	0x8
 #define K8_NBSL_EXT_ERR_DRAM_PARITY	0xD
 
-#define EXTRACT_ERROR_CODE(x)		((x) & 0xffff)
-#define	TEST_TLB_ERROR(x)		(((x) & 0xFFF0) == 0x0010)
-#define	TEST_MEM_ERROR(x)		(((x) & 0xFF00) == 0x0100)
-#define	TEST_BUS_ERROR(x)		(((x) & 0xF800) == 0x0800)
-#define	EXTRACT_TT_CODE(x)		(((x) >> 2) & 0x3)
-#define	EXTRACT_II_CODE(x)		(((x) >> 2) & 0x3)
-#define	EXTRACT_LL_CODE(x)		(((x) >> 0) & 0x3)
-#define	EXTRACT_RRRR_CODE(x)		(((x) >> 4) & 0xf)
-#define	EXTRACT_TO_CODE(x)		(((x) >> 8) & 0x1)
-#define	EXTRACT_PP_CODE(x)		(((x) >> 9) & 0x3)
-
 /*
  * The following are for BUS type errors AFTER values have been normalized by
  * shifting right
@@ -386,9 +373,7 @@ enum {
 #define K8_NBSH_CORE1			BIT(1)
 #define K8_NBSH_CORE0			BIT(0)
 
-#define EXTRACT_LDT_LINK(x)		(((x) >> 4) & 0x7)
 #define EXTRACT_ERR_CPU_MAP(x)		((x) & 0xF)
-#define EXTRACT_LOW_SYNDROME(x)		(((x) >> 15) & 0xff)
 
 
 #define K8_NBEAL			0x50
diff --git a/drivers/edac/amd64_edac_err_types.c b/drivers/edac/amd64_edac_err_types.c
deleted file mode 100644
index f212ff1..0000000
--- a/drivers/edac/amd64_edac_err_types.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#include "amd64_edac.h"
-
-/*
- * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
- * for DDR2 DRAM mapping.
- */
-u32 revf_quad_ddr2_shift[] = {
-	0,	/* 0000b NULL DIMM (128mb) */
-	28,	/* 0001b 256mb */
-	29,	/* 0010b 512mb */
-	29,	/* 0011b 512mb */
-	29,	/* 0100b 512mb */
-	30,	/* 0101b 1gb */
-	30,	/* 0110b 1gb */
-	31,	/* 0111b 2gb */
-	31,	/* 1000b 2gb */
-	32,	/* 1001b 4gb */
-	32,	/* 1010b 4gb */
-	33,	/* 1011b 8gb */
-	0,	/* 1100b future */
-	0,	/* 1101b future */
-	0,	/* 1110b future */
-	0	/* 1111b future */
-};
-
-/*
- * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing
- * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
- * or higher value'.
- *
- *FIXME: Produce a better mapping/linearisation.
- */
-
-struct scrubrate scrubrates[] = {
-	{ 0x01, 1600000000UL},
-	{ 0x02, 800000000UL},
-	{ 0x03, 400000000UL},
-	{ 0x04, 200000000UL},
-	{ 0x05, 100000000UL},
-	{ 0x06, 50000000UL},
-	{ 0x07, 25000000UL},
-	{ 0x08, 12284069UL},
-	{ 0x09, 6274509UL},
-	{ 0x0A, 3121951UL},
-	{ 0x0B, 1560975UL},
-	{ 0x0C, 781440UL},
-	{ 0x0D, 390720UL},
-	{ 0x0E, 195300UL},
-	{ 0x0F, 97650UL},
-	{ 0x10, 48854UL},
-	{ 0x11, 24427UL},
-	{ 0x12, 12213UL},
-	{ 0x13, 6101UL},
-	{ 0x14, 3051UL},
-	{ 0x15, 1523UL},
-	{ 0x16, 761UL},
-	{ 0x00, 0UL},        /* scrubbing off */
-};
-
-/*
- * string representation for the different MCA reported error types, see F3x48
- * or MSR0000_0411.
- */
-const char *tt_msgs[] = {        /* transaction type */
-	"instruction",
-	"data",
-	"generic",
-	"reserved"
-};
-
-const char *ll_msgs[] = {	/* cache level */
-	"L0",
-	"L1",
-	"L2",
-	"L3/generic"
-};
-
-const char *rrrr_msgs[] = {
-	"generic",
-	"generic read",
-	"generic write",
-	"data read",
-	"data write",
-	"inst fetch",
-	"prefetch",
-	"evict",
-	"snoop",
-	"reserved RRRR= 9",
-	"reserved RRRR= 10",
-	"reserved RRRR= 11",
-	"reserved RRRR= 12",
-	"reserved RRRR= 13",
-	"reserved RRRR= 14",
-	"reserved RRRR= 15"
-};
-
-const char *pp_msgs[] = {	/* participating processor */
-	"local node originated (SRC)",
-	"local node responded to request (RES)",
-	"local node observed as 3rd party (OBS)",
-	"generic"
-};
-
-const char *to_msgs[] = {
-	"no timeout",
-	"timed out"
-};
-
-const char *ii_msgs[] = {	/* memory or i/o */
-	"mem access",
-	"reserved",
-	"i/o access",
-	"generic"
-};
-
-/* Map the 5 bits of Extended Error code to the string table. */
-const char *ext_msgs[] = {	/* extended error */
-	"K8 ECC error/F10 reserved",	/* 0_0000b */
-	"CRC error",			/* 0_0001b */
-	"sync error",			/* 0_0010b */
-	"mst abort",			/* 0_0011b */
-	"tgt abort",			/* 0_0100b */
-	"GART error",			/* 0_0101b */
-	"RMW error",			/* 0_0110b */
-	"Wdog timer error",		/* 0_0111b */
-	"F10-ECC/K8-Chipkill error",	/* 0_1000b */
-	"DEV Error",			/* 0_1001b */
-	"Link Data error",		/* 0_1010b */
-	"Link or L3 Protocol error",	/* 0_1011b */
-	"NB Array error",		/* 0_1100b */
-	"DRAM Parity error",		/* 0_1101b */
-	"Link Retry/GART Table Walk/DEV Table Walk error", /* 0_1110b */
-	"Res 0x0ff error",		/* 0_1111b */
-	"Res 0x100 error",		/* 1_0000b */
-	"Res 0x101 error",		/* 1_0001b */
-	"Res 0x102 error",		/* 1_0010b */
-	"Res 0x103 error",		/* 1_0011b */
-	"Res 0x104 error",		/* 1_0100b */
-	"Res 0x105 error",		/* 1_0101b */
-	"Res 0x106 error",		/* 1_0110b */
-	"Res 0x107 error",		/* 1_0111b */
-	"Res 0x108 error",		/* 1_1000b */
-	"Res 0x109 error",		/* 1_1001b */
-	"Res 0x10A error",		/* 1_1010b */
-	"Res 0x10B error",		/* 1_1011b */
-	"L3 Cache Data error",		/* 1_1100b */
-	"L3 CacheTag error",		/* 1_1101b */
-	"L3 Cache LRU error",		/* 1_1110b */
-	"Res 0x1FF error"		/* 1_1111b */
-};
-
-const char *htlink_msgs[] = {
-	"none",
-	"1",
-	"2",
-	"1 2",
-	"3",
-	"1 3",
-	"2 3",
-	"1 2 3"
-};
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
new file mode 100644
index 0000000..cf84654
--- /dev/null
+++ b/drivers/edac/edac_mce_amd.c
@@ -0,0 +1,101 @@
+#include <linux/module.h>
+#include "edac_mce_amd.h"
+
+/*
+ * string representation for the different MCA reported error types, see F3x48
+ * or MSR0000_0411.
+ */
+const char *tt_msgs[] = {        /* transaction type */
+	"instruction",
+	"data",
+	"generic",
+	"reserved"
+};
+EXPORT_SYMBOL_GPL(tt_msgs);
+
+const char *ll_msgs[] = {	/* cache level */
+	"L0",
+	"L1",
+	"L2",
+	"L3/generic"
+};
+EXPORT_SYMBOL_GPL(ll_msgs);
+
+const char *rrrr_msgs[] = {
+	"generic",
+	"generic read",
+	"generic write",
+	"data read",
+	"data write",
+	"inst fetch",
+	"prefetch",
+	"evict",
+	"snoop",
+	"reserved RRRR= 9",
+	"reserved RRRR= 10",
+	"reserved RRRR= 11",
+	"reserved RRRR= 12",
+	"reserved RRRR= 13",
+	"reserved RRRR= 14",
+	"reserved RRRR= 15"
+};
+EXPORT_SYMBOL_GPL(rrrr_msgs);
+
+const char *pp_msgs[] = {	/* participating processor */
+	"local node originated (SRC)",
+	"local node responded to request (RES)",
+	"local node observed as 3rd party (OBS)",
+	"generic"
+};
+EXPORT_SYMBOL_GPL(pp_msgs);
+
+const char *to_msgs[] = {
+	"no timeout",
+	"timed out"
+};
+EXPORT_SYMBOL_GPL(to_msgs);
+
+const char *ii_msgs[] = {	/* memory or i/o */
+	"mem access",
+	"reserved",
+	"i/o access",
+	"generic"
+};
+EXPORT_SYMBOL_GPL(ii_msgs);
+
+/* Map the 5 bits of Extended Error code to the string table. */
+const char *ext_msgs[] = {	/* extended error */
+	"K8 ECC error/F10 reserved",	/* 0_0000b */
+	"CRC error",			/* 0_0001b */
+	"sync error",			/* 0_0010b */
+	"mst abort",			/* 0_0011b */
+	"tgt abort",			/* 0_0100b */
+	"GART error",			/* 0_0101b */
+	"RMW error",			/* 0_0110b */
+	"Wdog timer error",		/* 0_0111b */
+	"F10-ECC/K8-Chipkill error",	/* 0_1000b */
+	"DEV Error",			/* 0_1001b */
+	"Link Data error",		/* 0_1010b */
+	"Link or L3 Protocol error",	/* 0_1011b */
+	"NB Array error",		/* 0_1100b */
+	"DRAM Parity error",		/* 0_1101b */
+	"Link Retry/GART Table Walk/DEV Table Walk error", /* 0_1110b */
+	"Res 0x0ff error",		/* 0_1111b */
+	"Res 0x100 error",		/* 1_0000b */
+	"Res 0x101 error",		/* 1_0001b */
+	"Res 0x102 error",		/* 1_0010b */
+	"Res 0x103 error",		/* 1_0011b */
+	"Res 0x104 error",		/* 1_0100b */
+	"Res 0x105 error",		/* 1_0101b */
+	"Res 0x106 error",		/* 1_0110b */
+	"Res 0x107 error",		/* 1_0111b */
+	"Res 0x108 error",		/* 1_1000b */
+	"Res 0x109 error",		/* 1_1001b */
+	"Res 0x10A error",		/* 1_1010b */
+	"Res 0x10B error",		/* 1_1011b */
+	"L3 Cache Data error",		/* 1_1100b */
+	"L3 CacheTag error",		/* 1_1101b */
+	"L3 Cache LRU error",		/* 1_1110b */
+	"Res 0x1FF error"		/* 1_1111b */
+};
+EXPORT_SYMBOL_GPL(ext_msgs);
diff --git a/drivers/edac/edac_mce_amd.h b/drivers/edac/edac_mce_amd.h
new file mode 100644
index 0000000..aea3863
--- /dev/null
+++ b/drivers/edac/edac_mce_amd.h
@@ -0,0 +1,29 @@
+#define ERROR_CODE(x)			((x) & 0xffff)
+#define EXT_ERROR_CODE(x)		(((x) >> 16) & 0x1f)
+#define LOW_SYNDROME(x)			(((x) >> 15) & 0xff)
+#define HIGH_SYNDROME(x)		(((x) >> 24) & 0xff)
+
+#define	TLB_ERROR(x)			(((x) & 0xFFF0) == 0x0010)
+#define	MEM_ERROR(x)			(((x) & 0xFF00) == 0x0100)
+#define	BUS_ERROR(x)			(((x) & 0xF800) == 0x0800)
+
+#define	TT(x)				(((x) >> 2) & 0x3)
+#define	TT_MSG(x)			tt_msgs[TT(x)]
+#define	II(x)				(((x) >> 2) & 0x3)
+#define	II_MSG(x)			ii_msgs[II(x)]
+#define	LL(x)				(((x) >> 0) & 0x3)
+#define	LL_MSG(x)			ll_msgs[LL(x)]
+#define	RRRR(x)				(((x) >> 4) & 0xf)
+#define	RRRR_MSG(x)			rrrr_msgs[RRRR(x)]
+#define	TO(x)				(((x) >> 8) & 0x1)
+#define	TO_MSG(x)			to_msgs[TO(x)]
+#define	PP(x)				(((x) >> 9) & 0x3)
+#define	PP_MSG(x)			pp_msgs[PP(x)]
+
+extern const char *tt_msgs[];
+extern const char *ll_msgs[];
+extern const char *rrrr_msgs[];
+extern const char *pp_msgs[];
+extern const char *to_msgs[];
+extern const char *ii_msgs[];
+extern const char *ext_msgs[];
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 07/20] EDAC: beef up ErrorCodeExt error signatures
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (5 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 06/20] EDAC: move MCE error descriptions to EDAC core Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 08/20] amd64_edac: cleanup amd64_process_error_info Borislav Petkov
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/edac_mce_amd.c |   71 ++++++++++++++++++++++--------------------
 1 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index cf84654..918567e 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -63,39 +63,42 @@ const char *ii_msgs[] = {	/* memory or i/o */
 };
 EXPORT_SYMBOL_GPL(ii_msgs);
 
-/* Map the 5 bits of Extended Error code to the string table. */
-const char *ext_msgs[] = {	/* extended error */
-	"K8 ECC error/F10 reserved",	/* 0_0000b */
-	"CRC error",			/* 0_0001b */
-	"sync error",			/* 0_0010b */
-	"mst abort",			/* 0_0011b */
-	"tgt abort",			/* 0_0100b */
-	"GART error",			/* 0_0101b */
-	"RMW error",			/* 0_0110b */
-	"Wdog timer error",		/* 0_0111b */
-	"F10-ECC/K8-Chipkill error",	/* 0_1000b */
-	"DEV Error",			/* 0_1001b */
-	"Link Data error",		/* 0_1010b */
-	"Link or L3 Protocol error",	/* 0_1011b */
-	"NB Array error",		/* 0_1100b */
-	"DRAM Parity error",		/* 0_1101b */
-	"Link Retry/GART Table Walk/DEV Table Walk error", /* 0_1110b */
-	"Res 0x0ff error",		/* 0_1111b */
-	"Res 0x100 error",		/* 1_0000b */
-	"Res 0x101 error",		/* 1_0001b */
-	"Res 0x102 error",		/* 1_0010b */
-	"Res 0x103 error",		/* 1_0011b */
-	"Res 0x104 error",		/* 1_0100b */
-	"Res 0x105 error",		/* 1_0101b */
-	"Res 0x106 error",		/* 1_0110b */
-	"Res 0x107 error",		/* 1_0111b */
-	"Res 0x108 error",		/* 1_1000b */
-	"Res 0x109 error",		/* 1_1001b */
-	"Res 0x10A error",		/* 1_1010b */
-	"Res 0x10B error",		/* 1_1011b */
-	"L3 Cache Data error",		/* 1_1100b */
-	"L3 CacheTag error",		/* 1_1101b */
-	"L3 Cache LRU error",		/* 1_1110b */
-	"Res 0x1FF error"		/* 1_1111b */
+/*
+ * Map the 4 or 5 (family-specific) bits of Extended Error code to the
+ * string table.
+ */
+const char *ext_msgs[] = {
+	"K8 ECC error",					/* 0_0000b */
+	"CRC error on link",				/* 0_0001b */
+	"Sync error packets on link",			/* 0_0010b */
+	"Master Abort during link operation",		/* 0_0011b */
+	"Target Abort during link operation",		/* 0_0100b */
+	"Invalid GART PTE entry during table walk",	/* 0_0101b */
+	"Unsupported atomic RMW command received",	/* 0_0110b */
+	"WDT error: NB transaction timeout",		/* 0_0111b */
+	"ECC/ChipKill ECC error",			/* 0_1000b */
+	"SVM DEV Error",				/* 0_1001b */
+	"Link Data error",				/* 0_1010b */
+	"Link/L3/Probe Filter Protocol error",		/* 0_1011b */
+	"NB Internal Arrays Parity error",		/* 0_1100b */
+	"DRAM Address/Control Parity error",		/* 0_1101b */
+	"Link Transmission error",			/* 0_1110b */
+	"GART/DEV Table Walk Data error"		/* 0_1111b */
+	"Res 0x100 error",				/* 1_0000b */
+	"Res 0x101 error",				/* 1_0001b */
+	"Res 0x102 error",				/* 1_0010b */
+	"Res 0x103 error",				/* 1_0011b */
+	"Res 0x104 error",				/* 1_0100b */
+	"Res 0x105 error",				/* 1_0101b */
+	"Res 0x106 error",				/* 1_0110b */
+	"Res 0x107 error",				/* 1_0111b */
+	"Res 0x108 error",				/* 1_1000b */
+	"Res 0x109 error",				/* 1_1001b */
+	"Res 0x10A error",				/* 1_1010b */
+	"Res 0x10B error",				/* 1_1011b */
+	"ECC error in L3 Cache Data",			/* 1_1100b */
+	"L3 Cache Tag error",				/* 1_1101b */
+	"L3 Cache LRU Parity error",			/* 1_1110b */
+	"Probe Filter error"				/* 1_1111b */
 };
 EXPORT_SYMBOL_GPL(ext_msgs);
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 08/20] amd64_edac: cleanup amd64_process_error_info
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (6 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 07/20] EDAC: beef up ErrorCodeExt error signatures Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 09/20] amd64_edac: cleanup/complete NB MCE decoding Borislav Petkov
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

* mv amd64_error_info_regs -> err_regs

* remove redundant info ptr

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c |   44 ++++++++++++++++++++------------------------
 drivers/edac/amd64_edac.h |   10 +++++-----
 2 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 7655ba1..a0afaa8 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -750,7 +750,7 @@ static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
  * specific.
  */
 static u64 extract_error_address(struct mem_ctl_info *mci,
-				 struct amd64_error_info_regs *info)
+				 struct err_regs *info)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 
@@ -1104,7 +1104,7 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
 
 /* extract the ERROR ADDRESS for the K8 CPUs */
 static u64 k8_get_error_address(struct mem_ctl_info *mci,
-				struct amd64_error_info_regs *info)
+				struct err_regs *info)
 {
 	return (((u64) (info->nbeah & 0xff)) << 32) +
 			(info->nbeal & ~0x03);
@@ -1147,7 +1147,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 }
 
 static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
-					struct amd64_error_info_regs *info,
+					struct err_regs *info,
 					u64 SystemAddress)
 {
 	struct mem_ctl_info *src_mci;
@@ -1366,7 +1366,7 @@ static void amd64_teardown(struct amd64_pvt *pvt)
 }
 
 static u64 f10_get_error_address(struct mem_ctl_info *mci,
-			struct amd64_error_info_regs *info)
+			struct err_regs *info)
 {
 	return (((u64) (info->nbeah & 0xffff)) << 32) +
 			(info->nbeal & ~0x01);
@@ -1743,7 +1743,7 @@ static int f10_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
  * The @sys_addr is usually an error address received from the hardware.
  */
 static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
-				     struct amd64_error_info_regs *info,
+				     struct err_regs *info,
 				     u64 sys_addr)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
@@ -2100,7 +2100,7 @@ static int get_channel_from_ecc_syndrome(unsigned short syndrome)
  *	- 0: if no valid error is indicated
  */
 static int amd64_get_error_info_regs(struct mem_ctl_info *mci,
-				     struct amd64_error_info_regs *regs)
+				     struct err_regs *regs)
 {
 	struct amd64_pvt *pvt;
 	struct pci_dev *misc_f3_ctl;
@@ -2149,10 +2149,10 @@ err_reg:
  *	- 0: if no error is found
  */
 static int amd64_get_error_info(struct mem_ctl_info *mci,
-				struct amd64_error_info_regs *info)
+				struct err_regs *info)
 {
 	struct amd64_pvt *pvt;
-	struct amd64_error_info_regs regs;
+	struct err_regs regs;
 
 	pvt = mci->pvt_info;
 
@@ -2208,7 +2208,7 @@ static int amd64_get_error_info(struct mem_ctl_info *mci,
 }
 
 static inline void amd64_decode_gart_tlb_error(struct mem_ctl_info *mci,
-					 struct amd64_error_info_regs *info)
+					 struct err_regs *info)
 {
 	u32 ec = ERROR_CODE(info->nbsl);
 
@@ -2218,7 +2218,7 @@ static inline void amd64_decode_gart_tlb_error(struct mem_ctl_info *mci,
 }
 
 static inline void amd64_decode_mem_cache_error(struct mem_ctl_info *mci,
-				      struct amd64_error_info_regs *info)
+				      struct err_regs *info)
 {
 	u32 ec = ERROR_CODE(info->nbsl);
 
@@ -2234,7 +2234,7 @@ static inline void amd64_decode_mem_cache_error(struct mem_ctl_info *mci,
  * ADDRESS and process.
  */
 static void amd64_handle_ce(struct mem_ctl_info *mci,
-			    struct amd64_error_info_regs *info)
+			    struct err_regs *info)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 	u64 SystemAddress;
@@ -2257,7 +2257,7 @@ static void amd64_handle_ce(struct mem_ctl_info *mci,
 
 /* Handle any Un-correctable Errors (UEs) */
 static void amd64_handle_ue(struct mem_ctl_info *mci,
-			    struct amd64_error_info_regs *info)
+			    struct err_regs *info)
 {
 	int csrow;
 	u64 SystemAddress;
@@ -2303,7 +2303,7 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
 }
 
 static void amd64_decode_bus_error(struct mem_ctl_info *mci,
-				   struct amd64_error_info_regs *info)
+				   struct err_regs *info)
 {
 	u32 ec  = ERROR_CODE(info->nbsl);
 	u32 xec = EXT_ERROR_CODE(info->nbsl);
@@ -2354,22 +2354,18 @@ static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 }
 
 int amd64_process_error_info(struct mem_ctl_info *mci,
-			     struct amd64_error_info_regs *info,
+			     struct err_regs *regs,
 			     int handle_errors)
 {
 	struct amd64_pvt *pvt;
-	struct amd64_error_info_regs *regs;
 	u32 err_code, ext_ec;
 	int gart_tlb_error = 0;
 
 	pvt = mci->pvt_info;
 
-	/* If caller doesn't want us to process the error, return */
 	if (!handle_errors)
 		return 1;
 
-	regs = info;
-
 	debugf1("NorthBridge ERROR: mci(0x%p)\n", mci);
 	debugf1("  MC node(%d) Error-Address(0x%.8x-%.8x)\n",
 		pvt->mc_node_id, regs->nbeah, regs->nbeal);
@@ -2435,13 +2431,13 @@ int amd64_process_error_info(struct mem_ctl_info *mci,
 		gart_tlb_error = 1;
 
 		debugf1("GART TLB error\n");
-		amd64_decode_gart_tlb_error(mci, info);
+		amd64_decode_gart_tlb_error(mci, regs);
 	} else if (MEM_ERROR(err_code)) {
 		debugf1("Memory/Cache error\n");
-		amd64_decode_mem_cache_error(mci, info);
+		amd64_decode_mem_cache_error(mci, regs);
 	} else if (BUS_ERROR(err_code)) {
 		debugf1("Bus (Link/DRAM) error\n");
-		amd64_decode_bus_error(mci, info);
+		amd64_decode_bus_error(mci, regs);
 	} else {
 		/* shouldn't reach here! */
 		amd64_mc_printk(mci, KERN_WARNING,
@@ -2478,10 +2474,10 @@ EXPORT_SYMBOL_GPL(amd64_process_error_info);
  */
 static void amd64_check(struct mem_ctl_info *mci)
 {
-	struct amd64_error_info_regs info;
+	struct err_regs regs;
 
-	if (amd64_get_error_info(mci, &info))
-		amd64_process_error_info(mci, &info, 1);
+	if (amd64_get_error_info(mci, &regs))
+		amd64_process_error_info(mci, &regs, 1);
 }
 
 /*
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 1ddef8d..bde8f78 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -449,7 +449,7 @@ enum amd64_chipset_families {
  *
  * Depends on entry into the modules
  */
-struct amd64_error_info_regs {
+struct err_regs {
 	u32 nbcfg;
 	u32 nbsh;
 	u32 nbsl;
@@ -527,7 +527,7 @@ struct amd64_pvt {
 	u32 online_spare;               /* On-Line spare Reg */
 
 	/* temp storage for when input is received from sysfs */
-	struct amd64_error_info_regs ctl_error_info;
+	struct err_regs ctl_error_info;
 
 	/* place to store error injection parameters prior to issue */
 	struct error_injection injection;
@@ -586,11 +586,11 @@ struct low_ops {
 	int (*early_channel_count)(struct amd64_pvt *pvt);
 
 	u64 (*get_error_address)(struct mem_ctl_info *mci,
-			struct amd64_error_info_regs *info);
+			struct err_regs *info);
 	void (*read_dram_base_limit)(struct amd64_pvt *pvt, int dram);
 	void (*read_dram_ctl_register)(struct amd64_pvt *pvt);
 	void (*map_sysaddr_to_csrow)(struct mem_ctl_info *mci,
-					struct amd64_error_info_regs *info,
+					struct err_regs *info,
 					u64 SystemAddr);
 	int (*dbam_map_to_pages)(struct amd64_pvt *pvt, int dram_map);
 };
@@ -623,7 +623,7 @@ static inline struct low_ops *family_ops(int index)
 #define F11_MIN_SCRUB_RATE_BITS	0x6
 
 int amd64_process_error_info(struct mem_ctl_info *mci,
-			     struct amd64_error_info_regs *info,
+			     struct err_regs *info,
 			     int handle_errors);
 int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
 			     u64 *hole_offset, u64 *hole_size);
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 09/20] amd64_edac: cleanup/complete NB MCE decoding
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (7 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 08/20] amd64_edac: cleanup amd64_process_error_info Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 10/20] amd64_edac: remove memory and GART TLB error decoders Borislav Petkov
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

* don't dump info which mcheck already does
* update to newest BKDG
* mv amd64_process_error_info -> amd64_decode_nb_mce
* shorten error struct names
* remove redundant info ptr in amd64_process_error_info
* remove unused ErrorCodeExt[19:16] (MCx_STATUS) defines

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c     |  125 +++++++++++++++--------------------------
 drivers/edac/amd64_edac.h     |   26 ++------
 drivers/edac/amd64_edac_dbg.c |    2 +-
 drivers/edac/edac_mce_amd.h   |    2 +
 4 files changed, 56 insertions(+), 99 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index a0afaa8..455d143 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2353,62 +2353,47 @@ static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 					  "Error Overflow set");
 }
 
-int amd64_process_error_info(struct mem_ctl_info *mci,
-			     struct err_regs *regs,
-			     int handle_errors)
+void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *regs,
+			 int handle_errors)
 {
-	struct amd64_pvt *pvt;
-	u32 err_code, ext_ec;
-	int gart_tlb_error = 0;
-
-	pvt = mci->pvt_info;
+	struct amd64_pvt *pvt = mci->pvt_info;
+	int ecc;
+	u32 ec  = ERROR_CODE(regs->nbsl);
+	u32 xec = EXT_ERROR_CODE(regs->nbsl);
 
 	if (!handle_errors)
-		return 1;
+		return;
 
-	debugf1("NorthBridge ERROR: mci(0x%p)\n", mci);
-	debugf1("  MC node(%d) Error-Address(0x%.8x-%.8x)\n",
-		pvt->mc_node_id, regs->nbeah, regs->nbeal);
-	debugf1("  nbsh(0x%.8x) nbsl(0x%.8x)\n",
-		regs->nbsh, regs->nbsl);
-	debugf1("  Valid Error=%s Overflow=%s\n",
-		(regs->nbsh & K8_NBSH_VALID_BIT) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_OVERFLOW) ? "True" : "False");
-	debugf1("  Err Uncorrected=%s MCA Error Reporting=%s\n",
-		(regs->nbsh & K8_NBSH_UNCORRECTED_ERR) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_ERR_ENABLE) ?
-			"True" : "False");
-	debugf1("  MiscErr Valid=%s ErrAddr Valid=%s PCC=%s\n",
-		(regs->nbsh & K8_NBSH_MISC_ERR_VALID) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_VALID_ERROR_ADDR) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_PCC) ?
-			"True" : "False");
-	debugf1("  CECC=%s UECC=%s Found by Scruber=%s\n",
-		(regs->nbsh & K8_NBSH_CECC) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_UECC) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_ERR_SCRUBER) ?
-			"True" : "False");
-	debugf1("  CORE0=%s CORE1=%s CORE2=%s CORE3=%s\n",
-		(regs->nbsh & K8_NBSH_CORE0) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_CORE1) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_CORE2) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_CORE3) ? "True" : "False");
+	pr_emerg(" Northbridge ERROR, mc node %d", pvt->mc_node_id);
 
+	/*
+	 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
+	 * value encoding has changed so interpret those differently
+	 */
+	if ((boot_cpu_data.x86 == 0x10) &&
+	    (boot_cpu_data.x86_model > 8)) {
+		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
+			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
+	} else {
+		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
+	}
 
-	err_code = ERROR_CODE(regs->nbsl);
+	pr_emerg(" Error: %sorrected",
+		 ((regs->nbsh & K8_NBSH_UC_ERR) ? "Unc" : "C"));
+	pr_cont(", Report Error: %s",
+		 ((regs->nbsh & K8_NBSH_ERR_EN) ? "yes" : "no"));
+	pr_cont(", MiscV: %svalid, CPU context corrupt: %s",
+		((regs->nbsh & K8_NBSH_MISCV) ? "" : "In"),
+		((regs->nbsh & K8_NBSH_PCC)   ? "yes" : "no"));
 
-	/* Determine which error type:
-	 *	1) GART errors - non-fatal, developmental events
-	 *	2) MEMORY errors
-	 *	3) BUS errors
-	 *	4) Unknown error
-	 */
-	if (TLB_ERROR(err_code)) {
+	/* do the two bits[14:13] together */
+	ecc = regs->nbsh & (0x3 << 13);
+	if (ecc)
+		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
+
+	pr_cont("\n");
+
+	if (TLB_ERROR(ec)) {
 		/*
 		 * GART errors are intended to help graphics driver developers
 		 * to detect bad GART PTEs. It is recommended by AMD to disable
@@ -2421,52 +2406,34 @@ int amd64_process_error_info(struct mem_ctl_info *mci,
 		 * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
 		 *     AMD NPT family 0Fh processors
 		 */
-		if (report_gart_errors == 0)
-			return 1;
-
-		/*
-		 * Only if GART error reporting is requested should we generate
-		 * any logs.
-		 */
-		gart_tlb_error = 1;
+		if (!report_gart_errors)
+			return;
 
-		debugf1("GART TLB error\n");
+		pr_emerg("GART TLB error\n");
 		amd64_decode_gart_tlb_error(mci, regs);
-	} else if (MEM_ERROR(err_code)) {
-		debugf1("Memory/Cache error\n");
+	} else if (MEM_ERROR(ec)) {
+		pr_emerg("Memory/Cache error\n");
 		amd64_decode_mem_cache_error(mci, regs);
-	} else if (BUS_ERROR(err_code)) {
-		debugf1("Bus (Link/DRAM) error\n");
+	} else if (BUS_ERROR(ec)) {
+		pr_emerg("Bus (Link/DRAM) error\n");
 		amd64_decode_bus_error(mci, regs);
 	} else {
 		/* shouldn't reach here! */
 		amd64_mc_printk(mci, KERN_WARNING,
 			     "%s(): unknown MCE error 0x%x\n", __func__,
-			     err_code);
+			     ec);
 	}
 
-	ext_ec = EXT_ERROR_CODE(regs->nbsl);
-	amd64_mc_printk(mci, KERN_ERR,
-		"ExtErr=(0x%x) %s\n", ext_ec, ext_msgs[ext_ec]);
+	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
 
 	/*
 	 * Check the UE bit of the NB status high register, if set generate some
 	 * logs. If NOT a GART error, then process the event as a NO-INFO event.
 	 * If it was a GART error, skip that process.
 	 */
-	if (regs->nbsh & K8_NBSH_UNCORRECTED_ERR) {
-		amd64_mc_printk(mci, KERN_CRIT, "uncorrected error\n");
-		if (!gart_tlb_error)
-			edac_mc_handle_ue_no_info(mci, "UE bit is set\n");
-	}
-
-	if (regs->nbsh & K8_NBSH_PCC)
-		amd64_mc_printk(mci, KERN_CRIT,
-			"PCC (processor context corrupt) set\n");
-
-	return 1;
+	if (regs->nbsh & K8_NBSH_UC_ERR && !report_gart_errors)
+		edac_mc_handle_ue_no_info(mci, "UE bit is set");
 }
-EXPORT_SYMBOL_GPL(amd64_process_error_info);
 
 /*
  * The main polling 'check' function, called FROM the edac core to perform the
@@ -2477,7 +2444,7 @@ static void amd64_check(struct mem_ctl_info *mci)
 	struct err_regs regs;
 
 	if (amd64_get_error_info(mci, &regs))
-		amd64_process_error_info(mci, &regs, 1);
+		amd64_decode_nb_mce(mci, &regs, 1);
 }
 
 /*
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index bde8f78..ecab0c9 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -306,16 +306,7 @@ enum {
 
 /* Family F10h: Normalized Extended Error Codes */
 #define F10_NBSL_EXT_ERR_RES		0x0
-#define F10_NBSL_EXT_ERR_CRC		0x1
-#define F10_NBSL_EXT_ERR_SYNC		0x2
-#define F10_NBSL_EXT_ERR_MST		0x3
-#define F10_NBSL_EXT_ERR_TGT		0x4
-#define F10_NBSL_EXT_ERR_GART		0x5
-#define F10_NBSL_EXT_ERR_RMW		0x6
-#define F10_NBSL_EXT_ERR_WDT		0x7
 #define F10_NBSL_EXT_ERR_ECC		0x8
-#define F10_NBSL_EXT_ERR_DEV		0x9
-#define F10_NBSL_EXT_ERR_LINK_DATA	0xA
 
 /* Next two are overloaded values */
 #define F10_NBSL_EXT_ERR_LINK_PROTO	0xB
@@ -360,18 +351,15 @@ enum {
 
 #define K8_NBSH_VALID_BIT		BIT(31)
 #define K8_NBSH_OVERFLOW		BIT(30)
-#define K8_NBSH_UNCORRECTED_ERR		BIT(29)
-#define K8_NBSH_ERR_ENABLE		BIT(28)
-#define K8_NBSH_MISC_ERR_VALID		BIT(27)
+#define K8_NBSH_UC_ERR			BIT(29)
+#define K8_NBSH_ERR_EN			BIT(28)
+#define K8_NBSH_MISCV			BIT(27)
 #define K8_NBSH_VALID_ERROR_ADDR	BIT(26)
 #define K8_NBSH_PCC			BIT(25)
+#define K8_NBSH_ERR_CPU_VAL		BIT(24)
 #define K8_NBSH_CECC			BIT(14)
 #define K8_NBSH_UECC			BIT(13)
 #define K8_NBSH_ERR_SCRUBER		BIT(8)
-#define K8_NBSH_CORE3			BIT(3)
-#define K8_NBSH_CORE2			BIT(2)
-#define K8_NBSH_CORE1			BIT(1)
-#define K8_NBSH_CORE0			BIT(0)
 
 #define EXTRACT_ERR_CPU_MAP(x)		((x) & 0xF)
 
@@ -622,8 +610,8 @@ static inline struct low_ops *family_ops(int index)
 #define F10_MIN_SCRUB_RATE_BITS	0x5
 #define F11_MIN_SCRUB_RATE_BITS	0x6
 
-int amd64_process_error_info(struct mem_ctl_info *mci,
-			     struct err_regs *info,
-			     int handle_errors);
+void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *info,
+			int handle_errors);
+
 int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
 			     u64 *hole_offset, u64 *hole_size);
diff --git a/drivers/edac/amd64_edac_dbg.c b/drivers/edac/amd64_edac_dbg.c
index 0a41b24..bcb4e2e 100644
--- a/drivers/edac/amd64_edac_dbg.c
+++ b/drivers/edac/amd64_edac_dbg.c
@@ -24,7 +24,7 @@ static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data,
 
 		/* Process the Mapping request */
 		/* TODO: Add race prevention */
-		amd64_process_error_info(mci, &pvt->ctl_error_info, 1);
+		amd64_decode_nb_mce(mci, &pvt->ctl_error_info, 1);
 
 		return count;
 	}
diff --git a/drivers/edac/edac_mce_amd.h b/drivers/edac/edac_mce_amd.h
index aea3863..38c2bc4 100644
--- a/drivers/edac/edac_mce_amd.h
+++ b/drivers/edac/edac_mce_amd.h
@@ -1,5 +1,7 @@
 #define ERROR_CODE(x)			((x) & 0xffff)
 #define EXT_ERROR_CODE(x)		(((x) >> 16) & 0x1f)
+#define EXT_ERR_MSG(x)			ext_msgs[EXT_ERROR_CODE(x)]
+
 #define LOW_SYNDROME(x)			(((x) >> 15) & 0xff)
 #define HIGH_SYNDROME(x)		(((x) >> 24) & 0xff)
 
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 10/20] amd64_edac: remove memory and GART TLB error decoders
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (8 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 09/20] amd64_edac: cleanup/complete NB MCE decoding Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 11/20] amd64_edac: cleanup amd64_decode_bus_error Borislav Petkov
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c |   36 +++++++-----------------------------
 1 files changed, 7 insertions(+), 29 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 455d143..298020e 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2207,28 +2207,6 @@ static int amd64_get_error_info(struct mem_ctl_info *mci,
 	return 1;
 }
 
-static inline void amd64_decode_gart_tlb_error(struct mem_ctl_info *mci,
-					 struct err_regs *info)
-{
-	u32 ec = ERROR_CODE(info->nbsl);
-
-	amd64_mc_printk(mci, KERN_ERR,
-		     "GART TLB event: transaction type(%s), "
-		     "cache level(%s)\n", TT_MSG(ec), LL_MSG(ec));
-}
-
-static inline void amd64_decode_mem_cache_error(struct mem_ctl_info *mci,
-				      struct err_regs *info)
-{
-	u32 ec = ERROR_CODE(info->nbsl);
-
-	amd64_mc_printk(mci, KERN_ERR,
-		     "cache hierarchy error: memory transaction type(%s), "
-		     "transaction type(%s), cache level(%s)\n",
-		     RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
-}
-
-
 /*
  * Handle any Correctable Errors (CEs) that have occurred. Check for valid ERROR
  * ADDRESS and process.
@@ -2409,19 +2387,19 @@ void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *regs,
 		if (!report_gart_errors)
 			return;
 
-		pr_emerg("GART TLB error\n");
-		amd64_decode_gart_tlb_error(mci, regs);
+		pr_emerg(" GART TLB error, Transaction: %s, Cache Level %s\n",
+			 TT_MSG(ec), LL_MSG(ec));
 	} else if (MEM_ERROR(ec)) {
-		pr_emerg("Memory/Cache error\n");
-		amd64_decode_mem_cache_error(mci, regs);
+		pr_emerg(" Memory/Cache error, Transaction: %s, Type: %s,"
+			 " Cache Level: %s",
+			 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
 	} else if (BUS_ERROR(ec)) {
-		pr_emerg("Bus (Link/DRAM) error\n");
+		pr_emerg(" Bus (Link/DRAM) error\n");
 		amd64_decode_bus_error(mci, regs);
 	} else {
 		/* shouldn't reach here! */
 		amd64_mc_printk(mci, KERN_WARNING,
-			     "%s(): unknown MCE error 0x%x\n", __func__,
-			     ec);
+				"%s(): unknown MCE error 0x%x\n", __func__, ec);
 	}
 
 	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 11/20] amd64_edac: cleanup amd64_decode_bus_error
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (9 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 10/20] amd64_edac: remove memory and GART TLB error decoders Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 12/20] x86, mce: pass mce info to EDAC for decoding Borislav Petkov
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c |   35 +++++++++--------------------------
 1 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 298020e..dcc318e 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2281,42 +2281,26 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
 }
 
 static void amd64_decode_bus_error(struct mem_ctl_info *mci,
-				   struct err_regs *info)
+				   struct err_regs *info, int ecc_type)
 {
 	u32 ec  = ERROR_CODE(info->nbsl);
 	u32 xec = EXT_ERROR_CODE(info->nbsl);
 
-	amd64_mc_printk(mci, KERN_ERR,
-		"BUS ERROR:\n"
-		"  time-out(%s) mem or i/o(%s)\n"
-		"  participating processor(%s)\n"
-		"  memory transaction type(%s)\n"
-		"  cache level(%s) Error Found by: %s\n",
-		TO_MSG(ec), II_MSG(ec), PP_MSG(ec), RRRR_MSG(ec), LL_MSG(ec),
-		(info->nbsh & K8_NBSH_ERR_SCRUBER) ?
-			"Scrubber" : "Normal Operation");
+	pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, %s\n",
+		 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec), PP_MSG(ec));
 
 
 	/* Bail early out if this was an 'observed' error */
 	if (PP(ec) == K8_NBSL_PP_OBS)
 		return;
 
-	/* Parse out the extended error code for ECC events */
-	switch (xec) {
-	/* F10 changed to one Extended ECC error code */
-	case F10_NBSL_EXT_ERR_RES:		/* Reserved field */
-	case F10_NBSL_EXT_ERR_ECC:		/* F10 ECC ext err code */
-		break;
-
-	default:
-		amd64_mc_printk(mci, KERN_ERR, "NOT ECC: no special error "
-					       "handling for this error\n");
+	/* Do only ECC errors */
+	if (xec && xec != F10_NBSL_EXT_ERR_ECC)
 		return;
-	}
 
-	if (info->nbsh & K8_NBSH_CECC)
+	if (ecc_type == 2)
 		amd64_handle_ce(mci, info);
-	else if (info->nbsh & K8_NBSH_UECC)
+	else if (ecc_type == 1)
 		amd64_handle_ue(mci, info);
 
 	/*
@@ -2327,8 +2311,7 @@ static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 	 * catastrophic.
 	 */
 	if (info->nbsh & K8_NBSH_OVERFLOW)
-		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR
-					  "Error Overflow set");
+		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR "Error Overflow");
 }
 
 void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *regs,
@@ -2395,7 +2378,7 @@ void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *regs,
 			 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
 	} else if (BUS_ERROR(ec)) {
 		pr_emerg(" Bus (Link/DRAM) error\n");
-		amd64_decode_bus_error(mci, regs);
+		amd64_decode_bus_error(mci, regs, ecc);
 	} else {
 		/* shouldn't reach here! */
 		amd64_mc_printk(mci, KERN_WARNING,
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 12/20] x86, mce: pass mce info to EDAC for decoding
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (10 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 11/20] amd64_edac: cleanup amd64_decode_bus_error Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 13/20] EDAC, AMD: carve out MCi_STATUS decoding Borislav Petkov
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andi Kleen

Move NB decoder along with required defines to EDAC MCE core. Add
registration routines for further decoding of the MCE info in the AMD64
EDAC module.

CC: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/mcheck/mce.c |    7 +++
 drivers/edac/amd64_edac.c        |   94 +++++++--------------------------
 drivers/edac/amd64_edac.h        |   36 -------------
 drivers/edac/amd64_edac_dbg.c    |    2 +-
 drivers/edac/edac_mce_amd.c      |  105 ++++++++++++++++++++++++++++++++++++++
 drivers/edac/edac_mce_amd.h      |   37 +++++++++++++
 6 files changed, 170 insertions(+), 111 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 1cfb623..69e7d8e 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -183,6 +183,11 @@ void mce_log(struct mce *mce)
 	set_bit(0, &mce_need_notify);
 }
 
+void __attribute__((weak)) decode_mce(struct mce *m)
+{
+	return;
+}
+
 static void print_mce(struct mce *m)
 {
 	printk(KERN_EMERG
@@ -205,6 +210,8 @@ static void print_mce(struct mce *m)
 	printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
 			m->cpuvendor, m->cpuid, m->time, m->socketid,
 			m->apicid);
+
+	decode_mce(m);
 }
 
 static void print_mce_head(void)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index dcc318e..776d761 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2280,8 +2280,8 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
 	}
 }
 
-static void amd64_decode_bus_error(struct mem_ctl_info *mci,
-				   struct err_regs *info, int ecc_type)
+static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
+					    struct err_regs *info, int ecc_type)
 {
 	u32 ec  = ERROR_CODE(info->nbsl);
 	u32 xec = EXT_ERROR_CODE(info->nbsl);
@@ -2314,86 +2314,23 @@ static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR "Error Overflow");
 }
 
-void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *regs,
-			 int handle_errors)
+void amd64_decode_bus_error(int node_id, struct err_regs *regs,
+				   int ecc_type)
 {
-	struct amd64_pvt *pvt = mci->pvt_info;
-	int ecc;
-	u32 ec  = ERROR_CODE(regs->nbsl);
-	u32 xec = EXT_ERROR_CODE(regs->nbsl);
-
-	if (!handle_errors)
-		return;
+	struct mem_ctl_info *mci = mci_lookup[node_id];
 
-	pr_emerg(" Northbridge ERROR, mc node %d", pvt->mc_node_id);
-
-	/*
-	 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
-	 * value encoding has changed so interpret those differently
-	 */
-	if ((boot_cpu_data.x86 == 0x10) &&
-	    (boot_cpu_data.x86_model > 8)) {
-		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
-			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
-	} else {
-		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
-	}
-
-	pr_emerg(" Error: %sorrected",
-		 ((regs->nbsh & K8_NBSH_UC_ERR) ? "Unc" : "C"));
-	pr_cont(", Report Error: %s",
-		 ((regs->nbsh & K8_NBSH_ERR_EN) ? "yes" : "no"));
-	pr_cont(", MiscV: %svalid, CPU context corrupt: %s",
-		((regs->nbsh & K8_NBSH_MISCV) ? "" : "In"),
-		((regs->nbsh & K8_NBSH_PCC)   ? "yes" : "no"));
-
-	/* do the two bits[14:13] together */
-	ecc = regs->nbsh & (0x3 << 13);
-	if (ecc)
-		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
-
-	pr_cont("\n");
-
-	if (TLB_ERROR(ec)) {
-		/*
-		 * GART errors are intended to help graphics driver developers
-		 * to detect bad GART PTEs. It is recommended by AMD to disable
-		 * GART table walk error reporting by default[1] (currently
-		 * being disabled in mce_cpu_quirks()) and according to the
-		 * comment in mce_cpu_quirks(), such GART errors can be
-		 * incorrectly triggered. We may see these errors anyway and
-		 * unless requested by the user, they won't be reported.
-		 *
-		 * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
-		 *     AMD NPT family 0Fh processors
-		 */
-		if (!report_gart_errors)
-			return;
-
-		pr_emerg(" GART TLB error, Transaction: %s, Cache Level %s\n",
-			 TT_MSG(ec), LL_MSG(ec));
-	} else if (MEM_ERROR(ec)) {
-		pr_emerg(" Memory/Cache error, Transaction: %s, Type: %s,"
-			 " Cache Level: %s",
-			 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
-	} else if (BUS_ERROR(ec)) {
-		pr_emerg(" Bus (Link/DRAM) error\n");
-		amd64_decode_bus_error(mci, regs, ecc);
-	} else {
-		/* shouldn't reach here! */
-		amd64_mc_printk(mci, KERN_WARNING,
-				"%s(): unknown MCE error 0x%x\n", __func__, ec);
-	}
-
-	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+	__amd64_decode_bus_error(mci, regs, ecc_type);
 
 	/*
 	 * Check the UE bit of the NB status high register, if set generate some
 	 * logs. If NOT a GART error, then process the event as a NO-INFO event.
 	 * If it was a GART error, skip that process.
+	 *
+	 * FIXME: this should go somewhere else, if at all.
 	 */
 	if (regs->nbsh & K8_NBSH_UC_ERR && !report_gart_errors)
 		edac_mc_handle_ue_no_info(mci, "UE bit is set");
+
 }
 
 /*
@@ -2404,8 +2341,10 @@ static void amd64_check(struct mem_ctl_info *mci)
 {
 	struct err_regs regs;
 
-	if (amd64_get_error_info(mci, &regs))
-		amd64_decode_nb_mce(mci, &regs, 1);
+	if (amd64_get_error_info(mci, &regs)) {
+		struct amd64_pvt *pvt = mci->pvt_info;
+		amd_decode_nb_mce(pvt->mc_node_id, &regs, 1);
+	}
 }
 
 /*
@@ -3096,6 +3035,13 @@ static int amd64_init_2nd_stage(struct amd64_pvt *pvt)
 
 	mci_lookup[node_id] = mci;
 	pvt_lookup[node_id] = NULL;
+
+	/* register stuff with EDAC MCE */
+	if (report_gart_errors)
+		amd_report_gart_errors(true);
+
+	amd_set_nb_bus_decoder(amd64_decode_bus_error);
+
 	return 0;
 
 err_add_mc:
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index ecab0c9..8ea07e2 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -346,24 +346,8 @@ enum {
 #define K8_NBSL_PP_OBS			0x2
 #define K8_NBSL_PP_GENERIC		0x3
 
-
-#define K8_NBSH				0x4C
-
-#define K8_NBSH_VALID_BIT		BIT(31)
-#define K8_NBSH_OVERFLOW		BIT(30)
-#define K8_NBSH_UC_ERR			BIT(29)
-#define K8_NBSH_ERR_EN			BIT(28)
-#define K8_NBSH_MISCV			BIT(27)
-#define K8_NBSH_VALID_ERROR_ADDR	BIT(26)
-#define K8_NBSH_PCC			BIT(25)
-#define K8_NBSH_ERR_CPU_VAL		BIT(24)
-#define K8_NBSH_CECC			BIT(14)
-#define K8_NBSH_UECC			BIT(13)
-#define K8_NBSH_ERR_SCRUBER		BIT(8)
-
 #define EXTRACT_ERR_CPU_MAP(x)		((x) & 0xF)
 
-
 #define K8_NBEAL			0x50
 #define K8_NBEAH			0x54
 #define K8_SCRCTRL			0x58
@@ -428,23 +412,6 @@ enum amd64_chipset_families {
 	F11_CPUS,
 };
 
-/*
- * Structure to hold:
- *
- * 1) dynamically read status and error address HW registers
- * 2) sysfs entered values
- * 3) MCE values
- *
- * Depends on entry into the modules
- */
-struct err_regs {
-	u32 nbcfg;
-	u32 nbsh;
-	u32 nbsl;
-	u32 nbeah;
-	u32 nbeal;
-};
-
 /* Error injection control structure */
 struct error_injection {
 	u32	section;
@@ -610,8 +577,5 @@ static inline struct low_ops *family_ops(int index)
 #define F10_MIN_SCRUB_RATE_BITS	0x5
 #define F11_MIN_SCRUB_RATE_BITS	0x6
 
-void amd64_decode_nb_mce(struct mem_ctl_info *mci, struct err_regs *info,
-			int handle_errors);
-
 int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
 			     u64 *hole_offset, u64 *hole_size);
diff --git a/drivers/edac/amd64_edac_dbg.c b/drivers/edac/amd64_edac_dbg.c
index bcb4e2e..59cf2cf 100644
--- a/drivers/edac/amd64_edac_dbg.c
+++ b/drivers/edac/amd64_edac_dbg.c
@@ -24,7 +24,7 @@ static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data,
 
 		/* Process the Mapping request */
 		/* TODO: Add race prevention */
-		amd64_decode_nb_mce(mci, &pvt->ctl_error_info, 1);
+		amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1);
 
 		return count;
 	}
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 918567e..ef18880 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -1,6 +1,21 @@
 #include <linux/module.h>
 #include "edac_mce_amd.h"
 
+static bool report_gart_errors;
+static void (*nb_bus_decoder)(int node_id, struct err_regs *regs, int ecc_type);
+
+void amd_report_gart_errors(bool v)
+{
+	report_gart_errors = v;
+}
+EXPORT_SYMBOL_GPL(amd_report_gart_errors);
+
+void amd_set_nb_bus_decoder(void (*f)(int, struct err_regs *, int))
+{
+	nb_bus_decoder = f;
+}
+EXPORT_SYMBOL_GPL(amd_set_nb_bus_decoder);
+
 /*
  * string representation for the different MCA reported error types, see F3x48
  * or MSR0000_0411.
@@ -102,3 +117,93 @@ const char *ext_msgs[] = {
 	"Probe Filter error"				/* 1_1111b */
 };
 EXPORT_SYMBOL_GPL(ext_msgs);
+
+void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
+{
+	int ecc;
+	u32 ec  = ERROR_CODE(regs->nbsl);
+	u32 xec = EXT_ERROR_CODE(regs->nbsl);
+
+	if (!handle_errors)
+		return;
+
+	pr_emerg(" Northbridge Error, node %d", node_id);
+
+	/*
+	 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
+	 * value encoding has changed so interpret those differently
+	 */
+	if ((boot_cpu_data.x86 == 0x10) &&
+	    (boot_cpu_data.x86_model > 8)) {
+		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
+			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
+	} else {
+		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
+	}
+
+	pr_emerg(" Error: %sorrected",
+		 ((regs->nbsh & K8_NBSH_UC_ERR) ? "Unc" : "C"));
+	pr_cont(", Report Error: %s",
+		 ((regs->nbsh & K8_NBSH_ERR_EN) ? "yes" : "no"));
+	pr_cont(", MiscV: %svalid, CPU context corrupt: %s",
+		((regs->nbsh & K8_NBSH_MISCV) ? "" : "In"),
+		((regs->nbsh & K8_NBSH_PCC)   ? "yes" : "no"));
+
+	/* do the two bits[14:13] together */
+	ecc = regs->nbsh & (0x3 << 13);
+	if (ecc)
+		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
+
+	pr_cont("\n");
+
+	if (TLB_ERROR(ec)) {
+		/*
+		 * GART errors are intended to help graphics driver developers
+		 * to detect bad GART PTEs. It is recommended by AMD to disable
+		 * GART table walk error reporting by default[1] (currently
+		 * being disabled in mce_cpu_quirks()) and according to the
+		 * comment in mce_cpu_quirks(), such GART errors can be
+		 * incorrectly triggered. We may see these errors anyway and
+		 * unless requested by the user, they won't be reported.
+		 *
+		 * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
+		 *     AMD NPT family 0Fh processors
+		 */
+		if (!report_gart_errors)
+			return;
+
+		pr_emerg(" GART TLB error, Transaction: %s, Cache Level %s\n",
+			 TT_MSG(ec), LL_MSG(ec));
+	} else if (MEM_ERROR(ec)) {
+		pr_emerg(" Memory/Cache error, Transaction: %s, Type: %s,"
+			 " Cache Level: %s",
+			 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
+	} else if (BUS_ERROR(ec)) {
+		pr_emerg(" Bus (Link/DRAM) error\n");
+		if (nb_bus_decoder)
+			nb_bus_decoder(node_id, regs, ecc);
+	} else {
+		/* shouldn't reach here! */
+		pr_warning("%s: unknown MCE error 0x%x\n", __func__, ec);
+	}
+
+	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+}
+EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
+
+void decode_mce(struct mce *m)
+{
+	struct err_regs regs;
+	int node;
+
+	if (m->bank != 4)
+		return;
+
+	regs.nbsl  = (u32) m->status;
+	regs.nbsh  = (u32)(m->status >> 32);
+	regs.nbeal = (u32) m->addr;
+	regs.nbeah = (u32)(m->addr >> 32);
+	node       = cpu_data(m->extcpu).cpu_node_id;
+
+	amd_decode_nb_mce(node, &regs, 1);
+}
diff --git a/drivers/edac/edac_mce_amd.h b/drivers/edac/edac_mce_amd.h
index 38c2bc4..3825697 100644
--- a/drivers/edac/edac_mce_amd.h
+++ b/drivers/edac/edac_mce_amd.h
@@ -1,3 +1,8 @@
+#ifndef _EDAC_MCE_AMD_H
+#define _EDAC_MCE_AMD_H
+
+#include <asm/mce.h>
+
 #define ERROR_CODE(x)			((x) & 0xffff)
 #define EXT_ERROR_CODE(x)		(((x) >> 16) & 0x1f)
 #define EXT_ERR_MSG(x)			ext_msgs[EXT_ERROR_CODE(x)]
@@ -22,6 +27,20 @@
 #define	PP(x)				(((x) >> 9) & 0x3)
 #define	PP_MSG(x)			pp_msgs[PP(x)]
 
+#define K8_NBSH				0x4C
+
+#define K8_NBSH_VALID_BIT		BIT(31)
+#define K8_NBSH_OVERFLOW		BIT(30)
+#define K8_NBSH_UC_ERR			BIT(29)
+#define K8_NBSH_ERR_EN			BIT(28)
+#define K8_NBSH_MISCV			BIT(27)
+#define K8_NBSH_VALID_ERROR_ADDR	BIT(26)
+#define K8_NBSH_PCC			BIT(25)
+#define K8_NBSH_ERR_CPU_VAL		BIT(24)
+#define K8_NBSH_CECC			BIT(14)
+#define K8_NBSH_UECC			BIT(13)
+#define K8_NBSH_ERR_SCRUBER		BIT(8)
+
 extern const char *tt_msgs[];
 extern const char *ll_msgs[];
 extern const char *rrrr_msgs[];
@@ -29,3 +48,21 @@ extern const char *pp_msgs[];
 extern const char *to_msgs[];
 extern const char *ii_msgs[];
 extern const char *ext_msgs[];
+
+/*
+ * relevant NB regs
+ */
+struct err_regs {
+	u32 nbcfg;
+	u32 nbsh;
+	u32 nbsl;
+	u32 nbeah;
+	u32 nbeal;
+};
+
+
+void amd_report_gart_errors(bool);
+void amd_set_nb_bus_decoder(void (*f)(int, struct err_regs *, int));
+void amd_decode_nb_mce(int, struct err_regs *, int);
+
+#endif /* _EDAC_MCE_AMD_H */
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 13/20] EDAC, AMD: carve out MCi_STATUS decoding
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (11 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 12/20] x86, mce: pass mce info to EDAC for decoding Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 14/20] EDAC, AMD: carve out decoding of MCi_STATUS ErrorCode Borislav Petkov
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

The MCi_STATUS registers have most field definitions in common so decode
them in the general path. Do not pass ecc_type along and compute it in
__amd64_decode_bus_error instead.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c   |    8 +++---
 drivers/edac/edac_mce_amd.c |   55 +++++++++++++++++++++----------------------
 drivers/edac/edac_mce_amd.h |    2 +-
 3 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 776d761..2684392 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2281,10 +2281,11 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
 }
 
 static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
-					    struct err_regs *info, int ecc_type)
+					    struct err_regs *info)
 {
 	u32 ec  = ERROR_CODE(info->nbsl);
 	u32 xec = EXT_ERROR_CODE(info->nbsl);
+	int ecc_type = info->nbsh & (0x3 << 13);
 
 	pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, %s\n",
 		 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec), PP_MSG(ec));
@@ -2314,12 +2315,11 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
 		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR "Error Overflow");
 }
 
-void amd64_decode_bus_error(int node_id, struct err_regs *regs,
-				   int ecc_type)
+void amd64_decode_bus_error(int node_id, struct err_regs *regs)
 {
 	struct mem_ctl_info *mci = mci_lookup[node_id];
 
-	__amd64_decode_bus_error(mci, regs, ecc_type);
+	__amd64_decode_bus_error(mci, regs);
 
 	/*
 	 * Check the UE bit of the NB status high register, if set generate some
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index ef18880..499af60 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -2,7 +2,7 @@
 #include "edac_mce_amd.h"
 
 static bool report_gart_errors;
-static void (*nb_bus_decoder)(int node_id, struct err_regs *regs, int ecc_type);
+static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
 
 void amd_report_gart_errors(bool v)
 {
@@ -10,7 +10,7 @@ void amd_report_gart_errors(bool v)
 }
 EXPORT_SYMBOL_GPL(amd_report_gart_errors);
 
-void amd_set_nb_bus_decoder(void (*f)(int, struct err_regs *, int))
+void amd_set_nb_bus_decoder(void (*f)(int, struct err_regs *))
 {
 	nb_bus_decoder = f;
 }
@@ -120,7 +120,6 @@ EXPORT_SYMBOL_GPL(ext_msgs);
 
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
-	int ecc;
 	u32 ec  = ERROR_CODE(regs->nbsl);
 	u32 xec = EXT_ERROR_CODE(regs->nbsl);
 
@@ -141,21 +140,6 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
 	}
 
-	pr_emerg(" Error: %sorrected",
-		 ((regs->nbsh & K8_NBSH_UC_ERR) ? "Unc" : "C"));
-	pr_cont(", Report Error: %s",
-		 ((regs->nbsh & K8_NBSH_ERR_EN) ? "yes" : "no"));
-	pr_cont(", MiscV: %svalid, CPU context corrupt: %s",
-		((regs->nbsh & K8_NBSH_MISCV) ? "" : "In"),
-		((regs->nbsh & K8_NBSH_PCC)   ? "yes" : "no"));
-
-	/* do the two bits[14:13] together */
-	ecc = regs->nbsh & (0x3 << 13);
-	if (ecc)
-		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
-
-	pr_cont("\n");
-
 	if (TLB_ERROR(ec)) {
 		/*
 		 * GART errors are intended to help graphics driver developers
@@ -181,7 +165,7 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 	} else if (BUS_ERROR(ec)) {
 		pr_emerg(" Bus (Link/DRAM) error\n");
 		if (nb_bus_decoder)
-			nb_bus_decoder(node_id, regs, ecc);
+			nb_bus_decoder(node_id, regs);
 	} else {
 		/* shouldn't reach here! */
 		pr_warning("%s: unknown MCE error 0x%x\n", __func__, ec);
@@ -194,16 +178,31 @@ EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
 void decode_mce(struct mce *m)
 {
 	struct err_regs regs;
-	int node;
+	int node, ecc;
 
-	if (m->bank != 4)
-		return;
+	pr_emerg("MC%d_STATUS:\n", m->bank);
 
-	regs.nbsl  = (u32) m->status;
-	regs.nbsh  = (u32)(m->status >> 32);
-	regs.nbeal = (u32) m->addr;
-	regs.nbeah = (u32)(m->addr >> 32);
-	node       = cpu_data(m->extcpu).cpu_node_id;
+	pr_emerg(" Error: %sorrected, Report: %s, MiscV: %svalid, "
+		 "CPU context corrupt: %s",
+		 ((m->status & MCI_STATUS_UC) ? "Unc"  : "C"),
+		 ((m->status & MCI_STATUS_EN) ? "yes"  : "no"),
+		 ((m->status & MCI_STATUS_MISCV) ? ""  : "in"),
+		 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
 
-	amd_decode_nb_mce(node, &regs, 1);
+	/* do the two bits[14:13] together */
+	ecc = m->status & (3ULL << 45);
+	if (ecc)
+		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
+
+	pr_cont("\n");
+
+	if (m->bank == 4) {
+		regs.nbsl  = (u32) m->status;
+		regs.nbsh  = (u32)(m->status >> 32);
+		regs.nbeal = (u32) m->addr;
+		regs.nbeah = (u32)(m->addr >> 32);
+		node       = cpu_data(m->extcpu).cpu_node_id;
+
+		amd_decode_nb_mce(node, &regs, 1);
+	}
 }
diff --git a/drivers/edac/edac_mce_amd.h b/drivers/edac/edac_mce_amd.h
index 3825697..8651962 100644
--- a/drivers/edac/edac_mce_amd.h
+++ b/drivers/edac/edac_mce_amd.h
@@ -62,7 +62,7 @@ struct err_regs {
 
 
 void amd_report_gart_errors(bool);
-void amd_set_nb_bus_decoder(void (*f)(int, struct err_regs *, int));
+void amd_set_nb_bus_decoder(void (*f)(int, struct err_regs *));
 void amd_decode_nb_mce(int, struct err_regs *, int);
 
 #endif /* _EDAC_MCE_AMD_H */
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 14/20] EDAC, AMD: carve out decoding of MCi_STATUS ErrorCode
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (12 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 13/20] EDAC, AMD: carve out MCi_STATUS decoding Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 15/20] EDAC, AMD: decode data cache MCEs Borislav Petkov
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

This is the MCE error code from the MCi_STATUS banks, bits [15:0] which
describe what type of error was encountered: GART TLB, Memory or Bus
error. The semantics of those bits are identical across all MCE banks so
decode those separately, irrespectively of MCE type.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c   |    4 ----
 drivers/edac/edac_mce_amd.c |   37 ++++++++++++++++++++++---------------
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 2684392..69c8e6d 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2287,10 +2287,6 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
 	u32 xec = EXT_ERROR_CODE(info->nbsl);
 	int ecc_type = info->nbsh & (0x3 << 13);
 
-	pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, %s\n",
-		 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec), PP_MSG(ec));
-
-
 	/* Bail early out if this was an 'observed' error */
 	if (PP(ec) == K8_NBSL_PP_OBS)
 		return;
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 499af60..e332da0 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -140,6 +140,16 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
 	}
 
+
+	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+
+	if (BUS_ERROR(ec) && nb_bus_decoder)
+		nb_bus_decoder(node_id, regs);
+}
+EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
+
+static inline void amd_decode_err_code(unsigned int ec)
+{
 	if (TLB_ERROR(ec)) {
 		/*
 		 * GART errors are intended to help graphics driver developers
@@ -156,33 +166,28 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 		if (!report_gart_errors)
 			return;
 
-		pr_emerg(" GART TLB error, Transaction: %s, Cache Level %s\n",
+		pr_emerg(" Transaction: %s, Cache Level %s\n",
 			 TT_MSG(ec), LL_MSG(ec));
 	} else if (MEM_ERROR(ec)) {
-		pr_emerg(" Memory/Cache error, Transaction: %s, Type: %s,"
-			 " Cache Level: %s",
+		pr_emerg(" Transaction: %s, Type: %s, Cache Level: %s",
 			 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
 	} else if (BUS_ERROR(ec)) {
-		pr_emerg(" Bus (Link/DRAM) error\n");
-		if (nb_bus_decoder)
-			nb_bus_decoder(node_id, regs);
-	} else {
-		/* shouldn't reach here! */
-		pr_warning("%s: unknown MCE error 0x%x\n", __func__, ec);
-	}
-
-	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+		pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, "
+			 "Participating Processor: %s\n",
+			  RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec),
+			  PP_MSG(ec));
+	} else
+		pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
 }
-EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
 
 void decode_mce(struct mce *m)
 {
 	struct err_regs regs;
 	int node, ecc;
 
-	pr_emerg("MC%d_STATUS:\n", m->bank);
+	pr_emerg("MC%d_STATUS: ", m->bank);
 
-	pr_emerg(" Error: %sorrected, Report: %s, MiscV: %svalid, "
+	pr_cont("%sorrected error, report: %s, MiscV: %svalid, "
 		 "CPU context corrupt: %s",
 		 ((m->status & MCI_STATUS_UC) ? "Unc"  : "C"),
 		 ((m->status & MCI_STATUS_EN) ? "yes"  : "no"),
@@ -196,6 +201,8 @@ void decode_mce(struct mce *m)
 
 	pr_cont("\n");
 
+	amd_decode_err_code(m->status & 0xffff);
+
 	if (m->bank == 4) {
 		regs.nbsl  = (u32) m->status;
 		regs.nbsh  = (u32)(m->status >> 32);
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 15/20] EDAC, AMD: decode data cache MCEs
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (13 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 14/20] EDAC, AMD: carve out decoding of MCi_STATUS ErrorCode Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 16/20] EDAC, AMD: decode instruction " Borislav Petkov
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

Those get reported in MC0_STATUS, see Table 92, F10h BKDG (31116, rev.
3.28) for more details.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/edac_mce_amd.c |   56 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index e332da0..07875d6 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -118,6 +118,49 @@ const char *ext_msgs[] = {
 };
 EXPORT_SYMBOL_GPL(ext_msgs);
 
+static void amd_decode_dc_mce(u64 mc0_status)
+{
+	u32 ec  = mc0_status & 0xffff;
+	u32 xec = (mc0_status >> 16) & 0xf;
+
+	pr_emerg(" Data Cache Error");
+
+	if (xec == 1 && TLB_ERROR(ec))
+		pr_cont(": %s TLB multimatch.\n", LL_MSG(ec));
+	else if (xec == 0) {
+		if (mc0_status & (1ULL << 40))
+			pr_cont(" during Data Scrub.\n");
+		else if (TLB_ERROR(ec))
+			pr_cont(": %s TLB parity error.\n", LL_MSG(ec));
+		else if (MEM_ERROR(ec)) {
+			u8 ll   = ec & 0x3;
+			u8 tt   = (ec >> 2) & 0x3;
+			u8 rrrr = (ec >> 4) & 0xf;
+
+			/* see F10h BKDG (31116), Table 92. */
+			if (ll == 0x1) {
+				if (tt != 0x1)
+					goto wrong_dc_mce;
+
+				pr_cont(": Data/Tag %s error.\n", RRRR_MSG(ec));
+
+			} else if (ll == 0x2 && rrrr == 0x3)
+				pr_cont(" during L1 linefill from L2.\n");
+			else
+				goto wrong_dc_mce;
+		} else if (BUS_ERROR(ec) && boot_cpu_data.x86 == 0xf)
+			pr_cont(" during system linefill.\n");
+		else
+			goto wrong_dc_mce;
+	} else
+		goto wrong_dc_mce;
+
+	return;
+
+wrong_dc_mce:
+	pr_warning("Corrupted DC MCE info?\n");
+}
+
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
 	u32 ec  = ERROR_CODE(regs->nbsl);
@@ -201,9 +244,12 @@ void decode_mce(struct mce *m)
 
 	pr_cont("\n");
 
-	amd_decode_err_code(m->status & 0xffff);
+	switch (m->bank) {
+	case 0:
+		amd_decode_dc_mce(m->status);
+		break;
 
-	if (m->bank == 4) {
+	case 4:
 		regs.nbsl  = (u32) m->status;
 		regs.nbsh  = (u32)(m->status >> 32);
 		regs.nbeal = (u32) m->addr;
@@ -211,5 +257,11 @@ void decode_mce(struct mce *m)
 		node       = cpu_data(m->extcpu).cpu_node_id;
 
 		amd_decode_nb_mce(node, &regs, 1);
+		break;
+
+	default:
+		break;
 	}
+
+	amd_decode_err_code(m->status & 0xffff);
 }
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 16/20] EDAC, AMD: decode instruction cache MCEs
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (14 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 15/20] EDAC, AMD: decode data cache MCEs Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 17/20] EDAC, AMD: decode bus unit MCEs Borislav Petkov
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

See Fam10h BKDG (31116, rev. 3.28), Table 95

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/edac_mce_amd.c |   61 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 07875d6..54d0de3 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -161,6 +161,63 @@ wrong_dc_mce:
 	pr_warning("Corrupted DC MCE info?\n");
 }
 
+static void amd_decode_ic_mce(u64 mc1_status)
+{
+	u32 ec  = mc1_status & 0xffff;
+	u32 xec = (mc1_status >> 16) & 0xf;
+
+	pr_emerg(" Instruction Cache Error");
+
+	if (xec == 1 && TLB_ERROR(ec))
+		pr_cont(": %s TLB multimatch.\n", LL_MSG(ec));
+	else if (xec == 0) {
+		if (TLB_ERROR(ec))
+			pr_cont(": %s TLB Parity error.\n", LL_MSG(ec));
+		else if (BUS_ERROR(ec)) {
+			if (boot_cpu_data.x86 == 0xf &&
+			    (mc1_status & (1ULL << 58)))
+				pr_cont(" during system linefill.\n");
+			else
+				pr_cont(" during attempted NB data read.\n");
+		} else if (MEM_ERROR(ec)) {
+			u8 ll   = ec & 0x3;
+			u8 rrrr = (ec >> 4) & 0xf;
+
+			if (ll == 0x2)
+				pr_cont(" during a linefill from L2.\n");
+			else if (ll == 0x1) {
+
+				switch (rrrr) {
+				case 0x5:
+					pr_cont(": Parity error during "
+					       "data load.\n");
+					break;
+
+				case 0x7:
+					pr_cont(": Copyback Parity/Victim"
+						" error.\n");
+					break;
+
+				case 0x8:
+					pr_cont(": Tag Snoop error.\n");
+					break;
+
+				default:
+					goto wrong_ic_mce;
+					break;
+				}
+			}
+		} else
+			goto wrong_ic_mce;
+	} else
+		goto wrong_ic_mce;
+
+	return;
+
+wrong_ic_mce:
+	pr_warning("Corrupted IC MCE info?\n");
+}
+
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
 	u32 ec  = ERROR_CODE(regs->nbsl);
@@ -249,6 +306,10 @@ void decode_mce(struct mce *m)
 		amd_decode_dc_mce(m->status);
 		break;
 
+	case 1:
+		amd_decode_ic_mce(m->status);
+		break;
+
 	case 4:
 		regs.nbsl  = (u32) m->status;
 		regs.nbsh  = (u32)(m->status >> 32);
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 17/20] EDAC, AMD: decode bus unit MCEs
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (15 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 16/20] EDAC, AMD: decode instruction " Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 18/20] EDAC, AMD: decode load store MCEs Borislav Petkov
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

... according to Table 69, Fam10h BKDG (31116, rev. 3.28).

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/edac_mce_amd.c |   46 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 54d0de3..ab0e6e7 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -218,6 +218,48 @@ wrong_ic_mce:
 	pr_warning("Corrupted IC MCE info?\n");
 }
 
+static void amd_decode_bu_mce(u64 mc2_status)
+{
+	u32 ec = mc2_status & 0xffff;
+	u32 xec = (mc2_status >> 16) & 0xf;
+
+	pr_emerg(" Bus Unit Error");
+
+	if (xec == 0x1)
+		pr_cont(" in the write data buffers.\n");
+	else if (xec == 0x3)
+		pr_cont(" in the victim data buffers.\n");
+	else if (xec == 0x2 && MEM_ERROR(ec))
+		pr_cont(": %s error in the L2 cache tags.\n", RRRR_MSG(ec));
+	else if (xec == 0x0) {
+		if (TLB_ERROR(ec))
+			pr_cont(": %s error in a Page Descriptor Cache or "
+				"Guest TLB.\n", TT_MSG(ec));
+		else if (BUS_ERROR(ec))
+			pr_cont(": %s/ECC error in data read from NB: %s.\n",
+				RRRR_MSG(ec), PP_MSG(ec));
+		else if (MEM_ERROR(ec)) {
+			u8 rrrr = (ec >> 4) & 0xf;
+
+			if (rrrr >= 0x7)
+				pr_cont(": %s error during data copyback.\n",
+					RRRR_MSG(ec));
+			else if (rrrr <= 0x1)
+				pr_cont(": %s parity/ECC error during data "
+					"access from L2.\n", RRRR_MSG(ec));
+			else
+				goto wrong_bu_mce;
+		} else
+			goto wrong_bu_mce;
+	} else
+		goto wrong_bu_mce;
+
+	return;
+
+wrong_bu_mce:
+	pr_warning("Corrupted BU MCE info?\n");
+}
+
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
 	u32 ec  = ERROR_CODE(regs->nbsl);
@@ -310,6 +352,10 @@ void decode_mce(struct mce *m)
 		amd_decode_ic_mce(m->status);
 		break;
 
+	case 2:
+		amd_decode_bu_mce(m->status);
+		break;
+
 	case 4:
 		regs.nbsl  = (u32) m->status;
 		regs.nbsh  = (u32)(m->status >> 32);
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 18/20] EDAC, AMD: decode load store MCEs
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (16 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 17/20] EDAC, AMD: decode bus unit MCEs Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 19/20] EDAC, AMD: decode FR MCEs Borislav Petkov
  2009-07-28 15:06 ` [PATCH 20/20] x86, mce: do not compile mcelog message on AMD Borislav Petkov
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

See Fam10h BKDG (31116, rev. 3.28), Table 100.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/edac_mce_amd.c |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index ab0e6e7..1c4468f 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -260,6 +260,27 @@ wrong_bu_mce:
 	pr_warning("Corrupted BU MCE info?\n");
 }
 
+static void amd_decode_ls_mce(u64 mc3_status)
+{
+	u32 ec  = mc3_status & 0xffff;
+	u32 xec = (mc3_status >> 16) & 0xf;
+
+	pr_emerg(" Load Store Error");
+
+	if (xec == 0x0) {
+		u8 rrrr = (ec >> 4) & 0xf;
+
+		if (!BUS_ERROR(ec) || (rrrr != 0x3 && rrrr != 0x4))
+			goto wrong_ls_mce;
+
+		pr_cont(" during %s.\n", RRRR_MSG(ec));
+	}
+	return;
+
+wrong_ls_mce:
+	pr_warning("Corrupted LS MCE info?\n");
+}
+
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
 	u32 ec  = ERROR_CODE(regs->nbsl);
@@ -356,6 +377,10 @@ void decode_mce(struct mce *m)
 		amd_decode_bu_mce(m->status);
 		break;
 
+	case 3:
+		amd_decode_ls_mce(m->status);
+		break;
+
 	case 4:
 		regs.nbsl  = (u32) m->status;
 		regs.nbsh  = (u32)(m->status >> 32);
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 19/20] EDAC, AMD: decode FR MCEs
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (17 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 18/20] EDAC, AMD: decode load store MCEs Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  2009-07-28 15:06 ` [PATCH 20/20] x86, mce: do not compile mcelog message on AMD Borislav Petkov
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86

See Fam10h BKDG (31116, rev. 3.28), Table 101.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/edac_mce_amd.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 1c4468f..a78d16c 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -311,6 +311,15 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 }
 EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
 
+static void amd_decode_fr_mce(u64 mc5_status)
+{
+	/* we have only one error signature so match all fields at once. */
+	if ((mc5_status & 0xffff) == 0x0f0f)
+		pr_emerg(" FR Error: CPU Watchdog timer expire.\n");
+	else
+		pr_warning("Corrupted FR MCE info?\n");
+}
+
 static inline void amd_decode_err_code(unsigned int ec)
 {
 	if (TLB_ERROR(ec)) {
@@ -391,6 +400,10 @@ void decode_mce(struct mce *m)
 		amd_decode_nb_mce(node, &regs, 1);
 		break;
 
+	case 5:
+		amd_decode_fr_mce(m->status);
+		break;
+
 	default:
 		break;
 	}
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 20/20] x86, mce: do not compile mcelog message on AMD
  2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
                   ` (18 preceding siblings ...)
  2009-07-28 15:06 ` [PATCH 19/20] EDAC, AMD: decode FR MCEs Borislav Petkov
@ 2009-07-28 15:06 ` Borislav Petkov
  19 siblings, 0 replies; 21+ messages in thread
From: Borislav Petkov @ 2009-07-28 15:06 UTC (permalink / raw)
  To: mingo, hpa, tglx, norsk5, aris; +Cc: linux-kernel, x86, Andi Kleen

Now that decoding is done in-kernel, suppress mcelog message part.

CC: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/mcheck/mce.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 69e7d8e..f7a2b42 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -222,7 +222,10 @@ static void print_mce_head(void)
 static void print_mce_tail(void)
 {
 	printk(KERN_EMERG "This is not a software problem!\n"
-	       "Run through mcelog --ascii to decode and contact your hardware vendor\n");
+#if (!defined(CONFIG_EDAC) || !defined(CONFIG_CPU_SUP_AMD))
+	       "Run through mcelog --ascii to decode and contact your hardware vendor\n"
+#endif
+	       );
 }
 
 #define PANIC_TIMEOUT 5 /* 5 seconds */
-- 
1.6.3.3



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2009-07-28 15:11 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-28 15:06 [RFC PATCH 0/20 v2] marry mcheck to EDAC Borislav Petkov
2009-07-28 15:06 ` [PATCH 01/20] topology: introduce cpu_node information for multi-node processors Borislav Petkov
2009-07-28 15:06 ` [PATCH 02/20] x86: provide CPU topology " Borislav Petkov
2009-07-28 15:06 ` [PATCH 03/20] x86: add cpu_node topology detection for AMD Magny-Cours Borislav Petkov
2009-07-28 15:06 ` [PATCH 04/20] x86: cacheinfo: fixup L3 cache information " Borislav Petkov
2009-07-28 15:06 ` [PATCH 05/20] x86: mcheck: make use of cpu_node_mask instead of cpu_core_mask to support multi-node processors Borislav Petkov
2009-07-28 15:06 ` [PATCH 06/20] EDAC: move MCE error descriptions to EDAC core Borislav Petkov
2009-07-28 15:06 ` [PATCH 07/20] EDAC: beef up ErrorCodeExt error signatures Borislav Petkov
2009-07-28 15:06 ` [PATCH 08/20] amd64_edac: cleanup amd64_process_error_info Borislav Petkov
2009-07-28 15:06 ` [PATCH 09/20] amd64_edac: cleanup/complete NB MCE decoding Borislav Petkov
2009-07-28 15:06 ` [PATCH 10/20] amd64_edac: remove memory and GART TLB error decoders Borislav Petkov
2009-07-28 15:06 ` [PATCH 11/20] amd64_edac: cleanup amd64_decode_bus_error Borislav Petkov
2009-07-28 15:06 ` [PATCH 12/20] x86, mce: pass mce info to EDAC for decoding Borislav Petkov
2009-07-28 15:06 ` [PATCH 13/20] EDAC, AMD: carve out MCi_STATUS decoding Borislav Petkov
2009-07-28 15:06 ` [PATCH 14/20] EDAC, AMD: carve out decoding of MCi_STATUS ErrorCode Borislav Petkov
2009-07-28 15:06 ` [PATCH 15/20] EDAC, AMD: decode data cache MCEs Borislav Petkov
2009-07-28 15:06 ` [PATCH 16/20] EDAC, AMD: decode instruction " Borislav Petkov
2009-07-28 15:06 ` [PATCH 17/20] EDAC, AMD: decode bus unit MCEs Borislav Petkov
2009-07-28 15:06 ` [PATCH 18/20] EDAC, AMD: decode load store MCEs Borislav Petkov
2009-07-28 15:06 ` [PATCH 19/20] EDAC, AMD: decode FR MCEs Borislav Petkov
2009-07-28 15:06 ` [PATCH 20/20] x86, mce: do not compile mcelog message on AMD Borislav Petkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome