diff options
author | Myron Stowe <mstowe@redhat.com> | 2011-11-07 18:23:27 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-01-17 04:33:40 -0500 |
commit | bc9ffce27962c0c5fdc6adf74790ea0fcbe4a99c (patch) | |
tree | 4708702e1d6302dd8b4c16df9f44853ed2128ee1 | |
parent | 4134b8c8811f23aa8a281db50dcee64dda414736 (diff) |
ACPI: Fix possible alignment issues with GAS 'address' references
Generic Address Structures (GAS) may reside within ACPI tables which
are byte aligned. This patch copies GAS 'address' references to a local
variable, which will be naturally aligned, to be used going forward.
ACPI Generic Address Structure (GAS) reference:
ACPI Specification, Revision 4.0, Section 5.2.3.1, "Generic Address
Structure"
Signed-off-by: Myron Stowe <myron.stowe@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/osl.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f31c5c5f1b7e..2e285cdbefb1 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -166,17 +166,21 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) | |||
166 | return supported; | 166 | return supported; |
167 | } | 167 | } |
168 | 168 | ||
169 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 169 | static void __init acpi_request_region (struct acpi_generic_address *gas, |
170 | unsigned int length, char *desc) | 170 | unsigned int length, char *desc) |
171 | { | 171 | { |
172 | if (!addr->address || !length) | 172 | u64 addr; |
173 | |||
174 | /* Handle possible alignment issues */ | ||
175 | memcpy(&addr, &gas->address, sizeof(addr)); | ||
176 | if (!addr || !length) | ||
173 | return; | 177 | return; |
174 | 178 | ||
175 | /* Resources are never freed */ | 179 | /* Resources are never freed */ |
176 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 180 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) |
177 | request_region(addr->address, length, desc); | 181 | request_region(addr, length, desc); |
178 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 182 | else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
179 | request_mem_region(addr->address, length, desc); | 183 | request_mem_region(addr, length, desc); |
180 | } | 184 | } |
181 | 185 | ||
182 | static int __init acpi_reserve_resources(void) | 186 | static int __init acpi_reserve_resources(void) |
@@ -427,35 +431,41 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
427 | __acpi_unmap_table(virt, size); | 431 | __acpi_unmap_table(virt, size); |
428 | } | 432 | } |
429 | 433 | ||
430 | static int acpi_os_map_generic_address(struct acpi_generic_address *addr) | 434 | static int acpi_os_map_generic_address(struct acpi_generic_address *gas) |
431 | { | 435 | { |
436 | u64 addr; | ||
432 | void __iomem *virt; | 437 | void __iomem *virt; |
433 | 438 | ||
434 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 439 | if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
435 | return 0; | 440 | return 0; |
436 | 441 | ||
437 | if (!addr->address || !addr->bit_width) | 442 | /* Handle possible alignment issues */ |
443 | memcpy(&addr, &gas->address, sizeof(addr)); | ||
444 | if (!addr || !gas->bit_width) | ||
438 | return -EINVAL; | 445 | return -EINVAL; |
439 | 446 | ||
440 | virt = acpi_os_map_memory(addr->address, addr->bit_width / 8); | 447 | virt = acpi_os_map_memory(addr, gas->bit_width / 8); |
441 | if (!virt) | 448 | if (!virt) |
442 | return -EIO; | 449 | return -EIO; |
443 | 450 | ||
444 | return 0; | 451 | return 0; |
445 | } | 452 | } |
446 | 453 | ||
447 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | 454 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) |
448 | { | 455 | { |
456 | u64 addr; | ||
449 | struct acpi_ioremap *map; | 457 | struct acpi_ioremap *map; |
450 | 458 | ||
451 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 459 | if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
452 | return; | 460 | return; |
453 | 461 | ||
454 | if (!addr->address || !addr->bit_width) | 462 | /* Handle possible alignment issues */ |
463 | memcpy(&addr, &gas->address, sizeof(addr)); | ||
464 | if (!addr || !gas->bit_width) | ||
455 | return; | 465 | return; |
456 | 466 | ||
457 | mutex_lock(&acpi_ioremap_lock); | 467 | mutex_lock(&acpi_ioremap_lock); |
458 | map = acpi_map_lookup(addr->address, addr->bit_width / 8); | 468 | map = acpi_map_lookup(addr, gas->bit_width / 8); |
459 | if (!map) { | 469 | if (!map) { |
460 | mutex_unlock(&acpi_ioremap_lock); | 470 | mutex_unlock(&acpi_ioremap_lock); |
461 | return; | 471 | return; |