diff options
| author | Liu Jinsong <jinsong.liu@intel.com> | 2013-02-16 03:59:03 -0500 |
|---|---|---|
| committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-02-25 07:44:21 -0500 |
| commit | 484400ffbf2dd33446d71c05b9cddf91932a882e (patch) | |
| tree | bb4d4650a246dadebe0eec93fac459876d67de46 | |
| parent | 77be36de8b07027a70fbc8f02703ccd76cd16d09 (diff) | |
xen/acpi: xen memory hotplug minor updates
Dan Carpenter found current xen memory hotplug logic
has potential issue: at func acpi_memory_get_device()
*mem_device = acpi_driver_data(device);
while the device may be NULL and then dereference.
At native side, Rafael recently updated acpi_memory_get_device(),
dropping acpi_bus_add, adding lock, and avoiding above issue.
This patch updates xen memory hotplug logic accordingly, removing
redundant logic, adding lock, and avoiding dereference.
Signed-off-by: Liu Jinsong <jinsong.liu@intel.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
| -rw-r--r-- | drivers/xen/xen-acpi-memhotplug.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/drivers/xen/xen-acpi-memhotplug.c b/drivers/xen/xen-acpi-memhotplug.c index 853b12dba5bb..faef5b396051 100644 --- a/drivers/xen/xen-acpi-memhotplug.c +++ b/drivers/xen/xen-acpi-memhotplug.c | |||
| @@ -158,31 +158,17 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) | |||
| 158 | return 0; | 158 | return 0; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | static int | 161 | static int acpi_memory_get_device(acpi_handle handle, |
| 162 | acpi_memory_get_device(acpi_handle handle, | 162 | struct acpi_memory_device **mem_device) |
| 163 | struct acpi_memory_device **mem_device) | ||
| 164 | { | 163 | { |
| 165 | acpi_status status; | ||
| 166 | acpi_handle phandle; | ||
| 167 | struct acpi_device *device = NULL; | 164 | struct acpi_device *device = NULL; |
| 168 | struct acpi_device *pdevice = NULL; | 165 | int result = 0; |
| 169 | int result; | ||
| 170 | 166 | ||
| 171 | if (!acpi_bus_get_device(handle, &device) && device) | 167 | acpi_scan_lock_acquire(); |
| 172 | goto end; | ||
| 173 | 168 | ||
| 174 | status = acpi_get_parent(handle, &phandle); | 169 | acpi_bus_get_device(handle, &device); |
| 175 | if (ACPI_FAILURE(status)) { | 170 | if (device) |
| 176 | pr_warn(PREFIX "Cannot find acpi parent\n"); | 171 | goto end; |
| 177 | return -EINVAL; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* Get the parent device */ | ||
| 181 | result = acpi_bus_get_device(phandle, &pdevice); | ||
| 182 | if (result) { | ||
| 183 | pr_warn(PREFIX "Cannot get acpi bus device\n"); | ||
| 184 | return -EINVAL; | ||
| 185 | } | ||
| 186 | 172 | ||
| 187 | /* | 173 | /* |
| 188 | * Now add the notified device. This creates the acpi_device | 174 | * Now add the notified device. This creates the acpi_device |
| @@ -190,18 +176,28 @@ acpi_memory_get_device(acpi_handle handle, | |||
| 190 | */ | 176 | */ |
| 191 | result = acpi_bus_scan(handle); | 177 | result = acpi_bus_scan(handle); |
| 192 | if (result) { | 178 | if (result) { |
| 193 | pr_warn(PREFIX "Cannot add acpi bus\n"); | 179 | pr_warn(PREFIX "ACPI namespace scan failed\n"); |
| 194 | return -EINVAL; | 180 | result = -EINVAL; |
| 181 | goto out; | ||
| 182 | } | ||
| 183 | result = acpi_bus_get_device(handle, &device); | ||
| 184 | if (result) { | ||
| 185 | pr_warn(PREFIX "Missing device object\n"); | ||
| 186 | result = -EINVAL; | ||
| 187 | goto out; | ||
| 195 | } | 188 | } |
| 196 | 189 | ||
| 197 | end: | 190 | end: |
| 198 | *mem_device = acpi_driver_data(device); | 191 | *mem_device = acpi_driver_data(device); |
| 199 | if (!(*mem_device)) { | 192 | if (!(*mem_device)) { |
| 200 | pr_err(PREFIX "Driver data not found\n"); | 193 | pr_err(PREFIX "driver data not found\n"); |
| 201 | return -ENODEV; | 194 | result = -ENODEV; |
| 195 | goto out; | ||
| 202 | } | 196 | } |
| 203 | 197 | ||
| 204 | return 0; | 198 | out: |
| 199 | acpi_scan_lock_release(); | ||
| 200 | return result; | ||
| 205 | } | 201 | } |
| 206 | 202 | ||
| 207 | static int acpi_memory_check_device(struct acpi_memory_device *mem_device) | 203 | static int acpi_memory_check_device(struct acpi_memory_device *mem_device) |
| @@ -259,12 +255,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
| 259 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 255 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 260 | "\nReceived EJECT REQUEST notification for device\n")); | 256 | "\nReceived EJECT REQUEST notification for device\n")); |
| 261 | 257 | ||
| 258 | acpi_scan_lock_acquire(); | ||
| 262 | if (acpi_bus_get_device(handle, &device)) { | 259 | if (acpi_bus_get_device(handle, &device)) { |
| 260 | acpi_scan_lock_release(); | ||
| 263 | pr_err(PREFIX "Device doesn't exist\n"); | 261 | pr_err(PREFIX "Device doesn't exist\n"); |
| 264 | break; | 262 | break; |
| 265 | } | 263 | } |
| 266 | mem_device = acpi_driver_data(device); | 264 | mem_device = acpi_driver_data(device); |
| 267 | if (!mem_device) { | 265 | if (!mem_device) { |
| 266 | acpi_scan_lock_release(); | ||
| 268 | pr_err(PREFIX "Driver Data is NULL\n"); | 267 | pr_err(PREFIX "Driver Data is NULL\n"); |
| 269 | break; | 268 | break; |
| 270 | } | 269 | } |
| @@ -274,6 +273,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
| 274 | * acpi_bus_remove if Xen support hotremove in the future | 273 | * acpi_bus_remove if Xen support hotremove in the future |
| 275 | */ | 274 | */ |
| 276 | acpi_memory_disable_device(mem_device); | 275 | acpi_memory_disable_device(mem_device); |
| 276 | acpi_scan_lock_release(); | ||
| 277 | break; | 277 | break; |
| 278 | 278 | ||
| 279 | default: | 279 | default: |
