EDAC/igen6: Fix NULL pointer dereference

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

authored by Qiuxu Zhuo and committed by Borislav Petkov (AMD) 88efa0de b2e673ae

+13 -11
+13 -11
drivers/edac/igen6_edac.c
··· 125 125 #define MEM_SLICE_HASH_MASK(v) (GET_BITFIELD(v, 6, 19) << 6) 126 126 #define MEM_SLICE_HASH_LSB_MASK_BIT(v) GET_BITFIELD(v, 24, 26) 127 127 128 - static const struct res_config { 128 + static struct res_config { 129 129 bool machine_check; 130 130 /* The number of present memory controllers. */ 131 131 int num_imc; ··· 479 479 return ECC_ERROR_LOG_ADDR45(ecclog); 480 480 } 481 481 482 - static const struct res_config ehl_cfg = { 482 + static struct res_config ehl_cfg = { 483 483 .num_imc = 1, 484 484 .imc_base = 0x5000, 485 485 .ibecc_base = 0xdc00, ··· 489 489 .err_addr_to_imc_addr = ehl_err_addr_to_imc_addr, 490 490 }; 491 491 492 - static const struct res_config icl_cfg = { 492 + static struct res_config icl_cfg = { 493 493 .num_imc = 1, 494 494 .imc_base = 0x5000, 495 495 .ibecc_base = 0xd800, ··· 499 499 .err_addr_to_imc_addr = ehl_err_addr_to_imc_addr, 500 500 }; 501 501 502 - static const struct res_config tgl_cfg = { 502 + static struct res_config tgl_cfg = { 503 503 .machine_check = true, 504 504 .num_imc = 2, 505 505 .imc_base = 0x5000, ··· 513 513 .err_addr_to_imc_addr = tgl_err_addr_to_imc_addr, 514 514 }; 515 515 516 - static const struct res_config adl_cfg = { 516 + static struct res_config adl_cfg = { 517 517 .machine_check = true, 518 518 .num_imc = 2, 519 519 .imc_base = 0xd800, ··· 524 524 .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, 525 525 }; 526 526 527 - static const struct res_config adl_n_cfg = { 527 + static struct res_config adl_n_cfg = { 528 528 .machine_check = true, 529 529 .num_imc = 1, 530 530 .imc_base = 0xd800, ··· 535 535 .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, 536 536 }; 537 537 538 - static const struct res_config rpl_p_cfg = { 538 + static struct res_config rpl_p_cfg = { 539 539 .machine_check = true, 540 540 .num_imc = 2, 541 541 .imc_base = 0xd800, ··· 547 547 .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, 548 548 }; 549 549 550 - static const struct res_config mtl_ps_cfg = { 550 + static struct res_config mtl_ps_cfg = { 551 551 .machine_check = true, 552 552 .num_imc = 2, 553 553 .imc_base = 0xd800, ··· 558 558 .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, 559 559 }; 560 560 561 - static const struct res_config mtl_p_cfg = { 561 + static struct res_config mtl_p_cfg = { 562 562 .machine_check = true, 563 563 .num_imc = 2, 564 564 .imc_base = 0xd800, ··· 569 569 .err_addr_to_imc_addr = adl_err_addr_to_imc_addr, 570 570 }; 571 571 572 - static const struct pci_device_id igen6_pci_tbl[] = { 572 + static struct pci_device_id igen6_pci_tbl[] = { 573 573 { PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg }, 574 574 { PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg }, 575 575 { PCI_VDEVICE(INTEL, DID_EHL_SKU7), (kernel_ulong_t)&ehl_cfg }, ··· 1350 1350 return -ENODEV; 1351 1351 } 1352 1352 1353 - if (lmc < res_cfg->num_imc) 1353 + if (lmc < res_cfg->num_imc) { 1354 1354 igen6_printk(KERN_WARNING, "Expected %d mcs, but only %d detected.", 1355 1355 res_cfg->num_imc, lmc); 1356 + res_cfg->num_imc = lmc; 1357 + } 1356 1358 1357 1359 return 0; 1358 1360