From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756191AbcBPVby (ORCPT ); Tue, 16 Feb 2016 16:31:54 -0500 Received: from mail-by2on0069.outbound.protection.outlook.com ([207.46.100.69]:4419 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1756106AbcBPVbt (ORCPT ); Tue, 16 Feb 2016 16:31:49 -0500 Authentication-Results: alien8.de; dkim=none (message not signed) header.d=none;alien8.de; dmarc=none action=none header.from=amd.com; From: Aravind Gopalakrishnan To: , , , , , , CC: , , , , , , , , Subject: [PATCH 1/4] EDAC, MCE, AMD: Enable error decoding of Scalable MCA errors Date: Tue, 16 Feb 2016 15:45:08 -0600 Message-ID: <1455659111-32074-2-git-send-email-Aravind.Gopalakrishnan@amd.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1455659111-32074-1-git-send-email-Aravind.Gopalakrishnan@amd.com> References: <1455659111-32074-1-git-send-email-Aravind.Gopalakrishnan@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: BY2PR04CA0013.namprd04.prod.outlook.com (10.255.247.23) To SN1PR12MB0431.namprd12.prod.outlook.com (25.162.105.12) X-MS-Office365-Filtering-Correlation-Id: a905c6c8-32b0-419f-7238-08d33718919d X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0431;2:UrnK6mYfWoi/c72ZjXn0AUIk+q9DnVX44rq1l67m2jukCc1Mx4aBAC1qOzJBLerSA6ghCqjpQByqmCO+fi/UYUIbrsFcaLthi/d94f+VHV4Lz5u2Hj6yKJZjgUj/tr3oR3XclFOi2mBYMbq8gU3Cy8xjulVyjwp681tYMJWQHnQvBjmD3vL7ft8RbuXkv3ka;3:KsVokm2PWRT6pVPWjriyUtDHgI/6ehQKn3jwQYlhi0W8fVYSlAmAdho1lqZBkf/7L7Fe9aj2aFmP9XXp0hA3PQXWlp7Ka0Qsy3owZmCigWPtXxQjTLSHRH2Y5xXfTTpg;25:UTB+NXumY2SuaIiMIX54WYQcf/9MRNAcc+C+YCA4sz2QkvERdKPuWMf3nADdccIbXvmXLGEEYL2u5U8VpzXxwKXNntVlrMbzPa+4aodDJEnimRvY55Gs2rpQH78mRnV15Yjf3GkVLZHZgAlh2uljDXo0oeQ2evG/Roh9bBe6JWe2JEbqPZRI+gZgj6uH5VpBxNN2eDVEVLGSbRd+PhqkQBTXAkt6Ux+KnUUs/12STocPiXGul4B2e2JOe2B5Nkbjqnptx4yb93GViusAkea/a9QjWvlkpiBfSBArJS1pg2tEVx6iNgF0fxglMXniuxKZ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0431; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0431;20:kM8NUj6m0Xdb2kl2+oQx1gFsTkqZawwgoItgKmcJAnigQyxg7TJ+krwGO+IR92tRIDqJP8KX525+MMcx3gu0PA/DUp6BLNRr/uI8+5+1+V2u74eoY+oITKWWhdT6iTtQQK7vRbTxCHlEApK7/phtKwsFNSRElFxLTz5xjJCd+Pk3GXwFsckEFF0zvU+PYeSAlNNz9pm7tjSOG00rS+YERo52RUGfgPs0HuiVcIGszVVlY12spFRaHZyypxyF4h6tWE+HahwFLknGEYUBRMrhsZB0MmJpTLk/tskwqsUPFr2eyJNWtMn9y7Lgfog6puW4sqPanAKx+uOdlIpYR32bp5IlMXfaeT7/9lST5HTCmzTOvdDA6Jv4jwp2omzxxygpL1OMr90sx9DnR8u/+Uy7Rd9C+PoGXu6SabVquDKtz5GviNH4Jh6BHC8x/3DDytCrtVMj7Wz6FmwGmGnviVVaNdoU2D4IKiMLQAnfHXfNGYPo882UuSMr/3XFXegMZQx2;4:U6jekFwZpjCqJkSopXMKVLOIpbkEFcoDZA3q7BiwNltMAr82gxsxBBns4pPlNw5p9ckmGLQH3iK9Nk0ZOVZz2PT1qKLgeFxUA6tDJqry+7PlOJs1UZ1f8PkNNGFu9577+6cxrPWy2G6wlA8TShImdzM/S7vDFUTluzw040HYEb/6BQfOVtu9HVWZmQwgbLujya+3qwhNZnax/IR3IA4ljlCz7Cn8rohn/2zFRBiZF0kQNSLAEM3YV6dGTEmqMrTkdg1u2fTtR051L9rkvIxW3I/roTyjmOzTwar5AsuHFH8/iZIsEfbPNAhhGIDh6tFRVdOPnfyV6bCYqUNRuzjijzW57CEe3LkvSNA5Mv7Sa178BTSs5fvX7/Ko0sWm7MwpvULe2qE/T9qbBu3+E3R2TCBILcQALwdBE0kG7SSAAgg= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001);SRVR:SN1PR12MB0431;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0431; X-Forefront-PRVS: 0854128AF0 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(5008740100001)(5001770100001)(42186005)(19580395003)(53416004)(2201001)(19580405001)(189998001)(86362001)(77096005)(92566002)(87976001)(229853001)(50226001)(2950100001)(48376002)(1096002)(5003940100001)(4326007)(3846002)(36756003)(66066001)(2906002)(50986999)(40100003)(122386002)(5004730100002)(6116002)(76176999)(50466002)(586003)(47776003);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0431;H:arav-dinar.amd.com;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0431;23:xkkvJGFySKIZDnzn922i3rNVvab5leB1pVrTdJVY8ezZ13GQMHVu6ti6iMcCxGVMu5jJhxlt4/QOxe6F5VFLjib335ksxeCzfR5+3bX8dEYCeyW5F76amGqb8B/FSSm2LGxkiKdF0959Adv5/qR27tHbB5k3AGuc29QLgGxhXziFxZU59ZeH5qvXWCRjKIuWyWEwuKuHpGtUEBkOyYsgs+l8nd4trPIr3iNv/+J37dq9LEWPXShOejxuGZYASBKVD3wdfLrMeyXJduz7c7EE1cIhZkN3sbfBr1cgjyDBBr3TrDw7uKgqIXQ5U+Jl5BsFQm7m2QA3FjCWn5k0Urc61xDGRCSKKRbt0juHW6h0Z1LriIwuv7k2Gbzen8x7nuK/XWwEbY5MqLu3riMacZNwHQ33aiOSQ8Mpe0Wy7TSJG42lq28bkeY/hQF09epB8Ydvp0F7k71LDyhOHaXj2mTuD72mJrrQBxrDR/iw9SOwdXkKlnBeLPAPeTt7ZA0F1RCe+Te0spldwQTVsERBuhiw1I8QLe1pROmB5GSeKaQleemtXyxgFg1eYzzcxP7zu+N2VVxY1Q4i8Uxi7OnErkpgQAsDSUsNf0TMoEURq1x9ivbz0KnCOZo/JiRVbst4unHTeZzoxR2p/EUPrvLFQLZlgTC7voKH2cgXp5H1COolsLSIYcvfYVDX9Jyx68dc3U8WXhSe2k7EEfbMDuijpp0ozD91uQAutGw+aulXgzzhoVMGBDTATnm6RakjeBk+ECAUlKgIoW2a7qd+8SW6IJZhiuFRwIVlSjxoZKkVMmRqk+EOTX/VpizKhKP6fHeXgWLtpVJj227aS3q9BQM8pwZoMNKEAvAKUziRL6QPomT2FlUCNo1qKTdLYk1uwzSiEXPgcR5VLK16s3EBiN7aN/KBxmUaV/AcuG7bPBYMZV7DR8ukiie9tfuBIXi3PuVc8Nr8 X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0431;5:/7/DLMYdjIL+EQeQgIA9tgIFjP909xaG4GTS2q3AAa0osyLu9J284/5iRAPFZgRkG78Ey50JN7xY+kwX8ytrT8Zdo7Qyi0u8X1x9yiKwGXrgPkKIzDTo661A+j5u5hGdv7RRrwPWjk4AchXkrVI5qw==;24:CFpDHEkN7AW0cKxs4K9gtGVDAx7eV/N8+sgapMeE2RFRYInD82KexSmRF8WZYHk5/Lb/FFbnZFuHqsZFn0PujruBSDmva6+6v9g0IQIb9iY=;20:eMD1nyfPknGeQ+kzVdontgSo2ZuqtChAmxaUdtGDu5jUkisb8sKS+rAbX9tNNLg+fSHldSbBn2FphBIYtSbJKQjC3OtDxzmyreXm4EbkOJxTnzepXB8WqSBuxOoPfARyASkdIR22g+WU944d4yUH/yF1PO1D8OjUc1PV3N7d4Q+6F0lEXofsfjiaab4dZUCypCvW+h+46YoF/4JmAIiSWCM7Oe/NZVkZ1G0SjRixefUyNk6CmTwrJRiJ5ZFEsA1G X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Feb 2016 21:31:43.5503 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0431 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For Scalable MCA enabled processors, errors are listed per IP block. And since it is not required for an IP to map to a particular bank, we need to use HWID and McaType values from the MCx_IPID register to figure out which IP a given bank represents. We also have a new bit (TCC) in the MCx_STATUS register to indicate Task context is corrupt. Add logic here to decode errors from all known IP blocks for Fam17h Model 00-0fh and to print TCC errors. Signed-off-by: Aravind Gopalakrishnan --- arch/x86/include/asm/mce.h | 50 ++++++ arch/x86/include/asm/msr-index.h | 2 + arch/x86/kernel/cpu/mcheck/mce_amd.c | 11 ++ drivers/edac/mce_amd.c | 327 ++++++++++++++++++++++++++++++++++- 4 files changed, 389 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 2ea4527..2ec67ac 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -42,6 +42,17 @@ /* AMD-specific bits */ #define MCI_STATUS_DEFERRED (1ULL<<44) /* declare an uncorrected error */ #define MCI_STATUS_POISON (1ULL<<43) /* access poisonous data */ +#define MCI_STATUS_TCC (1ULL<<55) /* Task context corrupt */ +/* + * McaX field if set indicates a given bank supports MCA extensions: + * - Deferred error interrupt type is specifiable by bank + * - BlkPtr field indicates prescence of extended MISC registers. + * But should not be used to determine MSR numbers + * - TCC bit is present in MCx_STATUS + */ +#define MCI_CONFIG_MCAX 0x1 +#define MCI_IPID_MCATYPE 0xFFFF0000 +#define MCI_IPID_HWID 0xFFF /* * Note that the full MCACOD field of IA32_MCi_STATUS MSR is @@ -287,4 +298,43 @@ struct cper_sec_mem_err; extern void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err); +/* + * Enumerating new IP types and HWID values + * in ScalableMCA enabled AMD processors + */ +#ifdef CONFIG_X86_MCE_AMD +enum ip_types { + F17H_CORE = 0, /* Core errors */ + DF, /* Data Fabric */ + UMC, /* Unified Memory Controller */ + FUSE, /* FUSE subsystem */ + PSP, /* Platform Security Processor */ + SMU, /* System Management Unit */ + N_IP_TYPES +}; + +struct hwid { + const char *ipname; + unsigned int hwid_value; +}; + +extern struct hwid hwid_mappings[N_IP_TYPES]; + +enum core_mcatypes { + LS = 0, /* Load Store */ + IF, /* Instruction Fetch */ + L2_CACHE, /* L2 cache */ + DE, /* Decoder unit */ + RES, /* Reserved */ + EX, /* Execution unit */ + FP, /* Floating Point */ + L3_CACHE /* L3 cache */ +}; + +enum df_mcatypes { + CS = 0, /* Coherent Slave */ + PIE /* Power management, Interrupts, etc */ +}; +#endif + #endif /* _ASM_X86_MCE_H */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 5523465..93bccbc 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -266,7 +266,9 @@ /* 'SMCA': AMD64 Scalable MCA */ #define MSR_AMD64_SMCA_MC0_CONFIG 0xc0002004 +#define MSR_AMD64_SMCA_MC0_IPID 0xc0002005 #define MSR_AMD64_SMCA_MCx_CONFIG(x) (MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x)) +#define MSR_AMD64_SMCA_MCx_IPID(x) (MSR_AMD64_SMCA_MC0_IPID + 0x10*(x)) #define MSR_P6_PERFCTR0 0x000000c1 #define MSR_P6_PERFCTR1 0x000000c2 diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 88de27b..8169103 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -71,6 +71,17 @@ static const char * const th_names[] = { "execution_unit", }; +/* Defining HWID to IP type mappings for Scalable MCA */ +struct hwid hwid_mappings[] = { + [F17H_CORE] = { "f17h_core", 0xB0 }, + [DF] = { "df", 0x2E }, + [UMC] = { "umc", 0x96 }, + [FUSE] = { "fuse", 0x5 }, + [PSP] = { "psp", 0xFF }, + [SMU] = { "smu", 0x1 }, +}; +EXPORT_SYMBOL_GPL(hwid_mappings); + static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks); static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index e3a945c..6e6b327 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c @@ -147,6 +147,136 @@ static const char * const mc6_mce_desc[] = { "Status Register File", }; +/* Scalable MCA error strings */ + +static const char * const f17h_ls_mce_desc[] = { + "Load queue parity", + "Store queue parity", + "Miss address buffer payload parity", + "L1 TLB parity", + "", /* reserved */ + "DC tag error type 6", + "DC tag error type 1", + "Internal error type 1", + "Internal error type 2", + "Sys Read data error thread 0", + "Sys read data error thread 1", + "DC tag error type 2", + "DC data error type 1 (poison comsumption)", + "DC data error type 2", + "DC data error type 3", + "DC tag error type 4", + "L2 TLB parity", + "PDC parity error", + "DC tag error type 3", + "DC tag error type 5", + "L2 fill data error", +}; + +static const char * const f17h_if_mce_desc[] = { + "microtag probe port parity error", + "IC microtag or full tag multi-hit error", + "IC full tag parity", + "IC data array parity", + "Decoupling queue phys addr parity error", + "L0 ITLB parity error", + "L1 ITLB parity error", + "L2 ITLB parity error", + "BPQ snoop parity on Thread 0", + "BPQ snoop parity on Thread 1", + "L1 BTB multi-match error", + "L2 BTB multi-match error", +}; + +static const char * const f17h_l2_mce_desc[] = { + "L2M tag multi-way-hit error", + "L2M tag ECC error", + "L2M data ECC error", + "HW assert", +}; + +static const char * const f17h_de_mce_desc[] = { + "uop cache tag parity error", + "uop cache data parity error", + "Insn buffer parity error", + "Insn dispatch queue parity error", + "Fetch address FIFO parity", + "Patch RAM data parity", + "Patch RAM sequencer parity", + "uop buffer parity" +}; + +static const char * const f17h_ex_mce_desc[] = { + "Watchdog timeout error", + "Phy register file parity", + "Flag register file parity", + "Immediate displacement register file parity", + "Address generator payload parity", + "EX payload parity", + "Checkpoint queue parity", + "Retire dispatch queue parity", +}; + +static const char * const f17h_fp_mce_desc[] = { + "Physical register file parity", + "Freelist parity error", + "Schedule queue parity", + "NSQ parity error", + "Retire queue parity", + "Status register file parity", +}; + +static const char * const f17h_l3_mce_desc[] = { + "Shadow tag macro ECC error", + "Shadow tag macro multi-way-hit error", + "L3M tag ECC error", + "L3M tag multi-way-hit error", + "L3M data ECC error", + "XI parity, L3 fill done channel error", + "L3 victim queue parity", + "L3 HW assert", +}; + +static const char * const f17h_cs_mce_desc[] = { + "Illegal request from transport layer", + "Address violation", + "Security violation", + "Illegal response from transport layer", + "Unexpected response", + "Parity error on incoming request or probe response data", + "Parity error on incoming read response data", + "Atomic request parity", + "ECC error on probe filter access", +}; + +static const char * const f17h_pie_mce_desc[] = { + "HW assert", + "Internal PIE register security violation", + "Error on GMI link", + "Poison data written to internal PIE register", +}; + +static const char * const f17h_umc_mce_desc[] = { + "DRAM ECC error", + "Data poison error on DRAM", + "SDP parity error", + "Advanced peripheral bus error", + "Command/address parity error", + "Write data CRC error", +}; + +static const char * const f17h_fuse_mce_desc[] = { + "FUSE RAM ECC error", +}; + +static const char * const f17h_psp_mce_desc[] = { + "PSP RAM ECC or parity error", +}; + +static const char * const f17h_smu_mce_desc[] = { + "SMU RAM ECC or parity error", +}; + static bool f12h_mc0_mce(u16 ec, u8 xec) { bool ret = false; @@ -731,6 +861,178 @@ static bool amd_filter_mce(struct mce *m) return false; } +static void decode_f17hcore_errors(u8 xec, unsigned int mca_type) +{ + switch (mca_type) { + case LS: + if (xec == 0x4 || xec > (ARRAY_SIZE(f17h_ls_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_ls_mce_desc[xec]); + break; + + case IF: + if (xec > (ARRAY_SIZE(f17h_if_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_if_mce_desc[xec]); + break; + + case L2_CACHE: + if (xec > (ARRAY_SIZE(f17h_l2_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_l2_mce_desc[xec]); + break; + + case DE: + if (xec > (ARRAY_SIZE(f17h_de_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_de_mce_desc[xec]); + break; + + case EX: + if (xec > (ARRAY_SIZE(f17h_ex_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_ex_mce_desc[xec]); + break; + + case FP: + if (xec > (ARRAY_SIZE(f17h_fp_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_fp_mce_desc[xec]); + break; + + case L3_CACHE: + if (xec > (ARRAY_SIZE(f17h_l3_mce_desc) - 1)) + goto wrong_f17hcore_error; + + pr_cont("%s.\n", f17h_l3_mce_desc[xec]); + break; + + default: + goto wrong_f17hcore_error; + } + + return; + +wrong_f17hcore_error: + pr_cont("Unrecognized error code from %s MCA bank\n", + (mca_type == L3_CACHE) ? "L3 Cache" : "F17h Core"); +} + +static void decode_df_errors(u8 xec, unsigned int mca_type) +{ + switch (mca_type) { + case CS: + if (xec > (ARRAY_SIZE(f17h_cs_mce_desc) - 1)) + goto wrong_df_error; + + pr_cont("%s.\n", f17h_cs_mce_desc[xec]); + break; + + case PIE: + if (xec > (ARRAY_SIZE(f17h_pie_mce_desc) - 1)) + goto wrong_df_error; + + pr_cont("%s.\n", f17h_pie_mce_desc[xec]); + break; + + default: + goto wrong_df_error; + } + + return; + +wrong_df_error: + pr_cont("Unrecognized error code from DF MCA bank\n"); +} + +/* Decode errors according to Scalable MCA specification */ +static void decode_smca_errors(struct mce *m) +{ + u32 low, high; + u32 addr = MSR_AMD64_SMCA_MCx_IPID(m->bank); + unsigned int hwid, mca_type, i; + u8 xec = XEC(m->status, xec_mask); + + if (rdmsr_safe(addr, &low, &high)) { + pr_emerg("Unable to decode errors from banks\n"); + return; + } + + hwid = high & MCI_IPID_HWID; + mca_type = (high & MCI_IPID_MCATYPE) >> 16; + + pr_emerg(HW_ERR "MC%d IPID value: 0x%08x%08x\n", + m->bank, high, low); + + /* + * Based on hwid and mca_type values, + * decode errors from respective IPs. + * Note: mca_type values make sense only + * in the context of an hwid + */ + for (i = 0; i < ARRAY_SIZE(hwid_mappings); i++) + if (hwid_mappings[i].hwid_value == hwid) + break; + + switch (i) { + case F17H_CORE: + pr_emerg(HW_ERR "%s Error: ", + (mca_type == L3_CACHE) ? "L3 Cache" : "F17h Core"); + decode_f17hcore_errors(xec, mca_type); + break; + + case DF: + pr_emerg(HW_ERR "DF Error: "); + decode_df_errors(xec, mca_type); + break; + + case UMC: + pr_emerg(HW_ERR "UMC Error: "); + if (xec > (ARRAY_SIZE(f17h_umc_mce_desc) - 1)) { + pr_cont("Unrecognized error code from UMC MCA bank\n"); + return; + } + pr_cont("%s.\n", f17h_umc_mce_desc[xec]); + break; + + case FUSE: + pr_emerg(HW_ERR "FUSE Error: "); + if (xec > (ARRAY_SIZE(f17h_fuse_mce_desc) - 1)) { + pr_cont("Unrecognized error code from FUSE MCA bank\n"); + return; + } + pr_cont("%s.\n", f17h_fuse_mce_desc[xec]); + break; + + case PSP: + pr_emerg(HW_ERR "PSP Error: "); + if (xec > (ARRAY_SIZE(f17h_psp_mce_desc) - 1)) { + pr_cont("Unrecognized error code from PSP MCA bank\n"); + return; + } + pr_cont("%s.\n", f17h_psp_mce_desc[xec]); + break; + + case SMU: + pr_emerg(HW_ERR "SMU Error: "); + if (xec > (ARRAY_SIZE(f17h_smu_mce_desc) - 1)) { + pr_cont("Unrecognized error code from SMU MCA bank\n"); + return; + } + pr_cont("%s.\n", f17h_smu_mce_desc[xec]); + break; + + default: + pr_emerg(HW_ERR "HWID:%d does not match any existing IPs\n", hwid); + } +} + static const char *decode_error_status(struct mce *m) { if (m->status & MCI_STATUS_UC) { @@ -769,11 +1071,21 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"), ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-")); - if (c->x86 == 0x15 || c->x86 == 0x16) + if (c->x86 >= 0x15) pr_cont("|%s|%s", ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"), ((m->status & MCI_STATUS_POISON) ? "Poison" : "-")); + if (mce_flags.smca) { + u32 smca_low, smca_high; + u32 smca_addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank); + + if (!rdmsr_safe(smca_addr, &smca_low, &smca_high) && + (smca_low & MCI_CONFIG_MCAX)) + pr_cont("|%s", + ((m->status & MCI_STATUS_TCC) ? "TCC" : "-")); + } + /* do the two bits[14:13] together */ ecc = (m->status >> 45) & 0x3; if (ecc) @@ -784,6 +1096,11 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) if (m->status & MCI_STATUS_ADDRV) pr_emerg(HW_ERR "MC%d Error Address: 0x%016llx\n", m->bank, m->addr); + if (mce_flags.smca) { + decode_smca_errors(m); + goto err_code; + } + if (!fam_ops) goto err_code; @@ -888,6 +1205,14 @@ static int __init mce_amd_init(void) fam_ops->mc2_mce = f16h_mc2_mce; break; + case 0x17: + xec_mask = 0x3f; + if (!mce_flags.smca) { + printk(KERN_WARNING "Decoding supported only on Scalable MCA enabled processors\n"); + return 0; + } + break; + default: printk(KERN_WARNING "Huh? What family is it: 0x%x?!\n", c->x86); kfree(fam_ops); -- 2.7.0