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
@ -130,6 +130,8 @@ static void intel_vsec_dev_release(struct device *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);
|
||||
ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
|
||||
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;
|
||||
int ret, id;
|
||||
|
||||
mutex_lock(&vsec_ida_lock);
|
||||
ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
|
||||
mutex_unlock(&vsec_ida_lock);
|
||||
ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev,
|
||||
PMT_XA_LIMIT, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
kfree(intel_vsec_dev->resource);
|
||||
kfree(intel_vsec_dev);
|
||||
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)
|
||||
parent = &pdev->dev;
|
||||
|
||||
auxdev->id = ret;
|
||||
auxdev->id = id;
|
||||
auxdev->name = name;
|
||||
auxdev->dev.parent = parent;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC);
|
||||
|
@ -38,6 +38,7 @@ struct intel_vsec_device {
|
||||
struct ida *ida;
|
||||
struct intel_vsec_platform_info *info;
|
||||
int num_resources;
|
||||
int id; /* xa */
|
||||
void *priv_data;
|
||||
size_t priv_data_size;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user