platform/x86/intel/vsec: Fix xa_alloc memory leak
[ Upstream commit 8cbcc1dbf8a62c730fadd60de761e0658547a589 ] Commit936874b77d("platform/x86/intel/vsec: Add PCI error recovery support to Intel PMT") added an xarray to track the list of vsec devices to be recovered after a PCI error. But it did not provide cleanup for the list leading to a memory leak that was caught by kmemleak. Do xa_alloc() before devm_add_action_or_reset() so that the list may be cleaned up with xa_erase() in the release function. Fixes:936874b77d("platform/x86/intel/vsec: Add PCI error recovery support to Intel PMT") Signed-off-by: David E. Box <david.e.box@linux.intel.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/r/20231129222132.2331261-2-david.e.box@linux.intel.com [hdegoede@redhat.com: Add missing xa_erase() on error-exit Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
0ff5cd92bb
commit
426710a2bc
2 changed files with 16 additions and 10 deletions
|
|
@ -130,6 +130,8 @@ static void intel_vsec_dev_release(struct device *dev)
|
||||||
{
|
{
|
||||||
struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev);
|
struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev);
|
||||||
|
|
||||||
|
xa_erase(&auxdev_array, intel_vsec_dev->id);
|
||||||
|
|
||||||
mutex_lock(&vsec_ida_lock);
|
mutex_lock(&vsec_ida_lock);
|
||||||
ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
|
ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
|
||||||
mutex_unlock(&vsec_ida_lock);
|
mutex_unlock(&vsec_ida_lock);
|
||||||
|
|
@ -145,19 +147,28 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
|
||||||
struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev;
|
struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev;
|
||||||
int ret, id;
|
int ret, id;
|
||||||
|
|
||||||
mutex_lock(&vsec_ida_lock);
|
ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev,
|
||||||
ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
|
PMT_XA_LIMIT, GFP_KERNEL);
|
||||||
mutex_unlock(&vsec_ida_lock);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kfree(intel_vsec_dev->resource);
|
kfree(intel_vsec_dev->resource);
|
||||||
kfree(intel_vsec_dev);
|
kfree(intel_vsec_dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&vsec_ida_lock);
|
||||||
|
id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
|
||||||
|
mutex_unlock(&vsec_ida_lock);
|
||||||
|
if (id < 0) {
|
||||||
|
xa_erase(&auxdev_array, intel_vsec_dev->id);
|
||||||
|
kfree(intel_vsec_dev->resource);
|
||||||
|
kfree(intel_vsec_dev);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
parent = &pdev->dev;
|
parent = &pdev->dev;
|
||||||
|
|
||||||
auxdev->id = ret;
|
auxdev->id = id;
|
||||||
auxdev->name = name;
|
auxdev->name = name;
|
||||||
auxdev->dev.parent = parent;
|
auxdev->dev.parent = parent;
|
||||||
auxdev->dev.release = intel_vsec_dev_release;
|
auxdev->dev.release = intel_vsec_dev_release;
|
||||||
|
|
@ -183,12 +194,6 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Add auxdev to list */
|
|
||||||
ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC);
|
EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC);
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ struct intel_vsec_device {
|
||||||
struct ida *ida;
|
struct ida *ida;
|
||||||
struct intel_vsec_platform_info *info;
|
struct intel_vsec_platform_info *info;
|
||||||
int num_resources;
|
int num_resources;
|
||||||
|
int id; /* xa */
|
||||||
void *priv_data;
|
void *priv_data;
|
||||||
size_t priv_data_size;
|
size_t priv_data_size;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue