aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorJulia Lawall <Julia.Lawall@lip6.fr>2012-03-15 09:32:05 +0100
committerLen Brown <len.brown@intel.com>2012-03-30 03:30:34 -0400
commitc80f5b31f3c55a197f5323b93d1e3553429a427e (patch)
tree4cc2183ddf4ce79765bb6d02f3d6b9191f3bcbe5 /drivers/acpi
parentACPI / PM: print physical addresses consistently with other parts of kernel (diff)
downloadlinux-dev-c80f5b31f3c55a197f5323b93d1e3553429a427e.tar.xz
linux-dev-c80f5b31f3c55a197f5323b93d1e3553429a427e.zip
ACPI: processor_driver: add missing kfree
The function acpi_processor_add is stored in the ops.add field of a acpi_driver structure. This function is then called in acpi_bus_driver_init. On failure, this function clears the field device->driver_data, but does not free its contents. Thus the free has to be done by the add function. In acpi_processor_add, the corresponding value is pr. This value is currently freed on failure before storing it in device->driver_data, but not after. This free is added in the error handling code at the end of the function. The per_cpu variable processors is also cleared so that it does not refer to a dangling pointer. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Reviewed-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Acked-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_driver.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 8ae05ce18500..fce0066aa4a4 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -535,8 +535,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
return -ENOMEM;
if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
- kfree(pr);
- return -ENOMEM;
+ result = -ENOMEM;
+ goto err_free_pr;
}
pr->handle = device->handle;
@@ -576,7 +576,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
dev = get_cpu_device(pr->id);
if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
result = -EFAULT;
- goto err_free_cpumask;
+ goto err_clear_processor;
}
/*
@@ -594,9 +594,15 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
err_remove_sysfs:
sysfs_remove_link(&device->dev.kobj, "sysdev");
+err_clear_processor:
+ /*
+ * processor_device_array is not cleared to allow checks for buggy BIOS
+ */
+ per_cpu(processors, pr->id) = NULL;
err_free_cpumask:
free_cpumask_var(pr->throttling.shared_cpu_map);
-
+err_free_pr:
+ kfree(pr);
return result;
}