* [PATCH 0/2] EDAC: Add two Intel Amston Lake SoCs support
@ 2025-11-24 6:54 Qiuxu Zhuo
2025-11-24 6:54 ` [PATCH 1/2] EDAC/igen6: " Qiuxu Zhuo
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Qiuxu Zhuo @ 2025-11-24 6:54 UTC (permalink / raw)
To: Tony Luck, Borislav Petkov
Cc: Qiuxu Zhuo, Yi Lai, Jianfeng Gao, linux-edac, linux-kernel
Patch 1: Add IBECC EDAC support for another two Intel Amston Lake SoCs.
Patch 2: Configure masks of four memory controller registers properly.
Qiuxu Zhuo (2):
EDAC/igen6: Add two Intel Amston Lake SoCs support
EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable
drivers/edac/igen6_edac.c | 71 ++++++++++++++++++++++++++++++++-------
1 file changed, 59 insertions(+), 12 deletions(-)
base-commit: ac3fd01e4c1efce8f2c054cdeb2ddd2fc0fb150d
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/2] EDAC/igen6: Add two Intel Amston Lake SoCs support 2025-11-24 6:54 [PATCH 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo @ 2025-11-24 6:54 ` Qiuxu Zhuo 2025-11-24 6:54 ` [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo 2025-12-19 4:29 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo 2 siblings, 0 replies; 9+ messages in thread From: Qiuxu Zhuo @ 2025-11-24 6:54 UTC (permalink / raw) To: Tony Luck, Borislav Petkov Cc: Qiuxu Zhuo, Jianfeng Gao, Yi Lai, linux-edac, linux-kernel Intel Amston Lake SoCs with IBECC (In-Band ECC) capability share the same IBECC registers as Alder Lake-N SoCs. Add two new compute die IDs for Amston Lake SoC products to enable EDAC support. Tested-by: Jianfeng Gao <jianfeng.gao@intel.com> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> --- drivers/edac/igen6_edac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index 2fc59f9eed69..5d887a3115f0 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -246,6 +246,8 @@ static struct work_struct ecclog_work; /* Compute did IDs for Amston Lake with IBECC */ #define DID_ASL_SKU1 0x464a +#define DID_ASL_SKU2 0x4646 +#define DID_ASL_SKU3 0x4652 /* Compute die IDs for Raptor Lake-P with IBECC */ #define DID_RPL_P_SKU1 0xa706 @@ -618,6 +620,8 @@ static struct pci_device_id igen6_pci_tbl[] = { { PCI_VDEVICE(INTEL, DID_ADL_N_SKU12), (kernel_ulong_t)&adl_n_cfg }, { PCI_VDEVICE(INTEL, DID_AZB_SKU1), (kernel_ulong_t)&adl_n_cfg }, { PCI_VDEVICE(INTEL, DID_ASL_SKU1), (kernel_ulong_t)&adl_n_cfg }, + { PCI_VDEVICE(INTEL, DID_ASL_SKU2), (kernel_ulong_t)&adl_n_cfg }, + { PCI_VDEVICE(INTEL, DID_ASL_SKU3), (kernel_ulong_t)&adl_n_cfg }, { PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), (kernel_ulong_t)&rpl_p_cfg }, { PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), (kernel_ulong_t)&rpl_p_cfg }, { PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), (kernel_ulong_t)&rpl_p_cfg }, -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable 2025-11-24 6:54 [PATCH 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo 2025-11-24 6:54 ` [PATCH 1/2] EDAC/igen6: " Qiuxu Zhuo @ 2025-11-24 6:54 ` Qiuxu Zhuo 2025-12-17 18:19 ` Luck, Tony 2025-12-19 4:29 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo 2 siblings, 1 reply; 9+ messages in thread From: Qiuxu Zhuo @ 2025-11-24 6:54 UTC (permalink / raw) To: Tony Luck, Borislav Petkov Cc: Qiuxu Zhuo, Jianfeng Gao, Yi Lai, linux-edac, linux-kernel The masks used to retrieve base addresses from {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} registers can be CPU model-specific. Currently, igen6_edac hard-codes these masks with the most significant bit at 38, while some CPUs have extended the most significant bit to bit 41 or bit 45. Systems with more than 512GB (2^39) memory need this extension to get correct masks. But all CPUs currently supported by igen6_edac support max memory less than 512GB (e.g., max memory size for Raptor Lake systems is 192GB, for Alder Lake systems is 128GB, ...), which means the previous hard-coded most significant bit 38 still works properly. So backporting this patch to stable kernels is not necessary. To make these masks reflect the CPUs' real support and easily support future Intel client CPUs supported by igen6_edac that have more than 512GB memory, add four new fields to structure res_config to make these masks CPU model-specific and configure them properly. Tested-by: Jianfeng Gao <jianfeng.gao@intel.com> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> --- drivers/edac/igen6_edac.c | 67 ++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index 5d887a3115f0..db4aa9f581e3 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -79,15 +79,11 @@ #define ECC_ERROR_LOG_OFFSET (IBECC_BASE + res_cfg->ibecc_error_log_offset) #define ECC_ERROR_LOG_CE BIT_ULL(62) #define ECC_ERROR_LOG_UE BIT_ULL(63) -#define ECC_ERROR_LOG_ADDR_SHIFT 5 -#define ECC_ERROR_LOG_ADDR(v) GET_BITFIELD(v, 5, 38) -#define ECC_ERROR_LOG_ADDR45(v) GET_BITFIELD(v, 5, 45) #define ECC_ERROR_LOG_SYND(v) GET_BITFIELD(v, 46, 61) /* Host MMIO base address */ #define MCHBAR_OFFSET 0x48 #define MCHBAR_EN BIT_ULL(0) -#define MCHBAR_BASE(v) (GET_BITFIELD(v, 16, 38) << 16) #define MCHBAR_SIZE 0x10000 /* Parameters for the channel decode stage */ @@ -125,10 +121,21 @@ #define MEM_SLICE_HASH_MASK(v) (GET_BITFIELD(v, 6, 19) << 6) #define MEM_SLICE_HASH_LSB_MASK_BIT(v) GET_BITFIELD(v, 24, 26) +/* Non-constant mask variant of FIELD_GET() */ +#define field_get(mask, reg) (((reg) & (mask)) >> (ffs(mask) - 1)) + static struct res_config { bool machine_check; /* The number of present memory controllers. */ int num_imc; + /* Host MMIO configuration */ + u64 reg_mchbar_mask; + /* Top of memory */ + u64 reg_tom_mask; + /* Top of upper usable DRAM */ + u64 reg_touud_mask; + /* IBECC error log */ + u64 reg_eccerrlog_addr_mask; u32 imc_base; u32 cmf_base; u32 cmf_size; @@ -305,7 +312,8 @@ static int get_mchbar(struct pci_dev *pdev, u64 *mchbar) return -ENODEV; } - *mchbar = MCHBAR_BASE(u.v); + *mchbar = u.v & res_cfg->reg_mchbar_mask; + edac_dbg(2, "MCHBAR 0x%llx (reg 0x%llx)\n", *mchbar, u.v); return 0; } @@ -481,11 +489,15 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc) static u64 rpl_p_err_addr(u64 ecclog) { - return ECC_ERROR_LOG_ADDR45(ecclog); + return field_get(res_cfg->reg_eccerrlog_addr_mask, ecclog); } static struct res_config ehl_cfg = { .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(38, 16), + .reg_tom_mask = GENMASK_ULL(38, 20), + .reg_touud_mask = GENMASK_ULL(38, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0x5000, .ibecc_base = 0xdc00, .ibecc_available = ehl_ibecc_available, @@ -496,6 +508,10 @@ static struct res_config ehl_cfg = { static struct res_config icl_cfg = { .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(38, 16), + .reg_tom_mask = GENMASK_ULL(38, 20), + .reg_touud_mask = GENMASK_ULL(38, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0x5000, .ibecc_base = 0xd800, .ibecc_error_log_offset = 0x170, @@ -507,6 +523,10 @@ static struct res_config icl_cfg = { static struct res_config tgl_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(38, 17), + .reg_tom_mask = GENMASK_ULL(38, 20), + .reg_touud_mask = GENMASK_ULL(38, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0x5000, .cmf_base = 0x11000, .cmf_size = 0x800, @@ -521,6 +541,10 @@ static struct res_config tgl_cfg = { static struct res_config adl_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x68, @@ -532,6 +556,10 @@ static struct res_config adl_cfg = { static struct res_config adl_n_cfg = { .machine_check = true, .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x68, @@ -543,6 +571,10 @@ static struct res_config adl_n_cfg = { static struct res_config rpl_p_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x68, @@ -555,6 +587,10 @@ static struct res_config rpl_p_cfg = { static struct res_config mtl_ps_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x170, @@ -566,6 +602,10 @@ static struct res_config mtl_ps_cfg = { static struct res_config mtl_p_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x170, @@ -577,6 +617,10 @@ static struct res_config mtl_p_cfg = { static struct res_config wcl_cfg = { .machine_check = true, .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x170, @@ -908,8 +952,8 @@ static void ecclog_work_cb(struct work_struct *work) if (res_cfg->err_addr) eaddr = res_cfg->err_addr(node->ecclog); else - eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << - ECC_ERROR_LOG_ADDR_SHIFT; + eaddr = node->ecclog & res_cfg->reg_eccerrlog_addr_mask; + res.mc = node->mc; res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc); res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc); @@ -1129,8 +1173,7 @@ static int debugfs_u64_set(void *data, u64 val) pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val); - val >>= ECC_ERROR_LOG_ADDR_SHIFT; - ecclog = (val << ECC_ERROR_LOG_ADDR_SHIFT) | ECC_ERROR_LOG_CE; + ecclog = (val & res_cfg->reg_eccerrlog_addr_mask) | ECC_ERROR_LOG_CE; if (!ecclog_gen_pool_add(0, ecclog)) irq_work_queue(&ecclog_irq_work); @@ -1196,7 +1239,7 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar) goto fail; } - igen6_tom = u.v & GENMASK_ULL(38, 20); + igen6_tom = u.v & res_cfg->reg_tom_mask; if (get_mchbar(pdev, mchbar)) goto fail; @@ -1207,7 +1250,7 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar) else if (pci_read_config_dword(pdev, TOUUD_OFFSET + 4, &u.v_hi)) edac_dbg(2, "Failed to read upper TOUUD\n"); else - igen6_touud = u.v & GENMASK_ULL(38, 20); + igen6_touud = u.v & res_cfg->reg_touud_mask; #endif return 0; -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable 2025-11-24 6:54 ` [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo @ 2025-12-17 18:19 ` Luck, Tony 2025-12-18 0:44 ` Zhuo, Qiuxu 0 siblings, 1 reply; 9+ messages in thread From: Luck, Tony @ 2025-12-17 18:19 UTC (permalink / raw) To: Qiuxu Zhuo Cc: Borislav Petkov, Jianfeng Gao, Yi Lai, linux-edac, linux-kernel On Mon, Nov 24, 2025 at 02:54:57PM +0800, Qiuxu Zhuo wrote: > diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c > index 5d887a3115f0..db4aa9f581e3 100644 > --- a/drivers/edac/igen6_edac.c > +++ b/drivers/edac/igen6_edac.c ... > +/* Non-constant mask variant of FIELD_GET() */ > +#define field_get(mask, reg) (((reg) & (mask)) >> (ffs(mask) - 1)) I applied to v6.19-rc1. But when building with make W=1 I get this warning: drivers/edac/igen6_edac.c:125:9: warning: "field_get" redefined 125 | #define field_get(mask, reg) (((reg) & (mask)) >> (ffs(mask) - 1)) | ^~~~~~~~~ In file included from ./include/linux/fortify-string.h:5, from ./include/linux/string.h:386, from ./include/linux/bitmap.h:13, from ./include/linux/cpumask.h:11, from ./arch/x86/include/asm/paravirt.h:21, from ./arch/x86/include/asm/cpuid/api.h:57, from ./arch/x86/include/asm/processor.h:19, from ./arch/x86/include/asm/timex.h:5, from ./include/linux/timex.h:67, from ./include/linux/time32.h:13, from ./include/linux/time.h:60, from ./include/linux/stat.h:19, from ./include/linux/module.h:13, from drivers/edac/igen6_edac.c:13: ./include/linux/bitfield.h:298:9: note: this is the location of the previous definition 298 | #define field_get(mask, reg) \ -Tony ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable 2025-12-17 18:19 ` Luck, Tony @ 2025-12-18 0:44 ` Zhuo, Qiuxu 0 siblings, 0 replies; 9+ messages in thread From: Zhuo, Qiuxu @ 2025-12-18 0:44 UTC (permalink / raw) To: Luck, Tony Cc: Borislav Petkov, Gao, Jianfeng, Lai, Yi1, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org > From: Luck, Tony <tony.luck@intel.com> > Sent: Thursday, December 18, 2025 2:19 AM > To: Zhuo, Qiuxu <qiuxu.zhuo@intel.com> > Cc: Borislav Petkov <bp@alien8.de>; Gao, Jianfeng <jianfeng.gao@intel.com>; > Lai, Yi1 <yi1.lai@intel.com>; linux-edac@vger.kernel.org; linux- > kernel@vger.kernel.org > Subject: Re: [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, > ECC_ERROR_LOG} configurable > > On Mon, Nov 24, 2025 at 02:54:57PM +0800, Qiuxu Zhuo wrote: > > diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c > > index 5d887a3115f0..db4aa9f581e3 100644 > > --- a/drivers/edac/igen6_edac.c > > +++ b/drivers/edac/igen6_edac.c > ... > > +/* Non-constant mask variant of FIELD_GET() */ #define > > +field_get(mask, reg) (((reg) & (mask)) >> (ffs(mask) - 1)) > > I applied to v6.19-rc1. But when building with make W=1 I get this warning: > > drivers/edac/igen6_edac.c:125:9: warning: "field_get" redefined > 125 | #define field_get(mask, reg) (((reg) & (mask)) >> (ffs(mask) - 1)) > | ^~~~~~~~~ Thanks Tony for reporting this warning. A global non-constant field_get() helper is now included in <linux/bitfield.h> from v6.19-rc1, so the driver doesn't need to define it locally. I'll remove the local field_get() definition from the driver in v2 to fix this warning. -Qiuxu ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support 2025-11-24 6:54 [PATCH 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo 2025-11-24 6:54 ` [PATCH 1/2] EDAC/igen6: " Qiuxu Zhuo 2025-11-24 6:54 ` [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo @ 2025-12-19 4:29 ` Qiuxu Zhuo 2025-12-19 4:29 ` [PATCH v2 1/2] EDAC/igen6: " Qiuxu Zhuo ` (2 more replies) 2 siblings, 3 replies; 9+ messages in thread From: Qiuxu Zhuo @ 2025-12-19 4:29 UTC (permalink / raw) To: tony.luck, bp; +Cc: qiuxu.zhuo, jianfeng.gao, linux-edac, linux-kernel, yi1.lai Changes in v2: - Patch 1: No changes. - Patch 2: Remove local field_get() definition. Patch 1: Add IBECC EDAC support for another two Intel Amston Lake SoCs. Patch 2: Configure masks of four memory controller registers properly. Qiuxu Zhuo (2): EDAC/igen6: Add two Intel Amston Lake SoCs support EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable drivers/edac/igen6_edac.c | 69 ++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 12 deletions(-) base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8 -- 2.43.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/2] EDAC/igen6: Add two Intel Amston Lake SoCs support 2025-12-19 4:29 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo @ 2025-12-19 4:29 ` Qiuxu Zhuo 2025-12-19 4:29 ` [PATCH v2 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo 2025-12-19 21:51 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Luck, Tony 2 siblings, 0 replies; 9+ messages in thread From: Qiuxu Zhuo @ 2025-12-19 4:29 UTC (permalink / raw) To: tony.luck, bp; +Cc: qiuxu.zhuo, jianfeng.gao, linux-edac, linux-kernel, yi1.lai Intel Amston Lake SoCs with IBECC (In-Band ECC) capability share the same IBECC registers as Alder Lake-N SoCs. Add two new compute die IDs for Amston Lake SoC products to enable EDAC support. Tested-by: Jianfeng Gao <jianfeng.gao@intel.com> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> --- v1->v2: - No changes. drivers/edac/igen6_edac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index 553c31a2d922..d29cfc7fad93 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -246,6 +246,8 @@ static struct work_struct ecclog_work; /* Compute did IDs for Amston Lake with IBECC */ #define DID_ASL_SKU1 0x464a +#define DID_ASL_SKU2 0x4646 +#define DID_ASL_SKU3 0x4652 /* Compute die IDs for Raptor Lake-P with IBECC */ #define DID_RPL_P_SKU1 0xa706 @@ -618,6 +620,8 @@ static struct pci_device_id igen6_pci_tbl[] = { { PCI_VDEVICE(INTEL, DID_ADL_N_SKU12), (kernel_ulong_t)&adl_n_cfg }, { PCI_VDEVICE(INTEL, DID_AZB_SKU1), (kernel_ulong_t)&adl_n_cfg }, { PCI_VDEVICE(INTEL, DID_ASL_SKU1), (kernel_ulong_t)&adl_n_cfg }, + { PCI_VDEVICE(INTEL, DID_ASL_SKU2), (kernel_ulong_t)&adl_n_cfg }, + { PCI_VDEVICE(INTEL, DID_ASL_SKU3), (kernel_ulong_t)&adl_n_cfg }, { PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), (kernel_ulong_t)&rpl_p_cfg }, { PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), (kernel_ulong_t)&rpl_p_cfg }, { PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), (kernel_ulong_t)&rpl_p_cfg }, -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable 2025-12-19 4:29 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo 2025-12-19 4:29 ` [PATCH v2 1/2] EDAC/igen6: " Qiuxu Zhuo @ 2025-12-19 4:29 ` Qiuxu Zhuo 2025-12-19 21:51 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Luck, Tony 2 siblings, 0 replies; 9+ messages in thread From: Qiuxu Zhuo @ 2025-12-19 4:29 UTC (permalink / raw) To: tony.luck, bp; +Cc: qiuxu.zhuo, jianfeng.gao, linux-edac, linux-kernel, yi1.lai The masks used to retrieve base addresses from {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} registers can be CPU model-specific. Currently, igen6_edac hard-codes these masks with the most significant bit at 38, while some CPUs have extended the most significant bit to bit 41 or bit 45. Systems with more than 512GB (2^39) memory need this extension to get correct masks. But all CPUs currently supported by igen6_edac support max memory less than 512GB (e.g., max memory size for Raptor Lake systems is 192GB, for Alder Lake systems is 128GB, ...), which means the previous hard-coded most significant bit 38 still works properly. So backporting this patch to stable kernels is not necessary. To make these masks reflect the CPUs' real support and easily support future Intel client CPUs supported by igen6_edac that have more than 512GB memory, add four new fields to structure res_config to make these masks CPU model-specific and configure them properly. Tested-by: Jianfeng Gao <jianfeng.gao@intel.com> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> --- v1->v2: - Remove local get_field() definition. drivers/edac/igen6_edac.c | 65 +++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index d29cfc7fad93..717862dc4765 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -19,6 +19,7 @@ #include <linux/genalloc.h> #include <linux/edac.h> #include <linux/bits.h> +#include <linux/bitfield.h> #include <linux/io.h> #include <asm/mach_traps.h> #include <asm/nmi.h> @@ -79,15 +80,11 @@ #define ECC_ERROR_LOG_OFFSET (IBECC_BASE + res_cfg->ibecc_error_log_offset) #define ECC_ERROR_LOG_CE BIT_ULL(62) #define ECC_ERROR_LOG_UE BIT_ULL(63) -#define ECC_ERROR_LOG_ADDR_SHIFT 5 -#define ECC_ERROR_LOG_ADDR(v) GET_BITFIELD(v, 5, 38) -#define ECC_ERROR_LOG_ADDR45(v) GET_BITFIELD(v, 5, 45) #define ECC_ERROR_LOG_SYND(v) GET_BITFIELD(v, 46, 61) /* Host MMIO base address */ #define MCHBAR_OFFSET 0x48 #define MCHBAR_EN BIT_ULL(0) -#define MCHBAR_BASE(v) (GET_BITFIELD(v, 16, 38) << 16) #define MCHBAR_SIZE 0x10000 /* Parameters for the channel decode stage */ @@ -129,6 +126,14 @@ static struct res_config { bool machine_check; /* The number of present memory controllers. */ int num_imc; + /* Host MMIO configuration */ + u64 reg_mchbar_mask; + /* Top of memory */ + u64 reg_tom_mask; + /* Top of upper usable DRAM */ + u64 reg_touud_mask; + /* IBECC error log */ + u64 reg_eccerrlog_addr_mask; u32 imc_base; u32 cmf_base; u32 cmf_size; @@ -305,7 +310,8 @@ static int get_mchbar(struct pci_dev *pdev, u64 *mchbar) return -ENODEV; } - *mchbar = MCHBAR_BASE(u.v); + *mchbar = u.v & res_cfg->reg_mchbar_mask; + edac_dbg(2, "MCHBAR 0x%llx (reg 0x%llx)\n", *mchbar, u.v); return 0; } @@ -481,11 +487,15 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc) static u64 rpl_p_err_addr(u64 ecclog) { - return ECC_ERROR_LOG_ADDR45(ecclog); + return field_get(res_cfg->reg_eccerrlog_addr_mask, ecclog); } static struct res_config ehl_cfg = { .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(38, 16), + .reg_tom_mask = GENMASK_ULL(38, 20), + .reg_touud_mask = GENMASK_ULL(38, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0x5000, .ibecc_base = 0xdc00, .ibecc_available = ehl_ibecc_available, @@ -496,6 +506,10 @@ static struct res_config ehl_cfg = { static struct res_config icl_cfg = { .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(38, 16), + .reg_tom_mask = GENMASK_ULL(38, 20), + .reg_touud_mask = GENMASK_ULL(38, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0x5000, .ibecc_base = 0xd800, .ibecc_error_log_offset = 0x170, @@ -507,6 +521,10 @@ static struct res_config icl_cfg = { static struct res_config tgl_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(38, 17), + .reg_tom_mask = GENMASK_ULL(38, 20), + .reg_touud_mask = GENMASK_ULL(38, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0x5000, .cmf_base = 0x11000, .cmf_size = 0x800, @@ -521,6 +539,10 @@ static struct res_config tgl_cfg = { static struct res_config adl_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x68, @@ -532,6 +554,10 @@ static struct res_config adl_cfg = { static struct res_config adl_n_cfg = { .machine_check = true, .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x68, @@ -543,6 +569,10 @@ static struct res_config adl_n_cfg = { static struct res_config rpl_p_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x68, @@ -555,6 +585,10 @@ static struct res_config rpl_p_cfg = { static struct res_config mtl_ps_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x170, @@ -566,6 +600,10 @@ static struct res_config mtl_ps_cfg = { static struct res_config mtl_p_cfg = { .machine_check = true, .num_imc = 2, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x170, @@ -577,6 +615,10 @@ static struct res_config mtl_p_cfg = { static struct res_config wcl_cfg = { .machine_check = true, .num_imc = 1, + .reg_mchbar_mask = GENMASK_ULL(41, 17), + .reg_tom_mask = GENMASK_ULL(41, 20), + .reg_touud_mask = GENMASK_ULL(41, 20), + .reg_eccerrlog_addr_mask = GENMASK_ULL(38, 5), .imc_base = 0xd800, .ibecc_base = 0xd400, .ibecc_error_log_offset = 0x170, @@ -908,8 +950,8 @@ static void ecclog_work_cb(struct work_struct *work) if (res_cfg->err_addr) eaddr = res_cfg->err_addr(node->ecclog); else - eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << - ECC_ERROR_LOG_ADDR_SHIFT; + eaddr = node->ecclog & res_cfg->reg_eccerrlog_addr_mask; + res.mc = node->mc; res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc); res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc); @@ -1129,8 +1171,7 @@ static int debugfs_u64_set(void *data, u64 val) pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val); - val >>= ECC_ERROR_LOG_ADDR_SHIFT; - ecclog = (val << ECC_ERROR_LOG_ADDR_SHIFT) | ECC_ERROR_LOG_CE; + ecclog = (val & res_cfg->reg_eccerrlog_addr_mask) | ECC_ERROR_LOG_CE; if (!ecclog_gen_pool_add(0, ecclog)) irq_work_queue(&ecclog_irq_work); @@ -1196,7 +1237,7 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar) goto fail; } - igen6_tom = u.v & GENMASK_ULL(38, 20); + igen6_tom = u.v & res_cfg->reg_tom_mask; if (get_mchbar(pdev, mchbar)) goto fail; @@ -1207,7 +1248,7 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar) else if (pci_read_config_dword(pdev, TOUUD_OFFSET + 4, &u.v_hi)) edac_dbg(2, "Failed to read upper TOUUD\n"); else - igen6_touud = u.v & GENMASK_ULL(38, 20); + igen6_touud = u.v & res_cfg->reg_touud_mask; #endif return 0; -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support 2025-12-19 4:29 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo 2025-12-19 4:29 ` [PATCH v2 1/2] EDAC/igen6: " Qiuxu Zhuo 2025-12-19 4:29 ` [PATCH v2 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo @ 2025-12-19 21:51 ` Luck, Tony 2 siblings, 0 replies; 9+ messages in thread From: Luck, Tony @ 2025-12-19 21:51 UTC (permalink / raw) To: Qiuxu Zhuo; +Cc: bp, jianfeng.gao, linux-edac, linux-kernel, yi1.lai On Fri, Dec 19, 2025 at 12:29:54PM +0800, Qiuxu Zhuo wrote: > Changes in v2: > > - Patch 1: No changes. > - Patch 2: Remove local field_get() definition. > > Patch 1: Add IBECC EDAC support for another two Intel Amston Lake SoCs. > Patch 2: Configure masks of four memory controller registers properly. > > Qiuxu Zhuo (2): > EDAC/igen6: Add two Intel Amston Lake SoCs support > EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable > > drivers/edac/igen6_edac.c | 69 ++++++++++++++++++++++++++++++++------- > 1 file changed, 57 insertions(+), 12 deletions(-) Applied. Thanks. -Tony ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-12-19 21:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-24 6:54 [PATCH 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo
2025-11-24 6:54 ` [PATCH 1/2] EDAC/igen6: " Qiuxu Zhuo
2025-11-24 6:54 ` [PATCH 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo
2025-12-17 18:19 ` Luck, Tony
2025-12-18 0:44 ` Zhuo, Qiuxu
2025-12-19 4:29 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Qiuxu Zhuo
2025-12-19 4:29 ` [PATCH v2 1/2] EDAC/igen6: " Qiuxu Zhuo
2025-12-19 4:29 ` [PATCH v2 2/2] EDAC/igen6: Make masks of {MCHBAR, TOM, TOUUD, ECC_ERROR_LOG} configurable Qiuxu Zhuo
2025-12-19 21:51 ` [PATCH v2 0/2] EDAC: Add two Intel Amston Lake SoCs support Luck, Tony
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox