From patchwork Fri Apr 24 18:57:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Luck X-Patchwork-Id: 11508833 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7482315AB for ; Fri, 24 Apr 2020 18:57:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 67620215A4 for ; Fri, 24 Apr 2020 18:57:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729204AbgDXS5l (ORCPT ); Fri, 24 Apr 2020 14:57:41 -0400 Received: from mga03.intel.com ([134.134.136.65]:21121 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728659AbgDXS5k (ORCPT ); Fri, 24 Apr 2020 14:57:40 -0400 IronPort-SDR: vJQbHb1yfMa0bajxOZWDydS+Zjccw+b8M4Ao6P+pw36OsEAtmWj9xkTC9GgDeuCyo1sCmOp9c0 L0F6s8VFqCuw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 11:57:39 -0700 IronPort-SDR: qGAbW3+tf8q/XCpcmcJS7MI9gCD5cfe0rTht3/0WSOOlenq7St1CsdlEva/i2INAuyFhLoTj8u MpxETXisVMTw== X-IronPort-AV: E=Sophos;i="5.73,313,1583222400"; d="scan'208";a="430893781" Received: from agluck-desk2.sc.intel.com ([10.3.52.68]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 11:57:39 -0700 From: Tony Luck To: Borislav Petkov Cc: Qiuxu Zhuo , Tony Luck , Aristeu Rozanski , Mauro Carvalho Chehab , linux-edac@vger.kernel.org Subject: [PATCH 1/2] EDAC, {skx,i10nm}: Make some configurations CPU model specific Date: Fri, 24 Apr 2020 11:57:37 -0700 Message-Id: <20200424185738.7985-2-tony.luck@intel.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20200424185738.7985-1-tony.luck@intel.com> References: <20200424185738.7985-1-tony.luck@intel.com> MIME-Version: 1.0 Sender: linux-edac-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-edac@vger.kernel.org From: Qiuxu Zhuo The device ID for configuration agent PCI device and the offset for bus number configuration register can be CPU model specific. So add a new structure res_config to make them configurable and pass res_config to {skx,i10nm}_init() and skx_get_all_bus_mappings() for use. Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Reviewed-by: Borislav Petkov --- drivers/edac/i10nm_base.c | 16 ++++++++++++---- drivers/edac/skx_base.c | 12 ++++++++++-- drivers/edac/skx_common.c | 11 +++++------ drivers/edac/skx_common.h | 11 +++++++++-- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index df08de963d10..ba4578c6ef2b 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -122,10 +122,16 @@ static int i10nm_get_all_munits(void) return 0; } +static struct res_config i10nm_cfg = { + .type = I10NM, + .decs_did = 0x3452, + .busno_cfg_offset = 0xcc, +}; + static const struct x86_cpu_id i10nm_cpuids[] = { - X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &i10nm_cfg), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &i10nm_cfg), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &i10nm_cfg), {} }; MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); @@ -234,6 +240,7 @@ static int __init i10nm_init(void) { u8 mc = 0, src_id = 0, node_id = 0; const struct x86_cpu_id *id; + struct res_config *cfg; const char *owner; struct skx_dev *d; int rc, i, off[3] = {0xd0, 0xc8, 0xcc}; @@ -248,12 +255,13 @@ static int __init i10nm_init(void) id = x86_match_cpu(i10nm_cpuids); if (!id) return -ENODEV; + cfg = (struct res_config *)id->driver_data; rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm); if (rc) return rc; - rc = skx_get_all_bus_mappings(0x3452, 0xcc, I10NM, &i10nm_edac_list); + rc = skx_get_all_bus_mappings(cfg, &i10nm_edac_list); if (rc < 0) goto fail; if (rc == 0) { diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c index 46a3a3440f5e..ae2c2b516adc 100644 --- a/drivers/edac/skx_base.c +++ b/drivers/edac/skx_base.c @@ -157,8 +157,14 @@ static int get_all_munits(const struct munit *m) return -ENODEV; } +static struct res_config skx_cfg = { + .type = SKX, + .decs_did = 0x2016, + .busno_cfg_offset = 0xcc, +}; + static const struct x86_cpu_id skx_cpuids[] = { - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, NULL), + X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &skx_cfg), { } }; MODULE_DEVICE_TABLE(x86cpu, skx_cpuids); @@ -641,6 +647,7 @@ static inline void teardown_skx_debug(void) {} static int __init skx_init(void) { const struct x86_cpu_id *id; + struct res_config *cfg; const struct munit *m; const char *owner; int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8}; @@ -656,12 +663,13 @@ static int __init skx_init(void) id = x86_match_cpu(skx_cpuids); if (!id) return -ENODEV; + cfg = (struct res_config *)id->driver_data; rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm); if (rc) return rc; - rc = skx_get_all_bus_mappings(0x2016, 0xcc, SKX, &skx_edac_list); + rc = skx_get_all_bus_mappings(cfg, &skx_edac_list); if (rc < 0) goto fail; if (rc == 0) { diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index 99bbaf629b8d..abc9ddd2b7d1 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -197,12 +197,11 @@ static int get_width(u32 mtr) } /* - * We use the per-socket device @did to count how many sockets are present, + * We use the per-socket device @cfg->did to count how many sockets are present, * and to detemine which PCI buses are associated with each socket. Allocate * and build the full list of all the skx_dev structures that we need here. */ -int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, - struct list_head **list) +int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list) { struct pci_dev *pdev, *prev; struct skx_dev *d; @@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, prev = NULL; for (;;) { - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, prev); + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, cfg->decs_did, prev); if (!pdev) break; ndev++; @@ -221,7 +220,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, return -ENOMEM; } - if (pci_read_config_dword(pdev, off, ®)) { + if (pci_read_config_dword(pdev, cfg->busno_cfg_offset, ®)) { kfree(d); pci_dev_put(pdev); skx_printk(KERN_ERR, "Failed to read bus idx\n"); @@ -230,7 +229,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, d->bus[0] = GET_BITFIELD(reg, 0, 7); d->bus[1] = GET_BITFIELD(reg, 8, 15); - if (type == SKX) { + if (cfg->type == SKX) { d->seg = pci_domain_nr(pdev->bus); d->bus[2] = GET_BITFIELD(reg, 16, 23); d->bus[3] = GET_BITFIELD(reg, 24, 31); diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 60d1ea669afd..19dd8c099520 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -112,6 +112,14 @@ struct decoded_addr { int bank_group; }; +struct res_config { + enum type type; + /* Configuration agent device ID */ + unsigned int decs_did; + /* Default bus number configuration register offset */ + int busno_cfg_offset; +}; + typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); typedef bool (*skx_decode_f)(struct decoded_addr *res); typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); @@ -123,8 +131,7 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); int skx_get_src_id(struct skx_dev *d, int off, u8 *id); int skx_get_node_id(struct skx_dev *d, u8 *id); -int skx_get_all_bus_mappings(unsigned int did, int off, enum type, - struct list_head **list); +int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list); int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); From patchwork Fri Apr 24 18:57:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Luck X-Patchwork-Id: 11508835 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE06114B4 for ; Fri, 24 Apr 2020 18:57:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A0C1B2075A for ; Fri, 24 Apr 2020 18:57:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729199AbgDXS5l (ORCPT ); Fri, 24 Apr 2020 14:57:41 -0400 Received: from mga03.intel.com ([134.134.136.65]:21121 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728953AbgDXS5l (ORCPT ); Fri, 24 Apr 2020 14:57:41 -0400 IronPort-SDR: PHrvr/XHV6zB7YsUtS861I2d7K/MMY/c6t33wWRemRgJxQJcsgXzMAQ555NH+YyK0fjhGe6TSq cy8Cm/h8g6mg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 11:57:40 -0700 IronPort-SDR: LnB8aXbPjv5c2Pwyyjv7onfs2A4ml/9YZnFObOEQZk9zTTiQBWUNDHApvnEKTaT2Md8kR1Zdk9 AEJZ6JBRCsew== X-IronPort-AV: E=Sophos;i="5.73,313,1583222400"; d="scan'208";a="430893784" Received: from agluck-desk2.sc.intel.com ([10.3.52.68]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 11:57:39 -0700 From: Tony Luck To: Borislav Petkov Cc: Qiuxu Zhuo , Jerry Chen , Jin Wen , Tony Luck , Aristeu Rozanski , Mauro Carvalho Chehab , linux-edac@vger.kernel.org Subject: [PATCH 2/2] EDAC, i10nm: Fix i10nm_edac loading failure on some servers Date: Fri, 24 Apr 2020 11:57:38 -0700 Message-Id: <20200424185738.7985-3-tony.luck@intel.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20200424185738.7985-1-tony.luck@intel.com> References: <20200424185738.7985-1-tony.luck@intel.com> MIME-Version: 1.0 Sender: linux-edac-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-edac@vger.kernel.org From: Qiuxu Zhuo It failed to load the i10nm_edac driver on Ice Lake and Tremont/Jacobsville servers if their CPU stepping >= 4 and failed on Ice Lake-D servers from stepping 0. The root cause was that for Ice Lake and Tremont/Jacobsville servers with CPU stepping >=4, the offset for bus number configuration register was updated from 0xcc to 0xd0. For Ice Lake-D servers, all the steppings use the updated 0xd0 offset. Fix the issue by using the appropriate offset for bus number configuration register according to the CPU model number and stepping. Reported-by: Jerry Chen Reported-and-tested-by: Jin Wen Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Reviewed-by: Borislav Petkov --- drivers/edac/i10nm_base.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index ba4578c6ef2b..ebb45738c11b 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -122,16 +122,24 @@ static int i10nm_get_all_munits(void) return 0; } -static struct res_config i10nm_cfg = { +/* ATOM_TREMONT_D, ICELAKE_X */ +static struct res_config i10nm_cfg0 = { .type = I10NM, .decs_did = 0x3452, .busno_cfg_offset = 0xcc, }; +/* ICELAKE_D */ +static struct res_config i10nm_cfg1 = { + .type = I10NM, + .decs_did = 0x3452, + .busno_cfg_offset = 0xd0, +}; + static const struct x86_cpu_id i10nm_cpuids[] = { - X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &i10nm_cfg), - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &i10nm_cfg), - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &i10nm_cfg), + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &i10nm_cfg0), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &i10nm_cfg0), + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &i10nm_cfg1), {} }; MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); @@ -257,6 +265,10 @@ static int __init i10nm_init(void) return -ENODEV; cfg = (struct res_config *)id->driver_data; + /* Newer steppings have different offset for ATOM_TREMONT_D/ICELAKE_X */ + if (boot_cpu_data.x86_stepping >= 4) + cfg->busno_cfg_offset = 0xd0; + rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm); if (rc) return rc;