Skip to content

Commit fe35415

Browse files
committed
Merge tag 'edac_updates_for_v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras
Pull EDAC updates from Borislav Petkov: "A small pile of EDAC updates which the autumn wind blew my way. :) - amd64_edac: Add support for three-rank interleaving mode which is present on AMD zen2 servers - The usual fixes and cleanups all over EDAC land" * tag 'edac_updates_for_v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell EDAC/ti: Remove redundant error messages EDAC/amd64: Handle three rank interleaving mode EDAC/mc_sysfs: Print MC-scope sysfs counters unsigned EDAC/al_mc: Make use of the helper function devm_add_action_or_reset() EDAC/mc: Replace strcpy(), sprintf() and snprintf() with strscpy() or scnprintf()
2 parents e664359 + 537bddd commit fe35415

File tree

6 files changed

+49
-44
lines changed

6 files changed

+49
-44
lines changed

drivers/edac/al_mc_edac.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,9 @@ static int al_mc_edac_probe(struct platform_device *pdev)
238238
if (!mci)
239239
return -ENOMEM;
240240

241-
ret = devm_add_action(&pdev->dev, devm_al_mc_edac_free, mci);
242-
if (ret) {
243-
edac_mc_free(mci);
241+
ret = devm_add_action_or_reset(&pdev->dev, devm_al_mc_edac_free, mci);
242+
if (ret)
244243
return ret;
245-
}
246244

247245
platform_set_drvdata(pdev, mci);
248246
al_mc = mci->pvt_info;
@@ -293,11 +291,9 @@ static int al_mc_edac_probe(struct platform_device *pdev)
293291
return ret;
294292
}
295293

296-
ret = devm_add_action(&pdev->dev, devm_al_mc_edac_del, &pdev->dev);
297-
if (ret) {
298-
edac_mc_del_mc(&pdev->dev);
294+
ret = devm_add_action_or_reset(&pdev->dev, devm_al_mc_edac_del, &pdev->dev);
295+
if (ret)
299296
return ret;
300-
}
301297

302298
if (al_mc->irq_ue > 0) {
303299
ret = devm_request_irq(&pdev->dev,

drivers/edac/amd64_edac.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,12 +1065,14 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
10651065
#define CS_ODD_PRIMARY BIT(1)
10661066
#define CS_EVEN_SECONDARY BIT(2)
10671067
#define CS_ODD_SECONDARY BIT(3)
1068+
#define CS_3R_INTERLEAVE BIT(4)
10681069

10691070
#define CS_EVEN (CS_EVEN_PRIMARY | CS_EVEN_SECONDARY)
10701071
#define CS_ODD (CS_ODD_PRIMARY | CS_ODD_SECONDARY)
10711072

10721073
static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
10731074
{
1075+
u8 base, count = 0;
10741076
int cs_mode = 0;
10751077

10761078
if (csrow_enabled(2 * dimm, ctrl, pvt))
@@ -1083,6 +1085,20 @@ static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
10831085
if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt))
10841086
cs_mode |= CS_ODD_SECONDARY;
10851087

1088+
/*
1089+
* 3 Rank inteleaving support.
1090+
* There should be only three bases enabled and their two masks should
1091+
* be equal.
1092+
*/
1093+
for_each_chip_select(base, ctrl, pvt)
1094+
count += csrow_enabled(base, ctrl, pvt);
1095+
1096+
if (count == 3 &&
1097+
pvt->csels[ctrl].csmasks[0] == pvt->csels[ctrl].csmasks[1]) {
1098+
edac_dbg(1, "3R interleaving in use.\n");
1099+
cs_mode |= CS_3R_INTERLEAVE;
1100+
}
1101+
10861102
return cs_mode;
10871103
}
10881104

@@ -1891,10 +1907,14 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
18911907
*
18921908
* The MSB is the number of bits in the full mask because BIT[0] is
18931909
* always 0.
1910+
*
1911+
* In the special 3 Rank interleaving case, a single bit is flipped
1912+
* without swapping with the most significant bit. This can be handled
1913+
* by keeping the MSB where it is and ignoring the single zero bit.
18941914
*/
18951915
msb = fls(addr_mask_orig) - 1;
18961916
weight = hweight_long(addr_mask_orig);
1897-
num_zero_bits = msb - weight;
1917+
num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE);
18981918

18991919
/* Take the number of zero bits off from the top of the mask. */
19001920
addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1);

drivers/edac/edac_mc.c

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,12 @@ unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
6666
char *p = buf;
6767

6868
for (i = 0; i < mci->n_layers; i++) {
69-
n = snprintf(p, len, "%s %d ",
69+
n = scnprintf(p, len, "%s %d ",
7070
edac_layer_name[mci->layers[i].type],
7171
dimm->location[i]);
7272
p += n;
7373
len -= n;
7474
count += n;
75-
if (!len)
76-
break;
7775
}
7876

7977
return count;
@@ -341,19 +339,16 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
341339
*/
342340
len = sizeof(dimm->label);
343341
p = dimm->label;
344-
n = snprintf(p, len, "mc#%u", mci->mc_idx);
342+
n = scnprintf(p, len, "mc#%u", mci->mc_idx);
345343
p += n;
346344
len -= n;
347345
for (layer = 0; layer < mci->n_layers; layer++) {
348-
n = snprintf(p, len, "%s#%u",
349-
edac_layer_name[mci->layers[layer].type],
350-
pos[layer]);
346+
n = scnprintf(p, len, "%s#%u",
347+
edac_layer_name[mci->layers[layer].type],
348+
pos[layer]);
351349
p += n;
352350
len -= n;
353351
dimm->location[layer] = pos[layer];
354-
355-
if (len <= 0)
356-
break;
357352
}
358353

359354
/* Link it to the csrows old API data */
@@ -1027,12 +1022,13 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
10271022
const char *other_detail)
10281023
{
10291024
struct dimm_info *dimm;
1030-
char *p;
1025+
char *p, *end;
10311026
int row = -1, chan = -1;
10321027
int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer };
10331028
int i, n_labels = 0;
10341029
struct edac_raw_error_desc *e = &mci->error_desc;
10351030
bool any_memory = true;
1031+
const char *prefix;
10361032

10371033
edac_dbg(3, "MC%d\n", mci->mc_idx);
10381034

@@ -1087,6 +1083,8 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
10871083
*/
10881084
p = e->label;
10891085
*p = '\0';
1086+
end = p + sizeof(e->label);
1087+
prefix = "";
10901088

10911089
mci_for_each_dimm(mci, dimm) {
10921090
if (top_layer >= 0 && top_layer != dimm->location[0])
@@ -1114,12 +1112,8 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
11141112
p = e->label;
11151113
*p = '\0';
11161114
} else {
1117-
if (p != e->label) {
1118-
strcpy(p, OTHER_LABEL);
1119-
p += strlen(OTHER_LABEL);
1120-
}
1121-
strcpy(p, dimm->label);
1122-
p += strlen(p);
1115+
p += scnprintf(p, end - p, "%s%s", prefix, dimm->label);
1116+
prefix = OTHER_LABEL;
11231117
}
11241118

11251119
/*
@@ -1141,25 +1135,25 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
11411135
}
11421136

11431137
if (any_memory)
1144-
strcpy(e->label, "any memory");
1138+
strscpy(e->label, "any memory", sizeof(e->label));
11451139
else if (!*e->label)
1146-
strcpy(e->label, "unknown memory");
1140+
strscpy(e->label, "unknown memory", sizeof(e->label));
11471141

11481142
edac_inc_csrow(e, row, chan);
11491143

11501144
/* Fill the RAM location data */
11511145
p = e->location;
1146+
end = p + sizeof(e->location);
1147+
prefix = "";
11521148

11531149
for (i = 0; i < mci->n_layers; i++) {
11541150
if (pos[i] < 0)
11551151
continue;
11561152

1157-
p += sprintf(p, "%s:%d ",
1158-
edac_layer_name[mci->layers[i].type],
1159-
pos[i]);
1153+
p += scnprintf(p, end - p, "%s%s:%d", prefix,
1154+
edac_layer_name[mci->layers[i].type], pos[i]);
1155+
prefix = " ";
11601156
}
1161-
if (p > e->location)
1162-
*(p - 1) = '\0';
11631157

11641158
edac_raw_mc_handle_error(e);
11651159
}

drivers/edac/edac_mc_sysfs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ static ssize_t mci_ue_count_show(struct device *dev,
744744
{
745745
struct mem_ctl_info *mci = to_mci(dev);
746746

747-
return sprintf(data, "%d\n", mci->ue_mc);
747+
return sprintf(data, "%u\n", mci->ue_mc);
748748
}
749749

750750
static ssize_t mci_ce_count_show(struct device *dev,
@@ -753,7 +753,7 @@ static ssize_t mci_ce_count_show(struct device *dev,
753753
{
754754
struct mem_ctl_info *mci = to_mci(dev);
755755

756-
return sprintf(data, "%d\n", mci->ce_mc);
756+
return sprintf(data, "%u\n", mci->ce_mc);
757757
}
758758

759759
static ssize_t mci_ce_noinfo_show(struct device *dev,
@@ -762,7 +762,7 @@ static ssize_t mci_ce_noinfo_show(struct device *dev,
762762
{
763763
struct mem_ctl_info *mci = to_mci(dev);
764764

765-
return sprintf(data, "%d\n", mci->ce_noinfo_count);
765+
return sprintf(data, "%u\n", mci->ce_noinfo_count);
766766
}
767767

768768
static ssize_t mci_ue_noinfo_show(struct device *dev,
@@ -771,7 +771,7 @@ static ssize_t mci_ue_noinfo_show(struct device *dev,
771771
{
772772
struct mem_ctl_info *mci = to_mci(dev);
773773

774-
return sprintf(data, "%d\n", mci->ue_noinfo_count);
774+
return sprintf(data, "%u\n", mci->ue_noinfo_count);
775775
}
776776

777777
static ssize_t mci_seconds_show(struct device *dev,

drivers/edac/sb_edac.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ static u64 haswell_get_tohm(struct sbridge_pvt *pvt)
10521052
pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOHM_1, &reg);
10531053
rc = ((reg << 6) | rc) << 26;
10541054

1055-
return rc | 0x1ffffff;
1055+
return rc | 0x3ffffff;
10561056
}
10571057

10581058
static u64 knl_get_tolm(struct sbridge_pvt *pvt)

drivers/edac/ti_edac.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,8 @@ static int ti_edac_probe(struct platform_device *pdev)
245245

246246
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
247247
reg = devm_ioremap_resource(dev, res);
248-
if (IS_ERR(reg)) {
249-
edac_printk(KERN_ERR, EDAC_MOD_NAME,
250-
"EMIF controller regs not defined\n");
248+
if (IS_ERR(reg))
251249
return PTR_ERR(reg);
252-
}
253250

254251
layers[0].type = EDAC_MC_LAYER_ALL_MEM;
255252
layers[0].size = 1;
@@ -281,8 +278,6 @@ static int ti_edac_probe(struct platform_device *pdev)
281278
error_irq = platform_get_irq(pdev, 0);
282279
if (error_irq < 0) {
283280
ret = error_irq;
284-
edac_printk(KERN_ERR, EDAC_MOD_NAME,
285-
"EMIF irq number not defined.\n");
286281
goto err;
287282
}
288283

0 commit comments

Comments
 (0)