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