EDAC/ghes: Fix NULL pointer dereference in ghes_edac_register()
Afterb9cae27728
("EDAC/ghes: Scan the system once on driver init") and with CONFIG_DEBUG_TEST_DRIVER_REMOVE enabled, ghes_hw.dimms becomes a NULL pointer after the second ->probe() (aka ghes_edac_register()) which the config option causes to be called. This happens because the static variable which holds down whether the system has been scanned already, doesn't get reset in ghes_edac_unregister(). Then, on the second probe, ghes_scan_system() doesn't get to enumerate the DIMMs, leading to ghes_hw.dimms remaining NULL. Clear the variable and rename it to something more descriptive so that a second probe succeeds. [ bp: Rewrite commit message. ] Fixes:b9cae27728
("EDAC/ghes: Scan the system once on driver init") Suggested-by: Borislav Petkov <bp@suse.de> Signed-off-by: Shiju Jose <shiju.jose@huawei.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20200827140450.1620-1-shiju.jose@huawei.com
This commit is contained in:
parent
d012a7190f
commit
b972fdba86
@ -55,6 +55,8 @@ static DEFINE_SPINLOCK(ghes_lock);
|
|||||||
static bool __read_mostly force_load;
|
static bool __read_mostly force_load;
|
||||||
module_param(force_load, bool, 0);
|
module_param(force_load, bool, 0);
|
||||||
|
|
||||||
|
static bool system_scanned;
|
||||||
|
|
||||||
/* Memory Device - Type 17 of SMBIOS spec */
|
/* Memory Device - Type 17 of SMBIOS spec */
|
||||||
struct memdev_dmi_entry {
|
struct memdev_dmi_entry {
|
||||||
u8 type;
|
u8 type;
|
||||||
@ -225,14 +227,12 @@ static void enumerate_dimms(const struct dmi_header *dh, void *arg)
|
|||||||
|
|
||||||
static void ghes_scan_system(void)
|
static void ghes_scan_system(void)
|
||||||
{
|
{
|
||||||
static bool scanned;
|
if (system_scanned)
|
||||||
|
|
||||||
if (scanned)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dmi_walk(enumerate_dimms, &ghes_hw);
|
dmi_walk(enumerate_dimms, &ghes_hw);
|
||||||
|
|
||||||
scanned = true;
|
system_scanned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
|
void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
|
||||||
@ -631,6 +631,8 @@ void ghes_edac_unregister(struct ghes *ghes)
|
|||||||
|
|
||||||
mutex_lock(&ghes_reg_mutex);
|
mutex_lock(&ghes_reg_mutex);
|
||||||
|
|
||||||
|
system_scanned = false;
|
||||||
|
|
||||||
if (!refcount_dec_and_test(&ghes_refcount))
|
if (!refcount_dec_and_test(&ghes_refcount))
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user