Commit bc9ffce2 authored by Myron Stowe's avatar Myron Stowe Committed by Len Brown

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: default avatarMyron Stowe <myron.stowe@redhat.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 4134b8c8
...@@ -166,17 +166,21 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) ...@@ -166,17 +166,21 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
return supported; return supported;
} }
static void __init acpi_request_region (struct acpi_generic_address *addr, static void __init acpi_request_region (struct acpi_generic_address *gas,
unsigned int length, char *desc) unsigned int length, char *desc)
{ {
if (!addr->address || !length) u64 addr;
/* Handle possible alignment issues */
memcpy(&addr, &gas->address, sizeof(addr));
if (!addr || !length)
return; return;
/* Resources are never freed */ /* Resources are never freed */
if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
request_region(addr->address, length, desc); request_region(addr, length, desc);
else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
request_mem_region(addr->address, length, desc); request_mem_region(addr, length, desc);
} }
static int __init acpi_reserve_resources(void) 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,35 +431,41 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
__acpi_unmap_table(virt, size); __acpi_unmap_table(virt, size);
} }
static int acpi_os_map_generic_address(struct acpi_generic_address *addr) static int acpi_os_map_generic_address(struct acpi_generic_address *gas)
{ {
u64 addr;
void __iomem *virt; void __iomem *virt;
if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
return 0; return 0;
if (!addr->address || !addr->bit_width) /* Handle possible alignment issues */
memcpy(&addr, &gas->address, sizeof(addr));
if (!addr || !gas->bit_width)
return -EINVAL; return -EINVAL;
virt = acpi_os_map_memory(addr->address, addr->bit_width / 8); virt = acpi_os_map_memory(addr, gas->bit_width / 8);
if (!virt) if (!virt)
return -EIO; return -EIO;
return 0; return 0;
} }
static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) static void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
{ {
u64 addr;
struct acpi_ioremap *map; struct acpi_ioremap *map;
if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
return; return;
if (!addr->address || !addr->bit_width) /* Handle possible alignment issues */
memcpy(&addr, &gas->address, sizeof(addr));
if (!addr || !gas->bit_width)
return; return;
mutex_lock(&acpi_ioremap_lock); mutex_lock(&acpi_ioremap_lock);
map = acpi_map_lookup(addr->address, addr->bit_width / 8); map = acpi_map_lookup(addr, gas->bit_width / 8);
if (!map) { if (!map) {
mutex_unlock(&acpi_ioremap_lock); mutex_unlock(&acpi_ioremap_lock);
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment