mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 00/10] amd64_edac fixes
@ 2009-09-24 12:32 Borislav Petkov
  2009-09-24 12:32 ` [PATCH 01/10] amd64_edac: convert cpumask_t to struct cpumask ptr Borislav Petkov
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

Hi all,

here are a bunch of AMD64 EDAC fixes which have piled up
in the last couple of weeks. I'll push them to Linus after
b8a4754147d61f5359a765a3afd3eb03012aa052 in x86/cpu has gone upstream
and in case there are no complaints.

 drivers/edac/amd64_edac.c     |  289 +++++++++++++++++++++--------------------
 drivers/edac/amd64_edac.h     |   33 ++---
 drivers/edac/amd64_edac_inj.c |   49 ++++++-
 3 files changed, 206 insertions(+), 165 deletions(-)


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

* [PATCH 01/10] amd64_edac: convert cpumask_t to struct cpumask ptr
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 02/10] amd64_edac: unify MCGCTL ECC switching Borislav Petkov
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 4e551e6..53e617f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2633,7 +2633,7 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
 static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
-	const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
+	const struct cpumask *cpumask = cpumask_of_node(pvt->mc_node_id);
 	int cpu, idx = 0, err = 0;
 	struct msr msrs[cpumask_weight(cpumask)];
 	u32 value;
@@ -2709,7 +2709,7 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 
 static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 {
-	const cpumask_t *cpumask = cpumask_of_node(pvt->mc_node_id);
+	const struct cpumask *cpumask = cpumask_of_node(pvt->mc_node_id);
 	int cpu, idx = 0, err = 0;
 	struct msr msrs[cpumask_weight(cpumask)];
 	u32 value;
@@ -2742,7 +2742,7 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 }
 
 /* get all cores on this DCT */
-static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
+static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
 {
 	int cpu;
 
@@ -2754,7 +2754,7 @@ static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
 /* check MCG_CTL on all the cpus on this node */
 static bool amd64_nb_mce_bank_enabled_on_node(int nid)
 {
-	cpumask_t mask;
+	struct cpumask mask;
 	struct msr *msrs;
 	int cpu, nbe, idx = 0;
 	bool ret = false;
-- 
1.6.3.3



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

* [PATCH 02/10] amd64_edac: unify MCGCTL ECC switching
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
  2009-09-24 12:32 ` [PATCH 01/10] amd64_edac: convert cpumask_t to struct cpumask ptr Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 03/10] amd64_edac: fix driver instance lookup table allocation Borislav Petkov
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

Unify almost identical code into one function and remove NUMA-specific
usage (specifically cpumask_of_node()) in favor of generic topology
methods.

Remove unused defines, while at it.

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 53e617f..ebb5a96 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2626,6 +2626,96 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
 	return empty;
 }
 
+/* get all cores on this DCT */
+static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
+{
+	int cpu;
+
+	for_each_online_cpu(cpu)
+		if (amd_get_nb_id(cpu) == nid)
+			cpumask_set_cpu(cpu, mask);
+}
+
+/* check MCG_CTL on all the cpus on this node */
+static bool amd64_nb_mce_bank_enabled_on_node(int nid)
+{
+	struct cpumask mask;
+	struct msr *msrs;
+	int cpu, nbe, idx = 0;
+	bool ret = false;
+
+	cpumask_clear(&mask);
+
+	get_cpus_on_this_dct_cpumask(&mask, nid);
+
+	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
+	if (!msrs) {
+		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
+			      __func__);
+		 return false;
+	}
+
+	rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
+
+	for_each_cpu(cpu, &mask) {
+		nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
+
+		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
+			cpu, msrs[idx].q,
+			(nbe ? "enabled" : "disabled"));
+
+		if (!nbe)
+			goto out;
+
+		idx++;
+	}
+	ret = true;
+
+out:
+	kfree(msrs);
+	return ret;
+}
+
+static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
+{
+	struct cpumask cmask;
+	struct msr *msrs = NULL;
+	int cpu, idx = 0;
+
+	cpumask_clear(&cmask);
+	get_cpus_on_this_dct_cpumask(&cmask, pvt->mc_node_id);
+
+	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&cmask), GFP_KERNEL);
+	if (!msrs) {
+		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
+			     __func__);
+		return -ENOMEM;
+	}
+
+	rdmsr_on_cpus(&cmask, MSR_IA32_MCG_CTL, msrs);
+	for_each_cpu(cpu, &cmask) {
+
+		if (on) {
+			if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
+				pvt->flags.ecc_report = 1;
+
+			msrs[idx].l |= K8_MSR_MCGCTL_NBE;
+		} else {
+			/*
+			 * Turn off ECC reporting only when it was off before
+			 */
+			if (!pvt->flags.ecc_report)
+				msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
+		}
+		idx++;
+	}
+	wrmsr_on_cpus(&cmask, MSR_IA32_MCG_CTL, msrs);
+
+	kfree(msrs);
+
+	return 0;
+}
+
 /*
  * Only if 'ecc_enable_override' is set AND BIOS had ECC disabled, do "we"
  * enable it.
@@ -2633,17 +2723,12 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
 static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
-	const struct cpumask *cpumask = cpumask_of_node(pvt->mc_node_id);
-	int cpu, idx = 0, err = 0;
-	struct msr msrs[cpumask_weight(cpumask)];
-	u32 value;
-	u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+	int err = 0;
+	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
 	if (!ecc_enable_override)
 		return;
 
-	memset(msrs, 0, sizeof(msrs));
-
 	amd64_printk(KERN_WARNING,
 		"'ecc_enable_override' parameter is active, "
 		"Enabling AMD ECC hardware now: CAUTION\n");
@@ -2659,16 +2744,9 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 	value |= mask;
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
-	rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-
-	for_each_cpu(cpu, cpumask) {
-		if (msrs[idx].l & K8_MSR_MCGCTL_NBE)
-			set_bit(idx, &pvt->old_mcgctl);
-
-		msrs[idx].l |= K8_MSR_MCGCTL_NBE;
-		idx++;
-	}
-	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
+	if (amd64_toggle_ecc_err_reporting(pvt, ON))
+		amd64_printk(KERN_WARNING, "Error enabling ECC reporting over "
+					   "MCGCTL!\n");
 
 	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
 	if (err)
@@ -2709,17 +2787,12 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 
 static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 {
-	const struct cpumask *cpumask = cpumask_of_node(pvt->mc_node_id);
-	int cpu, idx = 0, err = 0;
-	struct msr msrs[cpumask_weight(cpumask)];
-	u32 value;
-	u32 mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
+	int err = 0;
+	u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
 	if (!pvt->nbctl_mcgctl_saved)
 		return;
 
-	memset(msrs, 0, sizeof(msrs));
-
 	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCTL, &value);
 	if (err)
 		debugf0("Reading K8_NBCTL failed\n");
@@ -2729,66 +2802,9 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 	/* restore the NB Enable MCGCTL bit */
 	pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
-	rdmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-
-	for_each_cpu(cpu, cpumask) {
-		msrs[idx].l &= ~K8_MSR_MCGCTL_NBE;
-		msrs[idx].l |=
-			test_bit(idx, &pvt->old_mcgctl) << K8_MSR_MCGCTL_NBE;
-		idx++;
-	}
-
-	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
-}
-
-/* get all cores on this DCT */
-static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
-{
-	int cpu;
-
-	for_each_online_cpu(cpu)
-		if (amd_get_nb_id(cpu) == nid)
-			cpumask_set_cpu(cpu, mask);
-}
-
-/* check MCG_CTL on all the cpus on this node */
-static bool amd64_nb_mce_bank_enabled_on_node(int nid)
-{
-	struct cpumask mask;
-	struct msr *msrs;
-	int cpu, nbe, idx = 0;
-	bool ret = false;
-
-	cpumask_clear(&mask);
-
-	get_cpus_on_this_dct_cpumask(&mask, nid);
-
-	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
-	if (!msrs) {
-		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
-			      __func__);
-		 return false;
-	}
-
-	rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
-
-	for_each_cpu(cpu, &mask) {
-		nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
-
-		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
-			cpu, msrs[idx].q,
-			(nbe ? "enabled" : "disabled"));
-
-		if (!nbe)
-			goto out;
-
-		idx++;
-	}
-	ret = true;
-
-out:
-	kfree(msrs);
-	return ret;
+	if (amd64_toggle_ecc_err_reporting(pvt, OFF))
+		amd64_printk(KERN_WARNING, "Error restoring ECC reporting over "
+					   "MCGCTL!\n");
 }
 
 /*
@@ -2917,7 +2933,6 @@ static int amd64_probe_one_instance(struct pci_dev *dram_f2_ctl,
 	pvt->ext_model		= boot_cpu_data.x86_model >> 4;
 	pvt->mc_type_index	= mc_type_index;
 	pvt->ops		= family_ops(mc_type_index);
-	pvt->old_mcgctl		= 0;
 
 	/*
 	 * We have the dram_f2_ctl device as an argument, now go reserve its
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 8ea07e2..ec08870 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -129,6 +129,9 @@
  *         sections 3.5.4 and 3.5.5 for more information.
  */
 
+#define ON true
+#define OFF false
+
 #define EDAC_AMD64_VERSION		" Ver: 3.2.0 " __DATE__
 #define EDAC_MOD_STR			"amd64_edac"
 
@@ -390,10 +393,7 @@ enum {
 #define K8_NBCAP_DUAL_NODE		BIT(1)
 #define K8_NBCAP_DCT_DUAL		BIT(0)
 
-/*
- * MSR Regs
- */
-#define K8_MSR_MCGCTL			0x017b
+/* MSR Regs */
 #define K8_MSR_MCGCTL_NBE		BIT(4)
 
 #define K8_MSR_MC4CTL			0x0410
@@ -490,7 +490,6 @@ struct amd64_pvt {
 	/* Save old hw registers' values before we modified them */
 	u32 nbctl_mcgctl_saved;		/* When true, following 2 are valid */
 	u32 old_nbctl;
-	unsigned long old_mcgctl;	/* per core on this node */
 
 	/* MC Type Index value: socket F vs Family 10h */
 	u32 mc_type_index;
@@ -498,6 +497,7 @@ struct amd64_pvt {
 	/* misc settings */
 	struct flags {
 		unsigned long cf8_extcfg:1;
+		unsigned long ecc_report:1;
 	} flags;
 };
 
-- 
1.6.3.3



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

* [PATCH 03/10] amd64_edac: fix driver instance lookup table allocation
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
  2009-09-24 12:32 ` [PATCH 01/10] amd64_edac: convert cpumask_t to struct cpumask ptr Borislav Petkov
  2009-09-24 12:32 ` [PATCH 02/10] amd64_edac: unify MCGCTL ECC switching Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 04/10] amd64_edac: fix DRAM base and limit address extraction Borislav Petkov
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

Allocate memory statically for 8-node machines max for simplicity
instead of relying on MAX_NUMNODES which is 0 on !CONFIG_NUMA builds.

Spotted by Jan Beulich.

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index ebb5a96..49911be 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -15,8 +15,8 @@ module_param(ecc_enable_override, int, 0644);
 
 /* Lookup table for all possible MC control instances */
 struct amd64_pvt;
-static struct mem_ctl_info *mci_lookup[MAX_NUMNODES];
-static struct amd64_pvt *pvt_lookup[MAX_NUMNODES];
+static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
+static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];
 
 /*
  * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index ec08870..ea96f5a 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -135,6 +135,8 @@
 #define EDAC_AMD64_VERSION		" Ver: 3.2.0 " __DATE__
 #define EDAC_MOD_STR			"amd64_edac"
 
+#define EDAC_MAX_NUMNODES		8
+
 /* Extended Model from CPUID, for CPU Revision numbers */
 #define OPTERON_CPU_LE_REV_C		0
 #define OPTERON_CPU_REV_D		1
-- 
1.6.3.3



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

* [PATCH 04/10] amd64_edac: fix DRAM base and limit address extraction
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (2 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 03/10] amd64_edac: fix driver instance lookup table allocation Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 05/10] amd64_edac: fix interleave enable tests Borislav Petkov
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

K8 DRAM base and limit addresses from F1x40 +8*i and F1x44 + 8*i, where
i in (0..7) are both bits 39-24 and therefore the shifting should be
done by 24 and not by 8.

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 49911be..96deaaf 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1130,7 +1130,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 		debugf0("Reading K8_DRAM_BASE_LOW failed\n");
 
 	/* Extract parts into separate data entries */
-	pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
+	pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
 	pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
 	pvt->dram_rw_en[dram] = (low & 0x3);
 
@@ -1143,7 +1143,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 	 * Extract parts into separate data entries. Limit is the HIGHEST memory
 	 * location of the region, so lower 24 bits need to be all ones
 	 */
-	pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
+	pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
 	pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
 	pvt->dram_DstNode[dram] = (low & 0x7);
 }
-- 
1.6.3.3



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

* [PATCH 05/10] amd64_edac: fix interleave enable tests
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (3 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 04/10] amd64_edac: fix DRAM base and limit address extraction Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 06/10] amd64_edac: fix K8 intlv_sel check Borislav Petkov
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

The pvt->dram_IntlvEn saves the 3 "Interleave Enable" bits already
right-shifted by 8 so the check in find_mc_by_sys_addr() by shifting the
values to the left 8 bits is wrong.

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 96deaaf..3dfb8e6 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -289,12 +289,12 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
 		goto found;
 	}
 
-	if (unlikely((intlv_en != (0x01 << 8)) &&
-		     (intlv_en != (0x03 << 8)) &&
-		     (intlv_en != (0x07 << 8)))) {
+	if (unlikely((intlv_en != 0x01) &&
+		     (intlv_en != 0x03) &&
+		     (intlv_en != 0x07))) {
 		amd64_printk(KERN_WARNING, "junk value of 0x%x extracted from "
 			     "IntlvEn field of DRAM Base Register for node 0: "
-			     "This probably indicates a BIOS bug.\n", intlv_en);
+			     "this probably indicates a BIOS bug.\n", intlv_en);
 		return NULL;
 	}
 
-- 
1.6.3.3



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

* [PATCH 06/10] amd64_edac: fix K8 intlv_sel check
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (4 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 05/10] amd64_edac: fix interleave enable tests Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 07/10] amd64_edac: simple fix to allow reporting of CECC errors Borislav Petkov
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

The check when DRAM interleaving is enabled should be done against the
pvt->dram_IntlvSel field and not against the ->dram_limit.

Simplify first loop and fixup printk formatting while at it.

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 3dfb8e6..3f98ae0 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -279,14 +279,11 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
 	intlv_en = pvt->dram_IntlvEn[0];
 
 	if (intlv_en == 0) {
-		for (node_id = 0; ; ) {
+		for (node_id = 0; node_id < DRAM_REG_COUNT; node_id++) {
 			if (amd64_base_limit_match(pvt, sys_addr, node_id))
-				break;
-
-			if (++node_id >= DRAM_REG_COUNT)
-				goto err_no_match;
+				goto found;
 		}
-		goto found;
+		goto err_no_match;
 	}
 
 	if (unlikely((intlv_en != 0x01) &&
@@ -301,7 +298,7 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
 	bits = (((u32) sys_addr) >> 12) & intlv_en;
 
 	for (node_id = 0; ; ) {
-		if ((pvt->dram_limit[node_id] & intlv_en) == bits)
+		if ((pvt->dram_IntlvSel[node_id] & intlv_en) == bits)
 			break;	/* intlv_sel field matches */
 
 		if (++node_id >= DRAM_REG_COUNT)
@@ -311,10 +308,10 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
 	/* sanity test for sys_addr */
 	if (unlikely(!amd64_base_limit_match(pvt, sys_addr, node_id))) {
 		amd64_printk(KERN_WARNING,
-			  "%s(): sys_addr 0x%lx falls outside base/limit "
-			  "address range for node %d with node interleaving "
-			  "enabled.\n", __func__, (unsigned long)sys_addr,
-			  node_id);
+			     "%s(): sys_addr 0x%llx falls outside base/limit "
+			     "address range for node %d with node interleaving "
+			     "enabled.\n",
+			     __func__, sys_addr, node_id);
 		return NULL;
 	}
 
-- 
1.6.3.3



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

* [PATCH 07/10] amd64_edac: simple fix to allow reporting of CECC errors
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (5 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 06/10] amd64_edac: fix K8 intlv_sel check Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 08/10] amd64_edac: fix chip select handling Borislav Petkov
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Keith Mannthey, Borislav Petkov

From: Keith Mannthey <kmannth@us.ibm.com>

This allows the errors to be further decoded and mapped to csrows.
Tested with ECC debug dimms and an Rev F cpu based system.

Signed-off-by: Keith Mannthey <kmannth@us.ibm.com>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 3f98ae0..cb3bbf2 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1190,7 +1190,7 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 	 * different from the node that detected the error.
 	 */
 	src_mci = find_mc_by_sys_addr(mci, SystemAddress);
-	if (src_mci) {
+	if (!src_mci) {
 		amd64_mc_printk(mci, KERN_ERR,
 			     "failed to map error address 0x%lx to a node\n",
 			     (unsigned long)SystemAddress);
-- 
1.6.3.3



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

* [PATCH 08/10] amd64_edac: fix chip select handling
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (6 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 07/10] amd64_edac: simple fix to allow reporting of CECC errors Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 09/10] amd64_edac: fix DRAM base and limit extraction Borislav Petkov
  2009-09-24 12:32 ` [PATCH 10/10] amd64_edac: beef up DRAM error injection Borislav Petkov
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov, Keith Mannthey

Different processor families support a different number of chip selects.
Handle this in a family-dependent way with the proper values assigned at
init time (see amd64_set_dct_base_and_mask).

Remove _DCSM_COUNT defines since they're used at one place and originate
from public documentation.

CC: Keith Mannthey <kmannth@us.ibm.com>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 drivers/edac/amd64_edac.c |   57 ++++++++++++++++++++------------------------
 drivers/edac/amd64_edac.h |   15 ++++-------
 2 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index cb3bbf2..c2c7def 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -189,7 +189,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
 /* Map from a CSROW entry to the mask entry that operates on it */
 static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
 {
-	return csrow >> (pvt->num_dcsm >> 3);
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
+		return csrow;
+	else
+		return csrow >> 1;
 }
 
 /* return the 'base' address the i'th CS entry of the 'dct' DRAM controller */
@@ -374,7 +377,7 @@ static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
 	 * base/mask register pair, test the condition shown near the start of
 	 * section 3.5.4 (p. 84, BKDG #26094, K8, revA-E).
 	 */
-	for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) {
+	for (csrow = 0; csrow < pvt->cs_count; csrow++) {
 
 		/* This DRAM chip select is disabled on this node */
 		if ((pvt->dcsb0[csrow] & K8_DCSB_CS_ENABLE) == 0)
@@ -731,7 +734,7 @@ static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
 	u64 base, mask;
 
 	pvt = mci->pvt_info;
-	BUG_ON((csrow < 0) || (csrow >= CHIPSELECT_COUNT));
+	BUG_ON((csrow < 0) || (csrow >= pvt->cs_count));
 
 	base = base_from_dct_base(pvt, csrow);
 	mask = mask_from_dct_mask(pvt, csrow);
@@ -959,35 +962,27 @@ err_reg:
  */
 static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
 {
-	if (pvt->ext_model >= OPTERON_CPU_REV_F) {
+
+	if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
+		pvt->dcsb_base		= REV_E_DCSB_BASE_BITS;
+		pvt->dcsm_mask		= REV_E_DCSM_MASK_BITS;
+		pvt->dcs_mask_notused	= REV_E_DCS_NOTUSED_BITS;
+		pvt->dcs_shift		= REV_E_DCS_SHIFT;
+		pvt->cs_count		= 8;
+		pvt->num_dcsm		= 8;
+	} else {
 		pvt->dcsb_base		= REV_F_F1Xh_DCSB_BASE_BITS;
 		pvt->dcsm_mask		= REV_F_F1Xh_DCSM_MASK_BITS;
 		pvt->dcs_mask_notused	= REV_F_F1Xh_DCS_NOTUSED_BITS;
 		pvt->dcs_shift		= REV_F_F1Xh_DCS_SHIFT;
 
-		switch (boot_cpu_data.x86) {
-		case 0xf:
-			pvt->num_dcsm = REV_F_DCSM_COUNT;
-			break;
-
-		case 0x10:
-			pvt->num_dcsm = F10_DCSM_COUNT;
-			break;
-
-		case 0x11:
-			pvt->num_dcsm = F11_DCSM_COUNT;
-			break;
-
-		default:
-			amd64_printk(KERN_ERR, "Unsupported family!\n");
-			break;
+		if (boot_cpu_data.x86 == 0x11) {
+			pvt->cs_count = 4;
+			pvt->num_dcsm = 2;
+		} else {
+			pvt->cs_count = 8;
+			pvt->num_dcsm = 4;
 		}
-	} else {
-		pvt->dcsb_base		= REV_E_DCSB_BASE_BITS;
-		pvt->dcsm_mask		= REV_E_DCSM_MASK_BITS;
-		pvt->dcs_mask_notused	= REV_E_DCS_NOTUSED_BITS;
-		pvt->dcs_shift		= REV_E_DCS_SHIFT;
-		pvt->num_dcsm		= REV_E_DCSM_COUNT;
 	}
 }
 
@@ -1000,7 +995,7 @@ static void amd64_read_dct_base_mask(struct amd64_pvt *pvt)
 
 	amd64_set_dct_base_and_mask(pvt);
 
-	for (cs = 0; cs < CHIPSELECT_COUNT; cs++) {
+	for (cs = 0; cs < pvt->cs_count; cs++) {
 		reg = K8_DCSB0 + (cs * 4);
 		err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
 						&pvt->dcsb0[cs]);
@@ -1563,7 +1558,7 @@ static int f10_lookup_addr_in_dct(u32 in_addr, u32 nid, u32 cs)
 
 	debugf1("InputAddr=0x%x  channelselect=%d\n", in_addr, cs);
 
-	for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) {
+	for (csrow = 0; csrow < pvt->cs_count; csrow++) {
 
 		cs_base = amd64_get_dct_base(pvt, cs, csrow);
 		if (!(cs_base & K8_DCSB_CS_ENABLE))
@@ -2494,7 +2489,7 @@ err_reg:
  * NOTE: CPU Revision Dependent code
  *
  * Input:
- *	@csrow_nr ChipSelect Row Number (0..CHIPSELECT_COUNT-1)
+ *	@csrow_nr ChipSelect Row Number (0..pvt->cs_count-1)
  *	k8 private pointer to -->
  *			DRAM Bank Address mapping register
  *			node_id
@@ -2574,7 +2569,7 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
 		(pvt->nbcfg & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled"
 		);
 
-	for (i = 0; i < CHIPSELECT_COUNT; i++) {
+	for (i = 0; i < pvt->cs_count; i++) {
 		csrow = &mci->csrows[i];
 
 		if ((pvt->dcsb0[i] & K8_DCSB_CS_ENABLE) == 0) {
@@ -3000,7 +2995,7 @@ static int amd64_init_2nd_stage(struct amd64_pvt *pvt)
 		goto err_exit;
 
 	ret = -ENOMEM;
-	mci = edac_mc_alloc(0, CHIPSELECT_COUNT, pvt->channel_count, node_id);
+	mci = edac_mc_alloc(0, pvt->cs_count, pvt->channel_count, node_id);
 	if (!mci)
 		goto err_exit;
 
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index ea96f5a..6a22b1e 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -147,7 +147,7 @@
 #define OPTERON_CPU_REV_FA		5
 
 /* Hardware limit on ChipSelect rows per MC and processors per system */
-#define CHIPSELECT_COUNT		8
+#define MAX_CS_COUNT			8
 #define DRAM_REG_COUNT			8
 
 
@@ -198,7 +198,6 @@
  */
 #define REV_E_DCSB_BASE_BITS		(0xFFE0FE00ULL)
 #define REV_E_DCS_SHIFT			4
-#define REV_E_DCSM_COUNT		8
 
 #define REV_F_F1Xh_DCSB_BASE_BITS	(0x1FF83FE0ULL)
 #define REV_F_F1Xh_DCS_SHIFT		8
@@ -209,9 +208,6 @@
  */
 #define REV_F_DCSB_BASE_BITS		(0x1FF83FE0ULL)
 #define REV_F_DCS_SHIFT			8
-#define REV_F_DCSM_COUNT		4
-#define F10_DCSM_COUNT			4
-#define F11_DCSM_COUNT			2
 
 /* DRAM CS Mask Registers */
 #define K8_DCSM0			0x60
@@ -447,12 +443,12 @@ struct amd64_pvt {
 	u32 dbam1;		/* DRAM Base Address Mapping reg for DCT1 */
 
 	/* DRAM CS Base Address Registers F2x[1,0][5C:40] */
-	u32 dcsb0[CHIPSELECT_COUNT];
-	u32 dcsb1[CHIPSELECT_COUNT];
+	u32 dcsb0[MAX_CS_COUNT];
+	u32 dcsb1[MAX_CS_COUNT];
 
 	/* DRAM CS Mask Registers F2x[1,0][6C:60] */
-	u32 dcsm0[CHIPSELECT_COUNT];
-	u32 dcsm1[CHIPSELECT_COUNT];
+	u32 dcsm0[MAX_CS_COUNT];
+	u32 dcsm1[MAX_CS_COUNT];
 
 	/*
 	 * Decoded parts of DRAM BASE and LIMIT Registers
@@ -472,6 +468,7 @@ struct amd64_pvt {
 	 */
 	u32 dcsb_base;		/* DCSB base bits */
 	u32 dcsm_mask;		/* DCSM mask bits */
+	u32 cs_count;		/* num chip selects (== num DCSB registers) */
 	u32 num_dcsm;		/* Number of DCSM registers */
 	u32 dcs_mask_notused;	/* DCSM notused mask bits */
 	u32 dcs_shift;		/* DCSB and DCSM shift value */
-- 
1.6.3.3



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

* [PATCH 09/10] amd64_edac: fix DRAM base and limit extraction
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (7 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 08/10] amd64_edac: fix chip select handling Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  2009-09-24 12:32 ` [PATCH 10/10] amd64_edac: beef up DRAM error injection Borislav Petkov
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

On Fam10h and above, F1x[1, 0][7C:40] are DRAM Base/Limit registers
which specify the destination node of a DRAM address. Those address
boundaries are being extracted into ->dram_base[] and ->dram_limit[].
Correct the extraction masks to match the respective address bits.

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

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index c2c7def..08cb744 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1368,8 +1368,8 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 
 	pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
 
-	pvt->dram_base[dram] = (((((u64) high_base & 0x000000FF) << 32) |
-				((u64) low_base & 0xFFFF0000))) << 8;
+	pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
+			       (((u64)low_base  & 0xFFFF0000) << 24);
 
 	low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
 	high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1390,9 +1390,9 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 	 * Extract address values and form a LIMIT address. Limit is the HIGHEST
 	 * memory location of the region, so low 24 bits need to be all ones.
 	 */
-	low_limit |= 0x0000FFFF;
-	pvt->dram_limit[dram] =
-		((((u64) high_limit << 32) + (u64) low_limit) << 8) | (0xFF);
+	pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
+				(((u64) low_limit & 0xFFFF0000) << 24) |
+				0x00FFFFFF;
 }
 
 static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
-- 
1.6.3.3



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

* [PATCH 10/10] amd64_edac: beef up DRAM error injection
  2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
                   ` (8 preceding siblings ...)
  2009-09-24 12:32 ` [PATCH 09/10] amd64_edac: fix DRAM base and limit extraction Borislav Petkov
@ 2009-09-24 12:32 ` Borislav Petkov
  9 siblings, 0 replies; 11+ messages in thread
From: Borislav Petkov @ 2009-09-24 12:32 UTC (permalink / raw)
  To: norsk5; +Cc: linux-kernel, x86, Borislav Petkov

When injecting DRAM ECC errors (F3xBC_x8), EccVector[15:0] is a bitmask
of which bits should be error injected when written to and holds the
payload of 16-bit DRAM word when read, respectively.

Add /sysfs members to show the DRAM ECC section/word/vector.

Fail wrong injection values entered over /sysfs instead of truncating
them.

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

diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 6a22b1e..ba9dfbf 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -375,13 +375,11 @@ enum {
 
 #define SET_NB_DRAM_INJECTION_WRITE(word, bits)  \
 					(BIT(((word) & 0xF) + 20) | \
-					BIT(17) |  \
-					((bits) & 0xF))
+					BIT(17) | bits)
 
 #define SET_NB_DRAM_INJECTION_READ(word, bits)  \
 					(BIT(((word) & 0xF) + 20) | \
-					BIT(16) |  \
-					((bits) & 0xF))
+					BIT(16) |  bits)
 
 #define K8_NBCAP			0xE8
 #define K8_NBCAP_CORES			(BIT(12)|BIT(13))
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index d3675b7..29f1f7a 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -1,5 +1,11 @@
 #include "amd64_edac.h"
 
+static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf)
+{
+	struct amd64_pvt *pvt = mci->pvt_info;
+	return sprintf(buf, "0x%x\n", pvt->injection.section);
+}
+
 /*
  * store error injection section value which refers to one of 4 16-byte sections
  * within a 64-byte cacheline
@@ -15,12 +21,26 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
 
 	ret = strict_strtoul(data, 10, &value);
 	if (ret != -EINVAL) {
+
+		if (value > 3) {
+			amd64_printk(KERN_WARNING,
+				     "%s: invalid section 0x%lx\n",
+				     __func__, value);
+			return -EINVAL;
+		}
+
 		pvt->injection.section = (u32) value;
 		return count;
 	}
 	return ret;
 }
 
+static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf)
+{
+	struct amd64_pvt *pvt = mci->pvt_info;
+	return sprintf(buf, "0x%x\n", pvt->injection.word);
+}
+
 /*
  * store error injection word value which refers to one of 9 16-bit word of the
  * 16-byte (128-bit + ECC bits) section
@@ -37,14 +57,25 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
 	ret = strict_strtoul(data, 10, &value);
 	if (ret != -EINVAL) {
 
-		value = (value <= 8) ? value : 0;
-		pvt->injection.word = (u32) value;
+		if (value > 8) {
+			amd64_printk(KERN_WARNING,
+				     "%s: invalid word 0x%lx\n",
+				     __func__, value);
+			return -EINVAL;
+		}
 
+		pvt->injection.word = (u32) value;
 		return count;
 	}
 	return ret;
 }
 
+static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf)
+{
+	struct amd64_pvt *pvt = mci->pvt_info;
+	return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
+}
+
 /*
  * store 16 bit error injection vector which enables injecting errors to the
  * corresponding bit within the error injection word above. When used during a
@@ -60,8 +91,14 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
 	ret = strict_strtoul(data, 16, &value);
 	if (ret != -EINVAL) {
 
-		pvt->injection.bit_map = (u32) value & 0xFFFF;
+		if (value & 0xFFFF0000) {
+			amd64_printk(KERN_WARNING,
+				     "%s: invalid EccVector: 0x%lx\n",
+				     __func__, value);
+			return -EINVAL;
+		}
 
+		pvt->injection.bit_map = (u32) value;
 		return count;
 	}
 	return ret;
@@ -147,7 +184,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
 			.name = "inject_section",
 			.mode = (S_IRUGO | S_IWUSR)
 		},
-		.show = NULL,
+		.show = amd64_inject_section_show,
 		.store = amd64_inject_section_store,
 	},
 	{
@@ -155,7 +192,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
 			.name = "inject_word",
 			.mode = (S_IRUGO | S_IWUSR)
 		},
-		.show = NULL,
+		.show = amd64_inject_word_show,
 		.store = amd64_inject_word_store,
 	},
 	{
@@ -163,7 +200,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
 			.name = "inject_ecc_vector",
 			.mode = (S_IRUGO | S_IWUSR)
 		},
-		.show = NULL,
+		.show = amd64_inject_ecc_vector_show,
 		.store = amd64_inject_ecc_vector_store,
 	},
 	{
-- 
1.6.3.3



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

end of thread, other threads:[~2009-09-24 12:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-24 12:32 [PATCH 00/10] amd64_edac fixes Borislav Petkov
2009-09-24 12:32 ` [PATCH 01/10] amd64_edac: convert cpumask_t to struct cpumask ptr Borislav Petkov
2009-09-24 12:32 ` [PATCH 02/10] amd64_edac: unify MCGCTL ECC switching Borislav Petkov
2009-09-24 12:32 ` [PATCH 03/10] amd64_edac: fix driver instance lookup table allocation Borislav Petkov
2009-09-24 12:32 ` [PATCH 04/10] amd64_edac: fix DRAM base and limit address extraction Borislav Petkov
2009-09-24 12:32 ` [PATCH 05/10] amd64_edac: fix interleave enable tests Borislav Petkov
2009-09-24 12:32 ` [PATCH 06/10] amd64_edac: fix K8 intlv_sel check Borislav Petkov
2009-09-24 12:32 ` [PATCH 07/10] amd64_edac: simple fix to allow reporting of CECC errors Borislav Petkov
2009-09-24 12:32 ` [PATCH 08/10] amd64_edac: fix chip select handling Borislav Petkov
2009-09-24 12:32 ` [PATCH 09/10] amd64_edac: fix DRAM base and limit extraction Borislav Petkov
2009-09-24 12:32 ` [PATCH 10/10] amd64_edac: beef up DRAM error injection Borislav Petkov

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

all inboxes | Powered by JetHome®