* [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, ®s))
+ amd64_process_error_info(mci, ®s, 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, ®s))
- amd64_process_error_info(mci, ®s, 1);
+ amd64_decode_nb_mce(mci, ®s, 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, ®s))
- amd64_decode_nb_mce(mci, ®s, 1);
+ if (amd64_get_error_info(mci, ®s)) {
+ struct amd64_pvt *pvt = mci->pvt_info;
+ amd_decode_nb_mce(pvt->mc_node_id, ®s, 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, ®s, 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, ®s, 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, ®s, 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, ®s, 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, ®s, 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