6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
commit 88efa0de3285be66969b71ec137d9dab1ee19e52 upstream.
A kernel panic was reported with the following kernel log:
EDAC igen6: Expected 2 mcs, but only 1 detected. BUG: unable to handle page fault for address: 000000000000d570 ... Hardware name: Notebook V54x_6x_TU/V54x_6x_TU, BIOS Dasharo (coreboot+UEFI) v0.9.0 07/17/2024 RIP: e030:ecclog_handler+0x7e/0xf0 [igen6_edac] ... igen6_probe+0x2a0/0x343 [igen6_edac] ... igen6_init+0xc5/0xff0 [igen6_edac] ...
This issue occurred because one memory controller was disabled by the BIOS but the igen6_edac driver still checked all the memory controllers, including this absent one, to identify the source of the error. Accessing the null MMIO for the absent memory controller resulted in the oops above.
Fix this issue by reverting the configuration structure to non-const and updating the field 'res_cfg->num_imc' to reflect the number of detected memory controllers.
Fixes: 20e190b1c1fd ("EDAC/igen6: Skip absent memory controllers") Reported-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Closes: https://lore.kernel.org/all/aFFN7RlXkaK_loQb@mail-itl/ Suggested-by: Borislav Petkov bp@alien8.de Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Tony Luck tony.luck@intel.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Tested-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Link: https://lore.kernel.org/r/20250618162307.1523736-1-qiuxu.zhuo@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/edac/igen6_edac.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
--- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -125,7 +125,7 @@ #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)
-static const struct res_config { +static struct res_config { bool machine_check; /* The number of present memory controllers. */ int num_imc; @@ -473,7 +473,7 @@ static u64 rpl_p_err_addr(u64 ecclog) return ECC_ERROR_LOG_ADDR45(ecclog); }
-static const struct res_config ehl_cfg = { +static struct res_config ehl_cfg = { .num_imc = 1, .imc_base = 0x5000, .ibecc_base = 0xdc00, @@ -483,7 +483,7 @@ static const struct res_config ehl_cfg = .err_addr_to_imc_addr = ehl_err_addr_to_imc_addr, };
-static const struct res_config icl_cfg = { +static struct res_config icl_cfg = { .num_imc = 1, .imc_base = 0x5000, .ibecc_base = 0xd800, @@ -493,7 +493,7 @@ static const struct res_config icl_cfg = .err_addr_to_imc_addr = ehl_err_addr_to_imc_addr, };
-static const struct res_config tgl_cfg = { +static struct res_config tgl_cfg = { .machine_check = true, .num_imc = 2, .imc_base = 0x5000, @@ -507,7 +507,7 @@ static const struct res_config tgl_cfg = .err_addr_to_imc_addr = tgl_err_addr_to_imc_addr, };
-static const struct res_config adl_cfg = { +static struct res_config adl_cfg = { .machine_check = true, .num_imc = 2, .imc_base = 0xd800, @@ -518,7 +518,7 @@ static const struct res_config adl_cfg = .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, };
-static const struct res_config adl_n_cfg = { +static struct res_config adl_n_cfg = { .machine_check = true, .num_imc = 1, .imc_base = 0xd800, @@ -529,7 +529,7 @@ static const struct res_config adl_n_cfg .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, };
-static const struct res_config rpl_p_cfg = { +static struct res_config rpl_p_cfg = { .machine_check = true, .num_imc = 2, .imc_base = 0xd800, @@ -541,7 +541,7 @@ static const struct res_config rpl_p_cfg .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, };
-static const struct res_config mtl_ps_cfg = { +static struct res_config mtl_ps_cfg = { .machine_check = true, .num_imc = 2, .imc_base = 0xd800, @@ -552,7 +552,7 @@ static const struct res_config mtl_ps_cf .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, };
-static const struct res_config mtl_p_cfg = { +static struct res_config mtl_p_cfg = { .machine_check = true, .num_imc = 2, .imc_base = 0xd800, @@ -563,7 +563,7 @@ static const struct res_config mtl_p_cfg .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, };
-static const struct pci_device_id igen6_pci_tbl[] = { +static struct pci_device_id igen6_pci_tbl[] = { { PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg }, { PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg }, { PCI_VDEVICE(INTEL, DID_EHL_SKU7), (kernel_ulong_t)&ehl_cfg }, @@ -1342,9 +1342,11 @@ static int igen6_register_mcis(struct pc return -ENODEV; }
- if (lmc < res_cfg->num_imc) + if (lmc < res_cfg->num_imc) { igen6_printk(KERN_WARNING, "Expected %d mcs, but only %d detected.", res_cfg->num_imc, lmc); + res_cfg->num_imc = lmc; + }
return 0;