From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DEB993587D1; Wed, 19 Nov 2025 13:52:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560344; cv=none; b=GOxMC6ii0yElswpqrqPRppVw1Bnq7M56qQtPYK8hdHPaojI39V7GnNrGMx+pf1FlTGv6yTbG624Qo1ZJOZl47X/3aZPIiIvMtMQG5zrVraSAoJ6FEXJApdqRi37CnLwaKv6NAWH0C57K3fxbwbd8o4AdFhVBl6KVk2z9k+t3Ur4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560344; c=relaxed/simple; bh=CLCDritYqwWsg3vQUUO094s+CUEvzMPPOabvLZY+O40=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MyAd4N/fOlejkdTHAqxsiXPxfVWATy3znfmP9v/SSgTKmaiYooZKDCJdTPr3S4BkRRaQ2bWoO7I/vSeiP42+s8QLxCRzJH5m9tzjVENO2QsOowfmTkRg6gBZdbp3X54XCTt/dc4QzLUgtUvb6HjPnAd9mYsslAtvczx0WDUimZ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=akDNtFw7; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="akDNtFw7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560343; x=1795096343; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CLCDritYqwWsg3vQUUO094s+CUEvzMPPOabvLZY+O40=; b=akDNtFw73PI4J1MEcC04c9APnNTO8SHc4QQWZ4HDh+VTrAhbXaTVMBE8 o2UTO+SXXBsOFUni4K2qdu4FqM0ZbhypWr7rl3r9PNQbSzlyHgI8Lafdk t9176iA337MpB02zDUAhKFX4KunRfLedTn/7m/Pk5UutGAlS/wiA7AfRw ZqGB72qPzC/ipSaLWL5IP3m3TvUE1AcEczIsAaFyYAMShXmCh7DXXgN8D 5zjub6gpcXYCAnqk3OIW5Wp9SRi631H/EbWmJnQe+QTrwy3I6PgyWey2f W8V05bLmT/UMMR0EyroRYn8dZVCiRiQQ3mDJ0QieZMyNg7P2wLeOD4/Hf Q==; X-CSE-ConnectionGUID: gm93DUqAS5asmGQT3jlNaQ== X-CSE-MsgGUID: ZfzD0QuNT8S041zswvRU9w== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607310" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607310" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:22 -0800 X-CSE-ConnectionGUID: Jo6yM6OaTUGlnMivuHfhcA== X-CSE-MsgGUID: Mcq9B/krSwqw56BwhuJ8Xw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439471" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:18 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , Lai Yi , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/7] EDAC/{skx_common,skx,i10nm}: Make skx_register_mci() independent of pci_dev Date: Wed, 19 Nov 2025 21:41:25 +0800 Message-ID: <20251119134132.2389472-2-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Memory controllers in the new Intel server CPUs, such as Diamond Rapids, are presented as MMIO-based devices rather than PCI devices. Modify skx_register_mci() to be independent of 'pci_dev' and use a generic 'dev' of 'struct device' to prepare for support of such MMIO-based memory controllers. Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/i10nm_base.c | 3 ++- drivers/edac/skx_base.c | 4 ++-- drivers/edac/skx_common.c | 10 +++++----- drivers/edac/skx_common.h | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 2010a47149f4..89b3e8cc38b1 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -1198,7 +1198,8 @@ static int __init i10nm_init(void) d->imc[i].num_dimms =3D cfg->ddr_dimm_num; } =20 - rc =3D skx_register_mci(&d->imc[i], d->imc[i].mdev, + rc =3D skx_register_mci(&d->imc[i], &d->imc[i].mdev->dev, + pci_name(d->imc[i].mdev), "Intel_10nm Socket", EDAC_MOD_STR, i10nm_get_dimm_config, cfg); if (rc < 0) diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c index 078ddf95cc6e..aa6593ccda2d 100644 --- a/drivers/edac/skx_base.c +++ b/drivers/edac/skx_base.c @@ -662,8 +662,8 @@ static int __init skx_init(void) d->imc[i].src_id =3D src_id; d->imc[i].num_channels =3D cfg->ddr_chan_num; d->imc[i].num_dimms =3D cfg->ddr_dimm_num; - - rc =3D skx_register_mci(&d->imc[i], d->imc[i].chan[0].cdev, + rc =3D skx_register_mci(&d->imc[i], &d->imc[i].chan[0].cdev->dev, + pci_name(d->imc[i].chan[0].cdev), "Skylake Socket", EDAC_MOD_STR, skx_get_dimm_config, cfg); if (rc < 0) diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index 724842f512ac..cf58cb5951ab 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -545,9 +545,9 @@ int skx_get_nvdimm_info(struct dimm_info *dimm, struct = skx_imc *imc, } EXPORT_SYMBOL_GPL(skx_get_nvdimm_info); =20 -int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, - const char *ctl_name, const char *mod_str, - get_dimm_config_f get_dimm_config, +int skx_register_mci(struct skx_imc *imc, struct device *dev, + const char *dev_name, const char *ctl_name, + const char *mod_str, get_dimm_config_f get_dimm_config, struct res_config *cfg) { struct mem_ctl_info *mci; @@ -588,7 +588,7 @@ int skx_register_mci(struct skx_imc *imc, struct pci_de= v *pdev, mci->edac_ctl_cap =3D EDAC_FLAG_NONE; mci->edac_cap =3D EDAC_FLAG_NONE; mci->mod_name =3D mod_str; - mci->dev_name =3D pci_name(pdev); + mci->dev_name =3D dev_name; mci->ctl_page_to_phys =3D NULL; =20 rc =3D get_dimm_config(mci, cfg); @@ -596,7 +596,7 @@ int skx_register_mci(struct skx_imc *imc, struct pci_de= v *pdev, goto fail; =20 /* Record ptr to the generic device */ - mci->pdev =3D &pdev->dev; + mci->pdev =3D dev; =20 /* Add this new MC control structure to EDAC's list of MCs */ if (unlikely(edac_mc_add_mc(mci))) { diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 73ba89786cdf..0be088f47587 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -302,7 +302,7 @@ int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, str= uct dimm_info *dimm, int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, int chan, int dimmno, const char *mod_str); =20 -int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, +int skx_register_mci(struct skx_imc *imc, struct device *dev, const char *= dev_name, const char *ctl_name, const char *mod_str, get_dimm_config_f get_dimm_config, struct res_config *cfg); --=20 2.43.0 From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAF9B3557FE; Wed, 19 Nov 2025 13:52:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560353; cv=none; b=JF6R5PreQBssm2D9v6S+F1Q4rzXu42avgxXewur3kNZfIhc1/xTlFH8SSpq9xn7yLJDefiKkRFwEDgUQCiKQqwnLWNsEDSvtEPknQqclCLXJ2tbyzgxY/0L3i59cWJEEOSyYB6mNoR8qSfiDVpu/ls/8Ia3g+jsLQ1P8+TCfD7Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560353; c=relaxed/simple; bh=R4Onzs3LFqMx8Ji7eJ85mAWSzM+DEaETYbbH1SleTeU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sZfrOLuTe2nRaPsOxvjfAtlVuxjgJnmdZi0GEaOeG+ObUPx3zC0BNg2q7dU6vDWd+ioB9xgI7kjvW9MhLV37A283iFvEXbAI+1HlA6+YQ9CALCpIuu/jhhT4fZtp/dN6KVFnPxu37qq2SNxEbfMZS+G1mTS1/EV+uNpcUhIgwEQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=TqqUUoog; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="TqqUUoog" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560352; x=1795096352; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=R4Onzs3LFqMx8Ji7eJ85mAWSzM+DEaETYbbH1SleTeU=; b=TqqUUoogwlxUgVWZQEVB0UzRUU0PgNOBlCV9AH9OOvUXf5eTljZTevsc tqFJ5pyBgKntxJml31Z4Ob94DX/TFcOAzHwLdqQaJcIFRxfbVH63U+zAM xjntDuLiE/pWd5LPyWeLyejyCTuNg9TfYA5J5vZDPeTfX4CcPRl4/6Cc6 5kkGhp915ru1JF4WjCbSlqfTRQtIo/p7rR01pNE+q8M9074jM+r8W9qwv 7YeYow7qmzIyUeA28Tzi0QbO/pEk+R2WmwXDrZ60GvO22M/+TZep6PTwo hBBnqx8M27daq43xI1OQ1TbeC4jv4Zr67g56Fafjv9QX8CEOuFqfJmVAq A==; X-CSE-ConnectionGUID: u5pM/HbnSL+1jJeaNm5Kig== X-CSE-MsgGUID: TO8N0nMhQGeGZyXO9j3anw== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607322" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607322" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:31 -0800 X-CSE-ConnectionGUID: zPKS08OATZm6uKsq9UoZMA== X-CSE-MsgGUID: ONeNFPCNQnu7c0naCvHMaA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439506" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:29 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/7] EDAC/skx_common: Prepare for skx_get_edac_list() Date: Wed, 19 Nov 2025 21:41:26 +0800 Message-ID: <20251119134132.2389472-3-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Intel EDAC library 'skx_common' maintains the Intel server EDAC device list for {skx, i10nm}_edac drivers, which use skx_get_all_bus_mappings() to build and retrieve the EDAC device list. However, the upcoming Intel EDAC driver, imh_edac, for Diamond Rapids servers is designed for memory controllers that are MMIO-based devices rather than PCI devices. Consequently, it can't use skx_get_all_bus_mappings() due to the absence of a PCI bus. To accommodate this, prepare skx_get_edac_list() to enable the upcoming imh_edac driver to obtain the EDAC device list from the skx_common library and build the EDAC device list independently. Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/skx_common.c | 6 ++++++ drivers/edac/skx_common.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index cf58cb5951ab..6a1b30aa1ee6 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -384,6 +384,12 @@ int skx_get_all_bus_mappings(struct res_config *cfg, s= truct list_head **list) } EXPORT_SYMBOL_GPL(skx_get_all_bus_mappings); =20 +struct list_head *skx_get_edac_list(void) +{ + return &dev_edac_list; +} +EXPORT_SYMBOL_GPL(skx_get_edac_list); + int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) { struct pci_dev *pdev; diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 0be088f47587..52734091a79d 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -293,6 +293,8 @@ int skx_get_src_id(struct skx_dev *d, int off, u8 *id); =20 int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **li= st); =20 +struct list_head *skx_get_edac_list(void); + int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); =20 int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, --=20 2.43.0 From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E31C35F8C5; Wed, 19 Nov 2025 13:52:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560364; cv=none; b=WPcLc1p7HWVoUcQ2cNCZwT57QnfjldVh1YEpCFeGYVQ4Oed4CJxw+k5U3T4uDd6dwlYrl71jOGTjAjUp/DsI4WDqIct4zy8ghkt3h4vBIgDT5CIeuhF1YBDFwbBwMgnTyqLyuJT4Jtxioce7hOQPuk7eK5FcX1jlrY75Lh7s7yE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560364; c=relaxed/simple; bh=u4wUA6apnhjKgKWvp/nnJucr11Vb3MfjMnaOIa4dsTQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MOZJ6zb8pcxUXRnm9GuVbOuHPyBtWJA2O4eF1nToAJ5IYdIeDwcIPECIB/HQetB1g1JJp+p50KmKK30bEW4oR5XwYYIGum37eEnmFc/u72DCXvxbrc6fNGNVhiT1qXLNn8+cJO89t1xrls2m7TXJqEfLXt9z4mKfxVMv+dbDDic= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=fHJQRBJT; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="fHJQRBJT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560363; x=1795096363; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=u4wUA6apnhjKgKWvp/nnJucr11Vb3MfjMnaOIa4dsTQ=; b=fHJQRBJTWv+urzPgIyuOYAilU/9YW4FU12ioiE4i6ZbAU5PEYlAxLu8T xXQgYv0McfkLxf9QCvJgFqnj5F4tz68xk5j4f/CkNy6GJ6MLPQasbcN/X OOFkCvDtGew/qDsfRfK2LQ9q2o7kVIOVZ3Lc8mLSd1ZoFl5Xs50cfSY/r RZoiPd62xAthe2fqAp2VvjZzjAUnr7Urq/t5ms2ov1PqidDZK9qaGZkVC elegJtb9ym8HohZNkXsvB/nQgxeJUg8egUrpf7FEDd1Bmnn6PEo800+I0 sZ5UeBAN2K/VBdXpJxcdYyiKJIfIbiNSanv1WgxPccKKgdQhRRJ5SxgXR g==; X-CSE-ConnectionGUID: 7XzLoaODQL64eLdBLetNXA== X-CSE-MsgGUID: aL0x7oy6SuyA2zL7czcyXw== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607369" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607369" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:42 -0800 X-CSE-ConnectionGUID: QOEUOEbhSjm2tFdgpo22tg== X-CSE-MsgGUID: wqqaOwxcR2ymvYg2xuqKyg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439570" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:40 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/7] EDAC/skx_common: Prepare for skx_set_hi_lo() Date: Wed, 19 Nov 2025 21:41:27 +0800 Message-ID: <20251119134132.2389472-4-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The upcoming imh_edac driver for Intel Diamond Rapids servers cannot use skx_get_hi_lo() in skx_common to retrieve the TOHM (Top of High Memory) and TOLM (Top of Low Memory) parameters. Instead, it obtains these parameters within its own EDAC driver. To accommodate this, prepare skx_set_hi_lo() to allow the driver to notify skx_common of these parameters. Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/skx_common.c | 7 +++++++ drivers/edac/skx_common.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index 6a1b30aa1ee6..e45abd0008ef 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -430,6 +430,13 @@ int skx_get_hi_lo(unsigned int did, int off[], u64 *to= lm, u64 *tohm) } EXPORT_SYMBOL_GPL(skx_get_hi_lo); =20 +void skx_set_hi_lo(u64 tolm, u64 tohm) +{ + skx_tolm =3D tolm; + skx_tohm =3D tohm; +} +EXPORT_SYMBOL_GPL(skx_set_hi_lo); + static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, int minval, int maxval, const char *name) { diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 52734091a79d..86a883d3c2a4 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -296,6 +296,7 @@ int skx_get_all_bus_mappings(struct res_config *cfg, st= ruct list_head **list); struct list_head *skx_get_edac_list(void); =20 int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); +void skx_set_hi_lo(u64 tolm, u64 tohm); =20 int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, struct skx_imc *imc, int chan, int dimmno, --=20 2.43.0 From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0BAE835F8C5; Wed, 19 Nov 2025 13:52:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560370; cv=none; b=WDomiAefMnqRhdKZUiwA8G3YKYrcUh48eX7bAy9G3m+kmj4KNy72v01nr32y0gEVDX6Usc3eQ7zsU+HIdEE0rCXnKdxnLowN26cBqH2FWOL84k63us/8/9KtOAaVBuzX5gQHNDHjUwTLF4e3Ntmoi5946U5JJ8i7qT/TmcC6Kbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560370; c=relaxed/simple; bh=VBcGO2lBpS7mQszR6C3qaM4J0ffu0bVGyhSa2FplPwU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UTFb0ztN097LWNq9gfZ8dOq1QCsWm7TbUITfzi310xc+bYn7dmVvsc0aIgoo+iZKNlSrkwvuSSIaA1oywnSGAQ+nw6ZRkx3pb2tzLEGSDNJOu0EPPDsr6+pdK7Vdn5o5VIJo38Zn524Rt/YZL9AEgTS/5GUYPt9OAGFuVKNCIXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=m8Nd1A75; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="m8Nd1A75" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560368; x=1795096368; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VBcGO2lBpS7mQszR6C3qaM4J0ffu0bVGyhSa2FplPwU=; b=m8Nd1A75VZBpRdRtRxn17DVluNY//ORn/2fTrTO9URMNueXjCyUM34oU 7dGWIzc9SR52PsWI9J1aTLE/1oKR9UMBMO54XEaAypnR6KZumDH/0NgOW WtFSYEqUuhP1dnp6Hw25aYFydNicqxENthn7m7O3/0qjZLCVLv39q9Vqp a7dIH2Z3ythafJCGlhOW80SsSiy3Z+INLUKA6Q022SLHv6SKmHGdYGFGT xPhBIxIRemveWAcb0NaL0E5z4TlL7Q1gayZT5d1dgigS6b8vwReZqe6Sk pJoojgI1gH8u/i4lqjP6rN/3dqphWSvlryD1ptV+SoKngbgDTVYgJ4Hpg w==; X-CSE-ConnectionGUID: etetPlpgTAib/ThB17lwNw== X-CSE-MsgGUID: EWe5lXc1QZSP4lqcDPqFcQ== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607393" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607393" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:48 -0800 X-CSE-ConnectionGUID: AOne8lksROi5rJKBRQ1d3Q== X-CSE-MsgGUID: IhIarCsQToK5gmMefl1+lg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439614" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:45 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/7] EDAC/{skx_common,imh}: Add EDAC driver for Intel Diamond Rapids servers Date: Wed, 19 Nov 2025 21:41:28 +0800 Message-ID: <20251119134132.2389472-5-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Intel Diamond Rapids CPUs include Integrated Memory and I/O Hubs (IMH). The memory controllers within the IMHs provide memory stacks to the processor. Create a new driver for this IMH-based memory controllers rather than applying additional patches to the existing i10nm_edac.c for the following reasons: 1) The memory controllers are not presented as PCI devices; instead, the detection and all their registers have been transitioned to MMIO-based memory spaces. 2) Validation processes are costly. Modifications to i10nm_edac would require extensive validation checks against multiple platforms, including Ice Lake, Sapphire Rapids, Emerald Rapids, Granite Rapids, Sierra Forest, and Grand Ridge. 3) Future Intel CPUs will likely only need patches on top of this new EDAC driver. Validation can be limited to Diamond Rapids servers and future Intel CPU generations. Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/Kconfig | 10 + drivers/edac/Makefile | 3 + drivers/edac/imh_base.c | 562 ++++++++++++++++++++++++++++++++++++++ drivers/edac/skx_common.c | 8 +- drivers/edac/skx_common.h | 89 ++++-- 5 files changed, 646 insertions(+), 26 deletions(-) create mode 100644 drivers/edac/imh_base.c diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 39352b9b7a7e..dbdfc86656d1 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -291,6 +291,16 @@ config EDAC_I10NM system has non-volatile DIMMs you should also manually select CONFIG_ACPI_NFIT. =20 +config EDAC_IMH + tristate "Intel Integrated Memory/IO Hub MC" + depends on X86_64 && X86_MCE_INTEL && ACPI + select ACPI_ADXL + help + Support for error detection and correction the Intel + Integrated Memory/IO Hub Memory Controller. This MC IP is + first used on the Diamond Rapids servers but may appear on + others in the future. + config EDAC_PND2 tristate "Intel Pondicherry2" depends on PCI && X86_64 && X86_MCE_INTEL diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 1c14796410a3..8429b1e856bc 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -65,6 +65,9 @@ obj-$(CONFIG_EDAC_SKX) +=3D skx_edac.o skx_edac_common.o i10nm_edac-y :=3D i10nm_base.o obj-$(CONFIG_EDAC_I10NM) +=3D i10nm_edac.o skx_edac_common.o =20 +imh_edac-y :=3D imh_base.o +obj-$(CONFIG_EDAC_IMH) +=3D imh_edac.o skx_edac_common.o + obj-$(CONFIG_EDAC_HIGHBANK_MC) +=3D highbank_mc_edac.o obj-$(CONFIG_EDAC_HIGHBANK_L2) +=3D highbank_l2_edac.o =20 diff --git a/drivers/edac/imh_base.c b/drivers/edac/imh_base.c new file mode 100644 index 000000000000..9c1a17c53ec1 --- /dev/null +++ b/drivers/edac/imh_base.c @@ -0,0 +1,562 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Intel(R) servers with Integrated Memory/IO Hub-based memory = controller. + * Copyright (c) 2025, Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include "edac_module.h" +#include "skx_common.h" + +#define IMH_REVISION "v0.0.1" +#define EDAC_MOD_STR "imh_edac" + +/* Debug macros */ +#define imh_printk(level, fmt, arg...) \ + edac_printk(level, "imh", fmt, ##arg) + +/* Configuration Agent(Ubox) */ +#define MMIO_BASE_H(reg) (((u64)GET_BITFIELD(reg, 0, 29)) << 23) +#define SOCKET_ID(reg) GET_BITFIELD(reg, 0, 3) + +/* PUNIT */ +#define DDR_IMC_BITMAP(reg) GET_BITFIELD(reg, 23, 30) + +/* Memory Controller */ +#define ECC_ENABLED(reg) GET_BITFIELD(reg, 2, 2) +#define DIMM_POPULATED(reg) GET_BITFIELD(reg, 15, 15) + +/* System Cache Agent(SCA) */ +#define TOLM(reg) (((u64)GET_BITFIELD(reg, 16, 31)) << 16) +#define TOHM(reg) (((u64)GET_BITFIELD(reg, 16, 51)) << 16) + +/** + * struct local_reg - A register as described in the local package view. + * + * @pkg (input) : The package where the register is located. + * @pbase (input) : The IP MMIO base physical address in the local pack= age view. + * @size (input) : The IP MMIO size. + * @offset (input) : The register offset from the IP MMIO base @pbase. + * @width (input) : The register width in byte. + * @vbase (internal) : The IP MMIO base virtual address. + * @val (output) : The register value. + */ +struct local_reg { + int pkg; + u64 pbase; + u32 size; + u32 offset; + u8 width; + void __iomem *vbase; + u64 val; +}; + +#define DEFINE_LOCAL_REG(name, cfg, package, north, ip_name, ip_idx, reg_n= ame) \ + struct local_reg name =3D { \ + .pkg =3D package, \ + .pbase =3D (north ? (cfg)->mmio_base_l_north : \ + (cfg)->mmio_base_l_south) + \ + (cfg)->ip_name##_base + \ + (cfg)->ip_name##_size * (ip_idx), \ + .size =3D (cfg)->ip_name##_size, \ + .offset =3D (cfg)->ip_name##_reg_##reg_name##_offset, \ + .width =3D (cfg)->ip_name##_reg_##reg_name##_width, \ + } + +static u64 readx(void __iomem *addr, u8 width) +{ + switch (width) { + case 1: + return readb(addr); + case 2: + return readw(addr); + case 4: + return readl(addr); + case 8: + return readq(addr); + default: + imh_printk(KERN_ERR, "Invalid reg 0x%p width %d\n", addr, width); + return 0; + } +} + +static void __read_local_reg(void *reg) +{ + struct local_reg *r =3D (struct local_reg *)reg; + + r->val =3D readx(r->vbase + r->offset, r->width); +} + +/* Read a local-view register. */ +static bool read_local_reg(struct local_reg *reg) +{ + int cpu; + + /* Get the target CPU in the package @reg->pkg. */ + for_each_online_cpu(cpu) { + if (reg->pkg =3D=3D topology_physical_package_id(cpu)) + break; + } + + if (cpu >=3D nr_cpu_ids) + return false; + + reg->vbase =3D ioremap(reg->pbase, reg->size); + if (!reg->vbase) { + imh_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", reg->pbase); + return false; + } + + /* Get the target CPU to read the register. */ + smp_call_function_single(cpu, __read_local_reg, reg, 1); + iounmap(reg->vbase); + + return true; +} + +/* Get the bitmap of memory controller instances in package @pkg. */ +static u32 get_imc_bitmap(struct res_config *cfg, int pkg, bool north) +{ + DEFINE_LOCAL_REG(reg, cfg, pkg, north, pcu, 0, capid3); + + if (!read_local_reg(®)) + return 0; + + edac_dbg(2, "Pkg%d %s mc instances bitmap 0x%llx (reg 0x%llx)\n", + pkg, north ? "north" : "south", + DDR_IMC_BITMAP(reg.val), reg.val); + + return DDR_IMC_BITMAP(reg.val); +} + +static void imc_release(struct device *dev) +{ + edac_dbg(2, "imc device %s released\n", dev_name(dev)); + kfree(dev); +} + +static int __get_ddr_munits(struct res_config *cfg, struct skx_dev *d, + bool north, int lmc) +{ + unsigned long size =3D cfg->ddr_chan_mmio_sz * cfg->ddr_chan_num; + unsigned long bitmap =3D get_imc_bitmap(cfg, d->pkg, north); + void __iomem *mbase; + struct device *dev; + int i, rc, pmc; + u64 base; + + for_each_set_bit(i, &bitmap, sizeof(bitmap) * 8) { + base =3D north ? d->mmio_base_h_north : d->mmio_base_h_south; + base +=3D cfg->ddr_imc_base + size * i; + + edac_dbg(2, "Pkg%d mc%d mmio base 0x%llx size 0x%lx\n", + d->pkg, lmc, base, size); + + /* Set up the imc MMIO. */ + mbase =3D ioremap(base, size); + if (!mbase) { + imh_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", base); + return -ENOMEM; + } + + d->imc[lmc].mbase =3D mbase; + d->imc[lmc].lmc =3D lmc; + + /* Create the imc device instance. */ + dev =3D kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->release =3D imc_release; + device_initialize(dev); + rc =3D dev_set_name(dev, "0x%llx", base); + if (rc) { + imh_printk(KERN_ERR, "Failed to set dev name\n"); + put_device(dev); + return rc; + } + + d->imc[lmc].dev =3D dev; + + /* Set up the imc index mapping. */ + pmc =3D north ? i : 8 + i; + skx_set_mc_mapping(d, pmc, lmc); + + lmc++; + } + + return lmc; +} + +static bool get_ddr_munits(struct res_config *cfg, struct skx_dev *d) +{ + int lmc =3D __get_ddr_munits(cfg, d, true, 0); + + if (lmc < 0) + return false; + + lmc =3D __get_ddr_munits(cfg, d, false, lmc); + if (lmc <=3D 0) + return false; + + return true; +} + +static bool get_socket_id(struct res_config *cfg, struct skx_dev *d) +{ + DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ubox, 0, socket_id); + u8 src_id; + int i; + + if (!read_local_reg(®)) + return false; + + src_id =3D SOCKET_ID(reg.val); + edac_dbg(2, "socket id 0x%x (reg 0x%llx)\n", src_id, reg.val); + + for (i =3D 0; i < cfg->ddr_imc_num; i++) + d->imc[i].src_id =3D src_id; + + return true; +} + +/* Get TOLM (Top Of Low Memory) and TOHM (Top Of High Memory) parameters. = */ +static bool imh_get_tolm_tohm(struct res_config *cfg, u64 *tolm, u64 *tohm) +{ + DEFINE_LOCAL_REG(reg, cfg, 0, true, sca, 0, tolm); + + if (!read_local_reg(®)) + return false; + + *tolm =3D TOLM(reg.val); + edac_dbg(2, "tolm 0x%llx (reg 0x%llx)\n", *tolm, reg.val); + + DEFINE_LOCAL_REG(reg2, cfg, 0, true, sca, 0, tohm); + + if (!read_local_reg(®2)) + return false; + + *tohm =3D TOHM(reg2.val); + edac_dbg(2, "tohm 0x%llx (reg 0x%llx)\n", *tohm, reg2.val); + + return true; +} + +/* Get the system-view MMIO_BASE_H for {north,south}-IMH. */ +static int imh_get_all_mmio_base_h(struct res_config *cfg, struct list_hea= d *edac_list) +{ + int i, n =3D topology_max_packages(), imc_num =3D cfg->ddr_imc_num + cfg-= >hbm_imc_num; + struct skx_dev *d; + + for (i =3D 0; i < n; i++) { + d =3D kzalloc(struct_size(d, imc, imc_num), GFP_KERNEL); + if (!d) + return -ENOMEM; + + DEFINE_LOCAL_REG(reg, cfg, i, true, ubox, 0, mmio_base); + + /* Get MMIO_BASE_H for the north-IMH. */ + if (!read_local_reg(®) || !reg.val) { + kfree(d); + imh_printk(KERN_ERR, "Pkg%d has no north mmio_base_h\n", i); + return -ENODEV; + } + + d->mmio_base_h_north =3D MMIO_BASE_H(reg.val); + edac_dbg(2, "Pkg%d north mmio_base_h 0x%llx (reg 0x%llx)\n", + i, d->mmio_base_h_north, reg.val); + + /* Get MMIO_BASE_H for the south-IMH (optional). */ + DEFINE_LOCAL_REG(reg2, cfg, i, false, ubox, 0, mmio_base); + + if (read_local_reg(®2)) { + d->mmio_base_h_south =3D MMIO_BASE_H(reg2.val); + edac_dbg(2, "Pkg%d south mmio_base_h 0x%llx (reg 0x%llx)\n", + i, d->mmio_base_h_south, reg2.val); + } + + d->pkg =3D i; + d->num_imc =3D imc_num; + skx_init_mc_mapping(d); + list_add_tail(&d->list, edac_list); + } + + return 0; +} + +/* Get the number of per-package memory controllers. */ +static int imh_get_imc_num(struct res_config *cfg) +{ + int imc_num =3D hweight32(get_imc_bitmap(cfg, 0, true)) + + hweight32(get_imc_bitmap(cfg, 0, false)); + + if (!imc_num) { + imh_printk(KERN_ERR, "Invalid mc number\n"); + return -ENODEV; + } + + if (cfg->ddr_imc_num !=3D imc_num) { + /* + * Update the configuration data to reflect the number of + * present DDR memory controllers. + */ + cfg->ddr_imc_num =3D imc_num; + edac_dbg(2, "Set ddr mc number %d\n", imc_num); + } + + return 0; +} + +/* Get all memory controllers' parameters. */ +static int imh_get_munits(struct res_config *cfg, struct list_head *edac_l= ist) +{ + struct skx_imc *imc; + struct skx_dev *d; + u8 mc =3D 0; + int i; + + list_for_each_entry(d, edac_list, list) { + if (!get_ddr_munits(cfg, d)) { + imh_printk(KERN_ERR, "No mc found\n"); + return -ENODEV; + } + + if (!get_socket_id(cfg, d)) { + imh_printk(KERN_ERR, "Failed to get socket id\n"); + return -ENODEV; + } + + for (i =3D 0; i < cfg->ddr_imc_num; i++) { + imc =3D &d->imc[i]; + if (!imc->mbase) + continue; + + imc->chan_mmio_sz =3D cfg->ddr_chan_mmio_sz; + imc->num_channels =3D cfg->ddr_chan_num; + imc->num_dimms =3D cfg->ddr_dimm_num; + imc->mc =3D mc++; + } + } + + return 0; +} + +/* Helpers to read memory controller registers */ +static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 widt= h) +{ + return readx(imc->mbase + imc->chan_mmio_sz * chan + offset, width); +} + +static u32 read_imc_mcmtr(struct res_config *cfg, struct skx_imc *imc, int= chan) +{ + return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_mcmtr_offset, cfg->ddr_r= eg_mcmtr_width); +} + +static u32 read_imc_dimmmtr(struct res_config *cfg, struct skx_imc *imc, i= nt chan, int dimm) +{ + return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_dimmmtr_offset + + cfg->ddr_reg_dimmmtr_width * dimm, + cfg->ddr_reg_dimmmtr_width); +} + +static bool ecc_enabled(u32 mcmtr) +{ + return (bool)ECC_ENABLED(mcmtr); +} + +static bool dimm_populated(u32 dimmmtr) +{ + return (bool)DIMM_POPULATED(dimmmtr); +} + +/* Get each DIMM's configurations of the memory controller @mci. */ +static int imh_get_dimm_config(struct mem_ctl_info *mci, struct res_config= *cfg) +{ + struct skx_pvt *pvt =3D mci->pvt_info; + struct skx_imc *imc =3D pvt->imc; + struct dimm_info *dimm; + u32 mcmtr, dimmmtr; + int i, j, ndimms; + + for (i =3D 0; i < imc->num_channels; i++) { + if (!imc->mbase) + continue; + + mcmtr =3D read_imc_mcmtr(cfg, imc, i); + + for (ndimms =3D 0, j =3D 0; j < imc->num_dimms; j++) { + dimmmtr =3D read_imc_dimmmtr(cfg, imc, i, j); + edac_dbg(1, "mcmtr 0x%x dimmmtr 0x%x (mc%d ch%d dimm%d)\n", + mcmtr, dimmmtr, imc->mc, i, j); + + if (!dimm_populated(dimmmtr)) + continue; + + dimm =3D edac_get_dimm(mci, i, j, 0); + ndimms +=3D skx_get_dimm_info(dimmmtr, 0, 0, dimm, + imc, i, j, cfg); + } + + if (ndimms && !ecc_enabled(mcmtr)) { + imh_printk(KERN_ERR, "ECC is disabled on mc%d ch%d\n", + imc->mc, i); + return -ENODEV; + } + } + + return 0; +} + +/* Register all memory controllers to the EDAC core. */ +static int imh_register_mci(struct res_config *cfg, struct list_head *edac= _list) +{ + struct skx_imc *imc; + struct skx_dev *d; + int i, rc; + + list_for_each_entry(d, edac_list, list) { + for (i =3D 0; i < cfg->ddr_imc_num; i++) { + imc =3D &d->imc[i]; + if (!imc->mbase) + continue; + + rc =3D skx_register_mci(imc, imc->dev, + dev_name(imc->dev), + "Intel IMH-based Socket", + EDAC_MOD_STR, + imh_get_dimm_config, cfg); + if (rc) + return rc; + } + } + + return 0; +} + +static struct res_config dmr_cfg =3D { + .type =3D DMR, + .support_ddr5 =3D true, + .mmio_base_l_north =3D 0xf6800000, + .mmio_base_l_south =3D 0xf6000000, + .ddr_chan_num =3D 1, + .ddr_dimm_num =3D 2, + .ddr_imc_base =3D 0x39b000, + .ddr_chan_mmio_sz =3D 0x8000, + .ddr_reg_mcmtr_offset =3D 0x360, + .ddr_reg_mcmtr_width =3D 4, + .ddr_reg_dimmmtr_offset =3D 0x370, + .ddr_reg_dimmmtr_width =3D 4, + .ubox_base =3D 0x0, + .ubox_size =3D 0x2000, + .ubox_reg_mmio_base_offset =3D 0x580, + .ubox_reg_mmio_base_width =3D 4, + .ubox_reg_socket_id_offset =3D 0x1080, + .ubox_reg_socket_id_width =3D 4, + .pcu_base =3D 0x3000, + .pcu_size =3D 0x10000, + .pcu_reg_capid3_offset =3D 0x290, + .pcu_reg_capid3_width =3D 4, + .sca_base =3D 0x24c000, + .sca_size =3D 0x2500, + .sca_reg_tolm_offset =3D 0x2100, + .sca_reg_tolm_width =3D 8, + .sca_reg_tohm_offset =3D 0x2108, + .sca_reg_tohm_width =3D 8, +}; + +static const struct x86_cpu_id imh_cpuids[] =3D { + X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &dmr_cfg), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, imh_cpuids); + +static struct notifier_block imh_mce_dec =3D { + .notifier_call =3D skx_mce_check_error, + .priority =3D MCE_PRIO_EDAC, +}; + +static int __init imh_init(void) +{ + const struct x86_cpu_id *id; + struct list_head *edac_list; + struct res_config *cfg; + const char *owner; + u64 tolm, tohm; + int rc; + + edac_dbg(2, "\n"); + + if (ghes_get_devices()) + return -EBUSY; + + owner =3D edac_get_owner(); + if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) + return -EBUSY; + + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + + id =3D x86_match_cpu(imh_cpuids); + if (!id) + return -ENODEV; + cfg =3D (struct res_config *)id->driver_data; + skx_set_res_cfg(cfg); + + if (!imh_get_tolm_tohm(cfg, &tolm, &tohm)) + return -ENODEV; + + skx_set_hi_lo(tolm, tohm); + + rc =3D imh_get_imc_num(cfg); + if (rc < 0) + goto fail; + + edac_list =3D skx_get_edac_list(); + + rc =3D imh_get_all_mmio_base_h(cfg, edac_list); + if (rc) + goto fail; + + rc =3D imh_get_munits(cfg, edac_list); + if (rc) + goto fail; + + rc =3D imh_register_mci(cfg, edac_list); + if (rc) + goto fail; + + rc =3D skx_adxl_get(); + if (rc) + goto fail; + + opstate_init(); + mce_register_decode_chain(&imh_mce_dec); + + imh_printk(KERN_INFO, "%s\n", IMH_REVISION); + + return 0; +fail: + skx_remove(); + return rc; +} + +static void __exit imh_exit(void) +{ + edac_dbg(2, "\n"); + + mce_unregister_decode_chain(&imh_mce_dec); + skx_adxl_put(); + skx_remove(); +} + +module_init(imh_init); +module_exit(imh_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Qiuxu Zhuo"); +MODULE_DESCRIPTION("MC Driver for Intel servers using IMH-based memory con= troller"); diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index e45abd0008ef..32a4ef27a987 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -124,7 +124,7 @@ void skx_adxl_put(void) } EXPORT_SYMBOL_GPL(skx_adxl_put); =20 -static void skx_init_mc_mapping(struct skx_dev *d) +void skx_init_mc_mapping(struct skx_dev *d) { /* * By default, the BIOS presents all memory controllers within each @@ -135,6 +135,7 @@ static void skx_init_mc_mapping(struct skx_dev *d) for (int i =3D 0; i < d->num_imc; i++) d->imc[i].mc_mapping =3D i; } +EXPORT_SYMBOL_GPL(skx_init_mc_mapping); =20 void skx_set_mc_mapping(struct skx_dev *d, u8 pmc, u8 lmc) { @@ -823,6 +824,9 @@ void skx_remove(void) if (d->imc[i].mbase) iounmap(d->imc[i].mbase); =20 + if (d->imc[i].dev) + put_device(d->imc[i].dev); + for (j =3D 0; j < d->imc[i].num_channels; j++) { if (d->imc[i].chan[j].cdev) pci_dev_put(d->imc[i].chan[j].cdev); @@ -846,7 +850,7 @@ EXPORT_SYMBOL_GPL(skx_remove); /* * Debug feature. * Exercise the address decode logic by writing an address to - * /sys/kernel/debug/edac/{skx,i10nm}_test/addr. + * /sys/kernel/debug/edac/{skx,i10nm,imh}_test/addr. */ static struct dentry *skx_test; =20 diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 86a883d3c2a4..39a3462ede28 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -121,20 +121,33 @@ struct reg_rrl { * memory controllers on the die. */ struct skx_dev { - struct list_head list; + /* {skx,i10nm}_edac */ u8 bus[4]; int seg; struct pci_dev *sad_all; struct pci_dev *util_all; - struct pci_dev *uracu; /* for i10nm CPU */ - struct pci_dev *pcu_cr3; /* for HBM memory detection */ + struct pci_dev *uracu; + struct pci_dev *pcu_cr3; u32 mcroute; + + /* imh_edac */ + /* System-view MMIO base physical addresses. */ + u64 mmio_base_h_north; + u64 mmio_base_h_south; + int pkg; + int num_imc; + struct list_head list; struct skx_imc { + /* i10nm_edac */ + struct pci_dev *mdev; + + /* imh_edac */ + struct device *dev; + struct mem_ctl_info *mci; - struct pci_dev *mdev; /* for i10nm CPU */ - void __iomem *mbase; /* for i10nm CPU */ - int chan_mmio_sz; /* for i10nm CPU */ + void __iomem *mbase; + int chan_mmio_sz; int num_channels; /* channels per memory controller */ int num_dimms; /* dimms per channel */ bool hbm_mc; @@ -178,7 +191,8 @@ enum type { SKX, I10NM, SPR, - GNR + GNR, + DMR, }; =20 enum { @@ -237,10 +251,6 @@ struct pci_bdf { =20 struct res_config { enum type type; - /* Configuration agent device ID */ - unsigned int decs_did; - /* Default bus number configuration register offset */ - int busno_cfg_offset; /* DDR memory controllers per socket */ int ddr_imc_num; /* DDR channels per DDR memory controller */ @@ -258,23 +268,53 @@ struct res_config { /* Per HBM channel memory-mapped I/O size */ int hbm_chan_mmio_sz; bool support_ddr5; - /* SAD device BDF */ - struct pci_bdf sad_all_bdf; - /* PCU device BDF */ - struct pci_bdf pcu_cr3_bdf; - /* UTIL device BDF */ - struct pci_bdf util_all_bdf; - /* URACU device BDF */ - struct pci_bdf uracu_bdf; - /* DDR mdev device BDF */ - struct pci_bdf ddr_mdev_bdf; - /* HBM mdev device BDF */ - struct pci_bdf hbm_mdev_bdf; - int sad_all_offset; /* RRL register sets per DDR channel */ struct reg_rrl *reg_rrl_ddr; /* RRL register sets per HBM channel */ struct reg_rrl *reg_rrl_hbm[2]; + union { + /* {skx,i10nm}_edac */ + struct { + /* Configuration agent device ID */ + unsigned int decs_did; + /* Default bus number configuration register offset */ + int busno_cfg_offset; + struct pci_bdf sad_all_bdf; + struct pci_bdf pcu_cr3_bdf; + struct pci_bdf util_all_bdf; + struct pci_bdf uracu_bdf; + struct pci_bdf ddr_mdev_bdf; + struct pci_bdf hbm_mdev_bdf; + int sad_all_offset; + }; + /* imh_edac */ + struct { + /* MMIO base physical address in local package view */ + u64 mmio_base_l_north; + u64 mmio_base_l_south; + u64 ddr_imc_base; + u64 ddr_reg_mcmtr_offset; + u8 ddr_reg_mcmtr_width; + u64 ddr_reg_dimmmtr_offset; + u8 ddr_reg_dimmmtr_width; + u64 ubox_base; + u32 ubox_size; + u32 ubox_reg_mmio_base_offset; + u8 ubox_reg_mmio_base_width; + u32 ubox_reg_socket_id_offset; + u8 ubox_reg_socket_id_width; + u64 pcu_base; + u32 pcu_size; + u32 pcu_reg_capid3_offset; + u8 pcu_reg_capid3_width; + u64 sca_base; + u32 sca_size; + u32 sca_reg_tolm_offset; + u8 sca_reg_tolm_width; + u32 sca_reg_tohm_offset; + u8 sca_reg_tohm_width; + }; + }; }; =20 typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci, @@ -287,6 +327,7 @@ void skx_adxl_put(void); void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_l= og); void skx_set_mem_cfg(bool mem_cfg_2lm); void skx_set_res_cfg(struct res_config *cfg); +void skx_init_mc_mapping(struct skx_dev *d); void skx_set_mc_mapping(struct skx_dev *d, u8 pmc, u8 lmc); =20 int skx_get_src_id(struct skx_dev *d, int off, u8 *id); --=20 2.43.0 From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C5A1E22CBC0; Wed, 19 Nov 2025 13:52:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560374; cv=none; b=R3HhpmhM8bNT+15k2xFtqbff66j5BBIa+/M6Igx8JlHHYAF3+T1DnivnGmQLSYpthSJvgo7+hZ9uYIT9ho+OFmXJrO9j728Vq8bDFzXD/fXS+NIACuvsA8bDkODh9a7E31ZNw3sfHqG35ARsFPmBpdnyijZGNbgqZd2WkGdjx/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560374; c=relaxed/simple; bh=Ip+OfuruZplu6JDngj96v/lpIV4100IUqpyPeNFbO9U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sTA37MA+rVsEZ1ovYn/zPU3MItu/OTb2+cBJCXZyTfmURVLGQUEpwKg9SklGDuzLZpNse+6zjKqfKvslKLqzC17I+So9yuLxlCvJKaUPmWq8jVDDredpY1O46pSgDqU4WI1v6Kcg3rk2TD6mUpwslUJwkbEsedYk1jKGBE1utyY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=RqfKd18+; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="RqfKd18+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560373; x=1795096373; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ip+OfuruZplu6JDngj96v/lpIV4100IUqpyPeNFbO9U=; b=RqfKd18+LxWgB5YVO9keZoxlbDOBJ+2ooelSvsFdL3k1ioO9oDPTquRt YX67LAJ9klXjFffXBWU3FNUuh9aqGx4XaFX4v6CSwsubyRgv6Ej0yC8b2 tvh7PizDZ+35mHfwawxhx4CptyhhIuQlbDhEF0jqElC73ZOEdBxDm0air hzoSrCGUjQJsb3LKLCUl5/pEisorTgV9Dl3XSIVQ+6Evrr4972CNbicxq Ng5amEd+l6dFrZRvj1s/u1U14sU62Lv/DJVw0KE4SIIodhI1IdHxFiI2Z Tla6AgR/mgfH5y8QxzP2SmPsE2nliBsBc2I+4g5gcwL7fsrKADE3BXuDR g==; X-CSE-ConnectionGUID: 3j6/pvGCRViKp+Yptd37EQ== X-CSE-MsgGUID: dVHaQQebRlqHlgDh8zU9fQ== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607410" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607410" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:52 -0800 X-CSE-ConnectionGUID: Obu4ruGaTc6x5azfYvulWQ== X-CSE-MsgGUID: s/VB47YYRCy4lDvgbwMSag== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439641" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:52:50 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/7] EDAC/skx_common: Extend the maximum number of DRAM chip row bits Date: Wed, 19 Nov 2025 21:41:29 +0800 Message-ID: <20251119134132.2389472-6-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The allowed maximum number of row bits for DRAM chips in the Diamond Rapids server processor is up to 19. Extend the current maximum row bits from 18 to 19. Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/skx_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index 32a4ef27a987..3276afe43922 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -451,7 +451,7 @@ static int skx_get_dimm_attr(u32 reg, int lobit, int hi= bit, int add, } =20 #define numrank(reg) skx_get_dimm_attr(reg, 12, 13, 0, 0, 2, "ranks") -#define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 6, "rows") +#define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 7, "rows") #define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols") =20 int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, --=20 2.43.0 From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D223035F8C5; Wed, 19 Nov 2025 13:53:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560388; cv=none; b=H3OuzVjTh57YLujYKE3WMFf7LxFDQkY2daCsV8enlOjfi6zwiqVgyAunBVpjYm+49aCJFW+4WTqYSO96xa+BrFQTrpRQ9RcCBknnept4hzR1L1mNk4Rml/ZzFSJIsQL2c7bqjmw0tdZV7ZNZspCFB2fdbxN7P3X+vjex3BpxGks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560388; c=relaxed/simple; bh=4nvQWRKP+c+lm2sgAd6g5mnHFYeTFSjXsAM4cnMd1Ic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NoVigG34hPeYM8/1kZAPq2hJg6BdkdFwj87KWbbMlQCJ9CR1++7Ydg3BjTfB6BSmwJ6uAOqkP7ZbaIsZM5bw5urOxnRxHsQWmn1x0So3HQesQwFUKDoxYIHvtzY+oR4j9hrxFxlwjlj/ju4VGXAKwumroydmtRRd3psBIaH24pk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=edIMOnoV; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="edIMOnoV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560387; x=1795096387; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4nvQWRKP+c+lm2sgAd6g5mnHFYeTFSjXsAM4cnMd1Ic=; b=edIMOnoVrgLZ/oWbHufUYZ9LtooMM+vEX/jg9aK/xW9RHkeiGzJBHL9v VmJEW7y7OHS7LXtsjepWtswsBnRbH2cGFIkIJsd27mgmv4n4ORkFkOPVi eS51n3x2VF5NVuk1AUFQvQoucnOSX3NeyLDrnwmdUrcKOXtLw9u7r7cE2 AEkQxfH99hQnM+SMY3L938e6luBWIvcqvGQG/KRKqIW/YlA0woaAow0ql rIdedt11SQzkHojyeaIfCDD0JY2uTgA03iTFAVKiapdZuf6HjrXUbt81b 4bHtCkACPLYY4H78hUk7+P1jgevxC2senLwESoICFv9EWWH7htBDQu9nI A==; X-CSE-ConnectionGUID: akqBLTOaTTegXuN2XuK5JA== X-CSE-MsgGUID: S2LYjIvDTi2Tmoyv74admA== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607446" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607446" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:53:04 -0800 X-CSE-ConnectionGUID: vqiEW6IUTPisxd/q6aXFQQ== X-CSE-MsgGUID: 65PH8biHQPy4tDGN8LqPcg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439692" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:53:02 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 6/7] EDAC/{skx_comm,imh}: Detect 2-level memory configuration Date: Wed, 19 Nov 2025 21:41:30 +0800 Message-ID: <20251119134132.2389472-7-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Detect 2-level memory configurations and notify the 'skx_common' library to enable ADXL 2-level memory error decoding. Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/imh_base.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/edac/skx_common.h | 4 ++++ 2 files changed, 42 insertions(+) diff --git a/drivers/edac/imh_base.c b/drivers/edac/imh_base.c index 9c1a17c53ec1..5f0313c1ac2e 100644 --- a/drivers/edac/imh_base.c +++ b/drivers/edac/imh_base.c @@ -35,6 +35,9 @@ #define TOLM(reg) (((u64)GET_BITFIELD(reg, 16, 31)) << 16) #define TOHM(reg) (((u64)GET_BITFIELD(reg, 16, 51)) << 16) =20 +/* Home Agent (HA) */ +#define NMCACHING(reg) GET_BITFIELD(reg, 8, 8) + /** * struct local_reg - A register as described in the local package view. * @@ -346,6 +349,35 @@ static int imh_get_munits(struct res_config *cfg, stru= ct list_head *edac_list) return 0; } =20 +static bool check_2lm_enabled(struct res_config *cfg, struct skx_dev *d, i= nt ha_idx) +{ + DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ha, ha_idx, mode); + + if (!read_local_reg(®)) + return false; + + if (!NMCACHING(reg.val)) + return false; + + edac_dbg(2, "2-level memory configuration (reg 0x%llx, ha idx %d)\n", reg= .val, ha_idx); + return true; +} + +/* Check whether the system has a 2-level memory configuration. */ +static bool imh_2lm_enabled(struct res_config *cfg, struct list_head *head) +{ + struct skx_dev *d; + int i; + + list_for_each_entry(d, head, list) { + for (i =3D 0; i < cfg->ddr_imc_num; i++) + if (check_2lm_enabled(cfg, d, i)) + return true; + } + + return false; +} + /* Helpers to read memory controller registers */ static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 widt= h) { @@ -467,6 +499,10 @@ static struct res_config dmr_cfg =3D { .sca_reg_tolm_width =3D 8, .sca_reg_tohm_offset =3D 0x2108, .sca_reg_tohm_width =3D 8, + .ha_base =3D 0x3eb000, + .ha_size =3D 0x1000, + .ha_reg_mode_offset =3D 0x4a0, + .ha_reg_mode_width =3D 4, }; =20 static const struct x86_cpu_id imh_cpuids[] =3D { @@ -526,6 +562,8 @@ static int __init imh_init(void) if (rc) goto fail; =20 + skx_set_mem_cfg(imh_2lm_enabled(cfg, edac_list)); + rc =3D imh_register_mci(cfg, edac_list); if (rc) goto fail; diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index 39a3462ede28..f88038e5b18c 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -313,6 +313,10 @@ struct res_config { u8 sca_reg_tolm_width; u32 sca_reg_tohm_offset; u8 sca_reg_tohm_width; + u64 ha_base; + u32 ha_size; + u32 ha_reg_mode_offset; + u8 ha_reg_mode_width; }; }; }; --=20 2.43.0 From nobody Tue Dec 2 02:19:46 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED963364026; Wed, 19 Nov 2025 13:53:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560394; cv=none; b=r7NtpggnLZepfFh+ZoyDKuz5pUiogCGGqQr9P8RwqqPViGoZ68mAaw2lffWxodn46gAVCF12XrwtbTYpKmkNIx3rfOGlE/AzVM8nH9G3FfXsH0CZ1CNaX1PZ8gIUta/UC8/G+ASz4mDiRxDieL/2LGmkrKNh1imOWpEbazYbqY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763560394; c=relaxed/simple; bh=qyqLGbeqaYZi7TaAIvn7Ded65sgt4kEGWxVlLaVggn8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BnB3VB/qVWOicXKqt/28SeJj/YEit4hoLq9cFg0YwWtH4pzRC7rVeFSt9qHBhWnlZUA2RxajeiFleT4kDufxV1HnLCZj37Plfas593JK3lQ2eGzuqQO8eY9ZNVec8l61eXwfrTB3R6b2QSELhIukmz7E8dgvXcRxB3jhsqOBPmw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=KfNBWPE5; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="KfNBWPE5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763560393; x=1795096393; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qyqLGbeqaYZi7TaAIvn7Ded65sgt4kEGWxVlLaVggn8=; b=KfNBWPE5kTYdSL/V6Hf+GwCrfqaSi1YUUmXQYVM9sGAHxC5si/n+UKIb vXupmQKwDA/dmhE+Sf48i709pBaRZt7BhDzrohNrYa+BiQC2VR7j2+ulH ebtGAHqhtNIM2haLcSZtZO4+6b7xhe0BNelVGVN284ichdZeCkXBdhN1N WeWsmEXG0Xoi6jfjfK4bjCFbe/H4TANoMv8c06Jq7tr4Itl2qO3nI1kp8 m6R1Iu0C+h3AMXpGzUzp/bytVPUnfJ4g9g8uQNbTiHnwxGgl1vFYUtFYg S6VvhS+My7/6pMxrHy8i9RlhXUW4NNuG4Q4jqSnsO7SYfwUNH4X2aAqkv w==; X-CSE-ConnectionGUID: tKSZ5VLGRwWWV0VMyj00Tw== X-CSE-MsgGUID: BKF1l2rmQ2ymmzfplAM9Ng== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="64607471" X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="64607471" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:53:13 -0800 X-CSE-ConnectionGUID: YvhKlCICT0Os90jV4hDiNw== X-CSE-MsgGUID: PgOugZ3nQ6+QTD37wWO5LQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,315,1754982000"; d="scan'208";a="214439720" Received: from qiuxu-clx.sh.intel.com ([10.239.53.109]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 05:53:11 -0800 From: Qiuxu Zhuo To: Tony Luck , Borislav Petkov Cc: Qiuxu Zhuo , Yi Lai , linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 7/7] EDAC/imh: Setup 'imh_test' debugfs testing node Date: Wed, 19 Nov 2025 21:41:31 +0800 Message-ID: <20251119134132.2389472-8-qiuxu.zhuo@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> References: <20251119134132.2389472-1-qiuxu.zhuo@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Setup the following debugfs testing node to enable fake memory error address decoding tests for the imh_edac driver. /sys/kernel/debug/edac/imh_test/addr Tested-by: Yi Lai Signed-off-by: Qiuxu Zhuo --- drivers/edac/imh_base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/edac/imh_base.c b/drivers/edac/imh_base.c index 5f0313c1ac2e..91969f55cbb0 100644 --- a/drivers/edac/imh_base.c +++ b/drivers/edac/imh_base.c @@ -574,6 +574,7 @@ static int __init imh_init(void) =20 opstate_init(); mce_register_decode_chain(&imh_mce_dec); + skx_setup_debug("imh_test"); =20 imh_printk(KERN_INFO, "%s\n", IMH_REVISION); =20 @@ -587,6 +588,7 @@ static void __exit imh_exit(void) { edac_dbg(2, "\n"); =20 + skx_teardown_debug(); mce_unregister_decode_chain(&imh_mce_dec); skx_adxl_put(); skx_remove(); --=20 2.43.0