aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMyron Stowe <mstowe@redhat.com>2011-11-07 18:23:27 -0500
committerLen Brown <len.brown@intel.com>2012-01-17 04:33:40 -0500
commitbc9ffce27962c0c5fdc6adf74790ea0fcbe4a99c (patch)
tree4708702e1d6302dd8b4c16df9f44853ed2128ee1 /drivers
parent4134b8c8811f23aa8a281db50dcee64dda414736 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/osl.c38
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
169static void __init acpi_request_region (struct acpi_generic_address *addr, 169static 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
182static int __init acpi_reserve_resources(void) 186static 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
430static int acpi_os_map_generic_address(struct acpi_generic_address *addr) 434static 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
447static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) 454static 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;