From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754693AbcB2WSn (ORCPT ); Mon, 29 Feb 2016 17:18:43 -0500 Received: from mail-bn1bon0089.outbound.protection.outlook.com ([157.56.111.89]:4032 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752162AbcB2WRb (ORCPT ); Mon, 29 Feb 2016 17:17:31 -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 V2 2/5] EDAC, MCE, AMD: Enable error decoding of Scalable MCA errors Date: Mon, 29 Feb 2016 16:32:56 -0600 Message-ID: <1456785179-14378-3-git-send-email-Aravind.Gopalakrishnan@amd.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1456785179-14378-1-git-send-email-Aravind.Gopalakrishnan@amd.com> References: <1456785179-14378-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: BLUPR11CA0023.namprd11.prod.outlook.com (10.141.240.33) To BY1PR12MB0424.namprd12.prod.outlook.com (25.162.147.13) X-MS-Office365-Filtering-Correlation-Id: ecaa1f35-bbe3-4e75-706c-08d341561b76 X-Microsoft-Exchange-Diagnostics: 1;BY1PR12MB0424;2:odDCgLhk1nlUYHtjEFxpKtbQJvM9A3fGZFQTixockFtnTQc7uJcYCOaybEsc2ISPQS9eWw3oo7bNWXPi3t8U8b+Tc0FHz/WfYXXk81KyCV6MkrJnyMm2MPaLX9O3tvy1HibnW1/wUJwcJ7ZtJXK1i5kim1yYJWt4uguucmnyGOlzjbj5aCBAtU48jzK9yvp6;3:nKsVfYVLZ8URLYYs54QX0fy5eJgPHRApZIHNtiROFZDkzrel+V0O50DS5Cx/AtNcdkn7r4G8elPIDcsUa/nIN7E8k4Rj0nukmC/Sq6JEiIzezB98Xxh4s3r/dD7cMo0f;25:A2vB5x5bwSqIgsBUCTEVvMKkf2IK4S40SfGq/4sT8PymUrmcMRzuGpwyRLJirQK1o9uOx8A9etD/ozfHnafvWQGpwza9g0LrCVQmsMysoIhGXTA5DVOCc4+LMu0ZH9BxjNo8O8EtqFGMN20NPSXLpR8G0JtjqdrHl1M+5xiOMPWKO3BRzpRdPQt9YJLsVm1XbjbSl5g+M50v3VsVZVrOl7SGfzFS6HJL00Eaysj8igoEDa+TstQv/S5tV2obx80QovYb84137Y8wn802n5+lZuXXgKHj+/LHvD49duY7GVIVMiwjOHPkISrjrjTvV0PK2+YVdU3tkVw9wNAf2mBR0A== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR12MB0424; X-Microsoft-Exchange-Diagnostics: 1;BY1PR12MB0424;20:Pq0uWznm8h3ygCLMy1P61aQl0kxvx8s2NjftKiOD1/xOehSYhU82dGxHAOYXidZ6dLY9UWF86nTmp8yZoK2JRqWGP8qD4u6agoYPwpMp67JQtkmToBqNyrzbF6cS5QVOuP8Ev7ssUPdvcNSixQPiJszrehTNcTfbjlMUVv+2Eitu8H8Wrj4I4MZSbPPv86Cmb4uaTZuFKMBClL7rWI+sqTRfCqTSLtWUMFpCxz1sseDgHFG+7JugUATOIOgAExj5VIUo6rSBRcmg7FWg0OGpc73X6bA0b41tstjFIzeoHyxXaFSfT5O9HSrKmLX3WE/gelooIsi+kWx7iABqQu05n1Snll67Q3Hn+gvYBO/yHM69/Kv+ZIImzuQXuMunUhss0I8+PIJF/F0Oz6WMQISUx4q/vxrlLsyx9TV40NDVWbTOFNQ9eAWPxEoqhfO8OiLX121DQZE7rVExz+ogng3hl7XVuGyIP2D0lPTmu/KiBBTZvXHVFS5jNFAsYLYDfDV/;4:JunTbaj0H/iD2w1awhxZNdwgEdvP6L61MI7Q8rW8zVtBqIaQC6E3zox8aAQYg7mAsiNOFsFNHCOd+5/ZSRlFuyJRafWQBm6spVfj97bRf6Gkm+XuMyMBB9QciOPaP2wa9ePAWf+DohBRa7wA29je+8saGYAu942Pf1EjcBY62TeZM6bN4Iyro3dxSPYVTe0JGd8kGSSFxWK9s2AvAchz19NaW9Q2W1GsX8zbq4BlpdxvoG8k9V08EAkUQKEDBtD3CHtZOSYN1yG1a8ZSitAScrf44jOtbPJ38l0NssRAtxBLx4WtUWxUmBgv7CC8WeEoEdQzvMZbZjWbYPwtfQ0W0zUuCmzA1lV/YgSkarbtK2Fx3OZtioGhP2Vng2sfvAKi X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001);SRVR:BY1PR12MB0424;BCL:0;PCL:0;RULEID:;SRVR:BY1PR12MB0424; X-Forefront-PRVS: 0867F4F1AA X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(2201001)(2950100001)(77096005)(87976001)(53416004)(122386002)(4326007)(2906002)(5001960100003)(50466002)(40100003)(42186005)(50226001)(189998001)(5003940100001)(5008740100001)(19580405001)(19580395003)(36756003)(5001770100001)(86362001)(92566002)(66066001)(47776003)(50986999)(5004730100002)(76176999)(1096002)(586003)(3846002)(229853001)(48376002)(6116002)(81156008);DIR:OUT;SFP:1101;SCL:1;SRVR:BY1PR12MB0424;H:arav-dinar.amd.com;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY1PR12MB0424;23:0Kekk2d9PypOEnFQ2aQKNbPvv3RyRUX74UkCbookl?= =?us-ascii?Q?y9IJUAjTegpgLaNGcv52jiWa82MWvPgBPxPRspxN+KNjewD7/Mp7KF9JW67d?= =?us-ascii?Q?KaGc6SHk7wBtlJ+jOUoMh5/jvZipuuYbJ4n8ChKHhoS+qoOPyP9lrUPWWMMa?= =?us-ascii?Q?pa72iH+Yxg7i6wmCqba9iYUN1d/DbCUncybOZALNjTvh9cir0ngmZWy8sLYW?= =?us-ascii?Q?IcJIjv4tVVN0XIvJ0762nOp3bn8tw6nsMg2Ejk0fC77yHyhnrIUrkbToolaD?= =?us-ascii?Q?CRWWDww4TUO/QLWqSDl0XC02X++/vA4bo+tRPSw08FFRJBFusQF/dPFEoKdf?= =?us-ascii?Q?Az6FJ6lhrKxXBpARTs33k2S+AKrhlTW9om1DjtDMbvn8TBH0FfNwEUjHcDul?= =?us-ascii?Q?XlNc7XnJkaSeu/35eA51cwt5pZgKGIDCJMiBrM310gpiax8QVnPXtlA7Gf59?= =?us-ascii?Q?i0/Z2MKqPf5Irlzfp3PLZ6skinVe60cmF6nTCL7N69Z1leqDKfFY4Csvso7n?= =?us-ascii?Q?8a+FAxBNRBhqmsbOcxD9CdCMi8k9KOafyUKqiUAfbU4XM562uZhvCnPMD8Y6?= =?us-ascii?Q?uAqmRGvVyHiPYN6SnIdzPO23Wpp7W75hVfH30wcKgXKcntqpDIZpaFKgXg/Q?= =?us-ascii?Q?hmXqNn0QnTiZqoXDLNzqxrV8PrIiX0PSg/JM+3NAEVXWCO/nv5cUvzdU4zGc?= =?us-ascii?Q?+IjH9dyTrpGlfS3BBHP/MDNog9NIfdLYEE7M+RyEoCRl1Ua1UR3YELKvZV+n?= =?us-ascii?Q?g0LeRlM7Vb/NGZRf8G2A1MlUSyiXGhLSokczX/lI0wd2eNGaWnsS1UCF990V?= =?us-ascii?Q?+3rhpoFsM9zYKHiVBA9htDeePBMSIYp0HVwL8qS6LW6vMZKyZfjkh827X++3?= =?us-ascii?Q?aKVZdmpnQI4596CYICMda+B5sHmeC5hamToujWfJMvZIdJajy21KgR/4CnTG?= =?us-ascii?Q?79lK72yopd2NOe4WJVlh8HyqQqvFj6mmCnZ6s1k+uiRRG5t1mxoP6FrZPnzN?= =?us-ascii?Q?+0=3D?= X-Microsoft-Exchange-Diagnostics: 1;BY1PR12MB0424;5:THnRa4w4jI0kYee7U9cByiAOz13/irCDwcS/vwb+eLoRhdpkj5fGJd/7VnCiOI1dW7D41ljPA0vtD1ccpVdWjwjdmVXTQcXBS1HlULpdtBD+m95RCn6g+pn6iUQf77RSnQenoNzDq6oChW3+tJu3Cg==;24:3VzO8Mgg0Hqrxq2dr1hdmFVO8GnGw1nIKhKz8KjnqayT0zMB/VFv7vntBmPSohWcvbkPNrv4jKuADrSshTvsLjvrqriAQpb5j3Oz5flFAvk=;20:vQ95DDi2vhrgeFmhi1rIfLq6dz4v6BjPRfWAhZWZGNCp+i9uI1/VdRVs8oxZBysD1awklA20rWxk/50i3rgBZGV+gb3QOn3QxKQ7YGwD36gAUUlqWFOWZcmcuA2t1IYzKlXtPQ1kKxkThYhjDhV2Yboibwlh38ESIOTNJqhGpw/EGPL8DWgj1VSHJg825qznHEyaNIgd8IzMNTkuRimE662p65rowhQFQE00Lvw/1Kcp5Yyng6Og6JDiLlsXFDQe X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Feb 2016 22:17:25.1861 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR12MB0424 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 | 53 ++++++ arch/x86/kernel/cpu/mcheck/mce_amd.c | 11 ++ drivers/edac/mce_amd.c | 342 ++++++++++++++++++++++++++++++++++- 3 files changed, 405 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index e8b09b3..e83bbd6 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -42,6 +42,18 @@ /* 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. + * - MCx_MISC0[BlkPtr] field indicates presence 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 @@ -93,7 +105,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)) /* * This structure contains all data related to the MCE log. Also @@ -292,4 +306,43 @@ struct cper_sec_mem_err; extern void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err); +/* + * Enumerate new IP types and HWID values + * in ScalableMCA enabled AMD processors + */ +#ifdef CONFIG_X86_MCE_AMD +enum amd_ip_types { + SMCA_F17H_CORE_BLOCK = 0, /* Core errors */ + SMCA_DF_BLOCK, /* Data Fabric */ + SMCA_UMC_BLOCK, /* Unified Memory Controller */ + SMCA_PB_BLOCK, /* Parameter Block */ + SMCA_PSP_BLOCK, /* Platform Security Processor */ + SMCA_SMU_BLOCK, /* System Management Unit */ + N_AMD_IP_TYPES +}; + +struct amd_hwid { + const char *amd_ipname; + unsigned int amd_hwid_value; +}; + +extern struct amd_hwid amd_hwid_mappings[N_AMD_IP_TYPES]; + +enum amd_core_mca_blocks { + SMCA_LS_BLOCK = 0, /* Load Store */ + SMCA_IF_BLOCK, /* Instruction Fetch */ + SMCA_L2_CACHE_BLOCK, /* L2 cache */ + SMCA_DE_BLOCK, /* Decoder unit */ + RES, /* Reserved */ + SMCA_EX_BLOCK, /* Execution unit */ + SMCA_FP_BLOCK, /* Floating Point */ + SMCA_L3_CACHE_BLOCK /* L3 cache */ +}; + +enum amd_df_mca_blocks { + SMCA_CS_BLOCK = 0, /* Coherent Slave */ + SMCA_PIE_BLOCK /* Power management, Interrupts, etc */ +}; +#endif + #endif /* _ASM_X86_MCE_H */ diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 88de27b..13f15cb 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", }; +/* Define HWID to IP type mappings for Scalable MCA */ +struct amd_hwid amd_hwid_mappings[] = { + [SMCA_F17H_CORE_BLOCK] = { "f17h_core", 0xB0 }, + [SMCA_DF_BLOCK] = { "df", 0x2E }, + [SMCA_UMC_BLOCK] = { "umc", 0x96 }, + [SMCA_PB_BLOCK] = { "pb", 0x5 }, + [SMCA_PSP_BLOCK] = { "psp", 0xFF }, + [SMCA_SMU_BLOCK] = { "smu", 0x1 }, +}; +EXPORT_SYMBOL_GPL(amd_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..409448e 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_pb_mce_desc[] = { + "Parameter Block 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,192 @@ static bool amd_filter_mce(struct mce *m) return false; } +static void decode_f17hcore_errors(u8 xec, unsigned int mca_type) +{ + const char * const *error_desc_array; + char *ip_name; + size_t len; + + switch (mca_type) { + case SMCA_LS_BLOCK: + error_desc_array = f17h_ls_mce_desc; + ip_name = "LS"; + len = ARRAY_SIZE(f17h_ls_mce_desc) - 1; + + if (xec == 0x4) { + pr_cont("Unrecognized error code from LS MCA bank\n"); + return; + } + + break; + + case SMCA_IF_BLOCK: + error_desc_array = f17h_if_mce_desc; + ip_name = "IF"; + len = ARRAY_SIZE(f17h_if_mce_desc) - 1; + break; + + case SMCA_L2_CACHE_BLOCK: + error_desc_array = f17h_l2_mce_desc; + ip_name = "L2_Cache"; + len = ARRAY_SIZE(f17h_l2_mce_desc) - 1; + break; + + case SMCA_DE_BLOCK: + error_desc_array = f17h_de_mce_desc; + ip_name = "DE"; + len = ARRAY_SIZE(f17h_de_mce_desc) - 1; + break; + + case SMCA_EX_BLOCK: + error_desc_array = f17h_ex_mce_desc; + ip_name = "EX"; + len = ARRAY_SIZE(f17h_ex_mce_desc) - 1; + break; + + case SMCA_FP_BLOCK: + error_desc_array = f17h_fp_mce_desc; + ip_name = "FP"; + len = ARRAY_SIZE(f17h_fp_mce_desc) - 1; + break; + + case SMCA_L3_CACHE_BLOCK: + error_desc_array = f17h_l3_mce_desc; + ip_name = "L3_Cache"; + len = ARRAY_SIZE(f17h_l3_mce_desc) - 1; + break; + + default: + pr_cont("Unrecognized Mca Type value for F17h Core. Unable to decode errors\n"); + return; + } + + if (xec > len) { + pr_cont("Unrecognized error code from %s MCA bank\n", ip_name); + return; + } + + pr_cont("%s.\n", error_desc_array[xec]); +} + +static void decode_df_errors(u8 xec, unsigned int mca_type) +{ + const char * const *error_desc_array; + char *ip_name; + size_t len; + + switch (mca_type) { + case SMCA_CS_BLOCK: + error_desc_array = f17h_cs_mce_desc; + ip_name = "CS"; + len = ARRAY_SIZE(f17h_cs_mce_desc) - 1; + break; + + case SMCA_PIE_BLOCK: + error_desc_array = f17h_pie_mce_desc; + ip_name = "PIE"; + len = ARRAY_SIZE(f17h_pie_mce_desc) - 1; + break; + + default: + pr_cont("Unrecognized Mca Type value for DF. Unable to decode errors\n"); + return; + } + + if (xec > len) { + pr_cont("Unrecognized error code from %s MCA bank\n", ip_name); + return; + } + + pr_cont("%s.\n", error_desc_array[xec]); +} + +/* 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); + const char * const *error_desc_array; + char *ip_name; + size_t len; + + if (rdmsr_safe(addr, &low, &high)) { + pr_emerg("Invalid IP block specified, error information is unreliable.\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(amd_hwid_mappings); i++) + if (amd_hwid_mappings[i].amd_hwid_value == hwid) + break; + + switch (i) { + case SMCA_F17H_CORE_BLOCK: + ip_name = (mca_type == SMCA_L3_CACHE_BLOCK) ? + "L3 Cache" : "F17h Core"; + break; + + case SMCA_DF_BLOCK: + ip_name = "DF"; + break; + + case SMCA_UMC_BLOCK: + error_desc_array = f17h_umc_mce_desc; + ip_name = "UMC"; + len = ARRAY_SIZE(f17h_umc_mce_desc) - 1; + break; + + case SMCA_PB_BLOCK: + error_desc_array = f17h_pb_mce_desc; + ip_name = "PB"; + len = ARRAY_SIZE(f17h_pb_mce_desc) - 1; + break; + + case SMCA_PSP_BLOCK: + error_desc_array = f17h_psp_mce_desc; + ip_name = "PSP"; + len = ARRAY_SIZE(f17h_psp_mce_desc) - 1; + break; + + case SMCA_SMU_BLOCK: + error_desc_array = f17h_smu_mce_desc; + ip_name = "SMU"; + len = ARRAY_SIZE(f17h_smu_mce_desc) - 1; + break; + + default: + pr_emerg(HW_ERR "HWID:%d does not match any existing IPs\n", hwid); + return; + } + + pr_emerg(HW_ERR "%s Error: ", ip_name); + + if (i == SMCA_F17H_CORE_BLOCK) { + decode_f17hcore_errors(xec, mca_type); + } else if (i == SMCA_DF_BLOCK) { + decode_df_errors(xec, mca_type); + } else { + if (xec > len) { + pr_cont("Unrecognized error code from %s MCA bank\n", ip_name); + return; + } + + pr_cont("%s.\n", error_desc_array[xec]); + } +} + static const char *decode_error_status(struct mce *m) { if (m->status & MCI_STATUS_UC) { @@ -752,6 +1068,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) struct mce *m = (struct mce *)data; struct cpuinfo_x86 *c = &cpu_data(m->extcpu); int ecc; + u32 ebx = cpuid_ebx(0x80000007); if (amd_filter_mce(m)) return NOTIFY_STOP; @@ -769,11 +1086,20 @@ 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 (!!(ebx & BIT(3))) { + u32 low, high; + u32 addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank); + + if (!rdmsr_safe(addr, &low, &high) && + (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 +1110,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 (!!(ebx & BIT(3))) { + decode_smca_errors(m); + goto err_code; + } + if (!fam_ops) goto err_code; @@ -834,6 +1165,7 @@ static struct notifier_block amd_mce_dec_nb = { static int __init mce_amd_init(void) { struct cpuinfo_x86 *c = &boot_cpu_data; + u32 ebx = cpuid_ebx(0x80000007); if (c->x86_vendor != X86_VENDOR_AMD) return -ENODEV; @@ -888,6 +1220,14 @@ static int __init mce_amd_init(void) fam_ops->mc2_mce = f16h_mc2_mce; break; + case 0x17: + xec_mask = 0x3f; + if (!(ebx & BIT(3))) { + 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