Commit 02808fd9 authored by Borislav Petkov's avatar Borislav Petkov Committed by Greg Kroah-Hartman

EDAC: Correct channel count limit

commit bba14295 upstream.

c44696ff ("EDAC: Remove arbitrary limit on number of channels")
lifted the arbitrary limit on memory controller channels in EDAC.
However, the dynamic channel attributes dynamic_csrow_dimm_attr and
dynamic_csrow_ce_count_attr remained 6.

This wasn't a problem except channels 6 and 7 weren't visible in sysfs
on machines with more than 6 channels after the conversion to static
attr groups with

  2c1946b6 ("EDAC: Use static attribute groups for managing sysfs entries")

 [ without that, we're exploding in edac_create_sysfs_mci_device()
   because we're dereferencing out of the bounds of the
   dynamic_csrow_dimm_attr array. ]

Add attributes for channels 6 and 7 along with a guard for the
future, should more channels be required and/or to sanity check for
misconfigured machines.

We still need to check against the number of channels present on the MC
first, as Thor reported.
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reported-by: default avatarHironobu Ishii <ishii.hironobu@jp.fujitsu.com>
Tested-by: default avatarThor Thayer <tthayer@opensource.altera.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5c93b99d
...@@ -313,7 +313,6 @@ static struct device_type csrow_attr_type = { ...@@ -313,7 +313,6 @@ static struct device_type csrow_attr_type = {
* possible dynamic channel DIMM Label attribute files * possible dynamic channel DIMM Label attribute files
* *
*/ */
DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR, DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR,
channel_dimm_label_show, channel_dimm_label_store, 0); channel_dimm_label_show, channel_dimm_label_store, 0);
DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR, DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
...@@ -326,6 +325,10 @@ DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | S_IWUSR, ...@@ -326,6 +325,10 @@ DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | S_IWUSR,
channel_dimm_label_show, channel_dimm_label_store, 4); channel_dimm_label_show, channel_dimm_label_store, 4);
DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR, DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
channel_dimm_label_show, channel_dimm_label_store, 5); channel_dimm_label_show, channel_dimm_label_store, 5);
DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
channel_dimm_label_show, channel_dimm_label_store, 6);
DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
channel_dimm_label_show, channel_dimm_label_store, 7);
/* Total possible dynamic DIMM Label attribute file table */ /* Total possible dynamic DIMM Label attribute file table */
static struct attribute *dynamic_csrow_dimm_attr[] = { static struct attribute *dynamic_csrow_dimm_attr[] = {
...@@ -335,6 +338,8 @@ static struct attribute *dynamic_csrow_dimm_attr[] = { ...@@ -335,6 +338,8 @@ static struct attribute *dynamic_csrow_dimm_attr[] = {
&dev_attr_legacy_ch3_dimm_label.attr.attr, &dev_attr_legacy_ch3_dimm_label.attr.attr,
&dev_attr_legacy_ch4_dimm_label.attr.attr, &dev_attr_legacy_ch4_dimm_label.attr.attr,
&dev_attr_legacy_ch5_dimm_label.attr.attr, &dev_attr_legacy_ch5_dimm_label.attr.attr,
&dev_attr_legacy_ch6_dimm_label.attr.attr,
&dev_attr_legacy_ch7_dimm_label.attr.attr,
NULL NULL
}; };
...@@ -351,6 +356,10 @@ DEVICE_CHANNEL(ch4_ce_count, S_IRUGO, ...@@ -351,6 +356,10 @@ DEVICE_CHANNEL(ch4_ce_count, S_IRUGO,
channel_ce_count_show, NULL, 4); channel_ce_count_show, NULL, 4);
DEVICE_CHANNEL(ch5_ce_count, S_IRUGO, DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
channel_ce_count_show, NULL, 5); channel_ce_count_show, NULL, 5);
DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
channel_ce_count_show, NULL, 6);
DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
channel_ce_count_show, NULL, 7);
/* Total possible dynamic ce_count attribute file table */ /* Total possible dynamic ce_count attribute file table */
static struct attribute *dynamic_csrow_ce_count_attr[] = { static struct attribute *dynamic_csrow_ce_count_attr[] = {
...@@ -360,6 +369,8 @@ static struct attribute *dynamic_csrow_ce_count_attr[] = { ...@@ -360,6 +369,8 @@ static struct attribute *dynamic_csrow_ce_count_attr[] = {
&dev_attr_legacy_ch3_ce_count.attr.attr, &dev_attr_legacy_ch3_ce_count.attr.attr,
&dev_attr_legacy_ch4_ce_count.attr.attr, &dev_attr_legacy_ch4_ce_count.attr.attr,
&dev_attr_legacy_ch5_ce_count.attr.attr, &dev_attr_legacy_ch5_ce_count.attr.attr,
&dev_attr_legacy_ch6_ce_count.attr.attr,
&dev_attr_legacy_ch7_ce_count.attr.attr,
NULL NULL
}; };
...@@ -371,9 +382,16 @@ static umode_t csrow_dev_is_visible(struct kobject *kobj, ...@@ -371,9 +382,16 @@ static umode_t csrow_dev_is_visible(struct kobject *kobj,
if (idx >= csrow->nr_channels) if (idx >= csrow->nr_channels)
return 0; return 0;
if (idx >= ARRAY_SIZE(dynamic_csrow_ce_count_attr) - 1) {
WARN_ONCE(1, "idx: %d\n", idx);
return 0;
}
/* Only expose populated DIMMs */ /* Only expose populated DIMMs */
if (!csrow->channels[idx]->dimm->nr_pages) if (!csrow->channels[idx]->dimm->nr_pages)
return 0; return 0;
return attr->mode; return attr->mode;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment