Commit c73e8833 authored by Borislav Petkov's avatar Borislav Petkov

EDAC, mc: Fix locking around mc_devices list

When accessing the mc_devices list of memory controller descriptors, we
need to hold mem_ctls_mutex. This was not always the case, fix that.

Make all external callers call a version which grabs the mutex since the
last is local to edac_mc.c.
Reported-by: default avatarYazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent 90e493d7
...@@ -482,15 +482,8 @@ void edac_mc_free(struct mem_ctl_info *mci) ...@@ -482,15 +482,8 @@ void edac_mc_free(struct mem_ctl_info *mci)
} }
EXPORT_SYMBOL_GPL(edac_mc_free); EXPORT_SYMBOL_GPL(edac_mc_free);
/* Caller must hold mem_ctls_mutex */
/** static struct mem_ctl_info *__find_mci_by_dev(struct device *dev)
* find_mci_by_dev
*
* scan list of controllers looking for the one that manages
* the 'dev' device
* @dev: pointer to a struct device related with the MCI
*/
struct mem_ctl_info *find_mci_by_dev(struct device *dev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct list_head *item; struct list_head *item;
...@@ -506,6 +499,24 @@ struct mem_ctl_info *find_mci_by_dev(struct device *dev) ...@@ -506,6 +499,24 @@ struct mem_ctl_info *find_mci_by_dev(struct device *dev)
return NULL; return NULL;
} }
/**
* find_mci_by_dev
*
* scan list of controllers looking for the one that manages
* the 'dev' device
* @dev: pointer to a struct device related with the MCI
*/
struct mem_ctl_info *find_mci_by_dev(struct device *dev)
{
struct mem_ctl_info *ret;
mutex_lock(&mem_ctls_mutex);
ret = __find_mci_by_dev(dev);
mutex_unlock(&mem_ctls_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(find_mci_by_dev); EXPORT_SYMBOL_GPL(find_mci_by_dev);
/* /*
...@@ -588,7 +599,7 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci) ...@@ -588,7 +599,7 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci)
insert_before = &mc_devices; insert_before = &mc_devices;
p = find_mci_by_dev(mci->pdev); p = __find_mci_by_dev(mci->pdev);
if (unlikely(p != NULL)) if (unlikely(p != NULL))
goto fail0; goto fail0;
...@@ -640,26 +651,28 @@ static int del_mc_from_global_list(struct mem_ctl_info *mci) ...@@ -640,26 +651,28 @@ static int del_mc_from_global_list(struct mem_ctl_info *mci)
* *
* If found, return a pointer to the structure. * If found, return a pointer to the structure.
* Else return NULL. * Else return NULL.
*
* Caller must hold mem_ctls_mutex.
*/ */
struct mem_ctl_info *edac_mc_find(int idx) struct mem_ctl_info *edac_mc_find(int idx)
{ {
struct mem_ctl_info *mci = NULL;
struct list_head *item; struct list_head *item;
struct mem_ctl_info *mci;
mutex_lock(&mem_ctls_mutex);
list_for_each(item, &mc_devices) { list_for_each(item, &mc_devices) {
mci = list_entry(item, struct mem_ctl_info, link); mci = list_entry(item, struct mem_ctl_info, link);
if (mci->mc_idx >= idx) { if (mci->mc_idx >= idx) {
if (mci->mc_idx == idx) if (mci->mc_idx == idx) {
return mci; goto unlock;
}
break; break;
} }
} }
return NULL; unlock:
mutex_unlock(&mem_ctls_mutex);
return mci;
} }
EXPORT_SYMBOL(edac_mc_find); EXPORT_SYMBOL(edac_mc_find);
...@@ -779,7 +792,7 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) ...@@ -779,7 +792,7 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
mutex_lock(&mem_ctls_mutex); mutex_lock(&mem_ctls_mutex);
/* find the requested mci struct in the global list */ /* find the requested mci struct in the global list */
mci = find_mci_by_dev(dev); mci = __find_mci_by_dev(dev);
if (mci == NULL) { if (mci == NULL) {
mutex_unlock(&mem_ctls_mutex); mutex_unlock(&mem_ctls_mutex);
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment