[PATCH 1/3] x86/MCE/AMD: Provide an "Unknown" MCA bank type

From: Yazen Ghannam
Date: Thu Dec 02 2021 - 21:00:41 EST


The AMD MCA Thresholding sysfs interface populates directories for each
bank and thresholding block. The name used for each directory is looked
up in a table of known bank types. However, new bank types won't match
in this list and will return NULL for the name. This will cause the
machinecheck sysfs interface to fail to be populated.

Set new and unknown MCA bank types to the "unknown" type. Also,
ensure that the bank's thresholding block directories have unique names.
This will ensure that the machinecheck sysfs interface can be
initialized.

Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
---
arch/x86/include/asm/mce.h | 1 +
arch/x86/kernel/cpu/mce/amd.c | 34 ++++++++++++++++++++++++++++------
drivers/edac/mce_amd.c | 3 +++
3 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index d58f4f2e006f..7c1c35909946 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -319,6 +319,7 @@ enum smca_bank_types {
SMCA_XGMI_PCS, /* xGMI PCS Unit */
SMCA_XGMI_PHY, /* xGMI PHY Unit */
SMCA_WAFL_PHY, /* WAFL PHY Unit */
+ SMCA_UNKNOWN, /* Unknown type */
N_SMCA_BANK_TYPES
};

diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 2f351838d5f7..b9a5a94914a9 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -100,6 +100,7 @@ static struct smca_bank_name smca_names[] = {
[SMCA_XGMI_PCS] = { "xgmi_pcs", "Ext Global Memory Interconnect PCS Unit" },
[SMCA_XGMI_PHY] = { "xgmi_phy", "Ext Global Memory Interconnect PHY Unit" },
[SMCA_WAFL_PHY] = { "wafl_phy", "WAFL PHY Unit" },
+ [SMCA_UNKNOWN] = { "unknown", "Unrecognized Bank Type" },
};

static const char *smca_get_name(enum smca_bank_types t)
@@ -189,6 +190,9 @@ static struct smca_hwid smca_hwid_mcatypes[] = {

/* WAFL PHY MCA type */
{ SMCA_WAFL_PHY, HWID_MCATYPE(0x267, 0x0) },
+
+ /* Unknown type - this must be last in the list */
+ { SMCA_UNKNOWN, HWID_MCATYPE(0xFFF, 0xFFFF) },
};

struct smca_bank smca_banks[MAX_NR_BANKS];
@@ -300,7 +304,9 @@ static void smca_configure(unsigned int bank, unsigned int cpu)

for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) {
s_hwid = &smca_hwid_mcatypes[i];
- if (hwid_mcatype == s_hwid->hwid_mcatype) {
+
+ if (hwid_mcatype == s_hwid->hwid_mcatype ||
+ s_hwid->bank_type == SMCA_UNKNOWN) {
smca_banks[bank].hwid = s_hwid;
smca_banks[bank].id = low;
smca_banks[bank].sysfs_id = s_hwid->count++;
@@ -1032,12 +1038,28 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
return NULL;
}

- if (smca_banks[bank].hwid->count == 1)
- return smca_get_name(bank_type);
+ if (smca_banks[bank].hwid->count == 1) {
+ if (bank_type == SMCA_UNKNOWN) {
+ snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN,
+ "%s_%x", smca_get_name(bank_type),
+ smca_banks[bank].id);
+
+ return buf_mcatype;
+ } else {
+ return smca_get_name(bank_type);
+ }
+ }
+
+ if (b && bank_type == SMCA_UNKNOWN) {
+ snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN,
+ "%s_%x_block_%u", smca_get_name(bank_type),
+ smca_banks[bank].id, b->block);
+ } else {
+ snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN,
+ "%s_%u", smca_get_name(bank_type),
+ smca_banks[bank].sysfs_id);
+ }

- snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN,
- "%s_%x", smca_get_name(bank_type),
- smca_banks[bank].sysfs_id);
return buf_mcatype;
}

diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 67dbf4c31271..5ccc09db0a51 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -1068,6 +1068,9 @@ static void decode_smca_error(struct mce *m)

pr_emerg(HW_ERR "%s Ext. Error Code: %d", ip_name, xec);

+ if (bank_type == SMCA_UNKNOWN)
+ return;
+
/* Only print the decode of valid error codes */
if (xec < smca_mce_descs[bank_type].num_descs)
pr_cont(", %s.\n", smca_mce_descs[bank_type].descs[xec]);
--
2.25.1