Skip to content

Commit

Permalink
ACPI: Fix possible alignment issues with GAS 'address' references
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Myron Stowe authored and Len Brown committed Jan 17, 2012
1 parent 4134b8c commit bc9ffce
Showing 1 changed file with 24 additions and 14 deletions.
38 changes: 24 additions & 14 deletions drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,21 @@ static u32 acpi_osi_handler(acpi_string interface, u32 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)
{
if (!addr->address || !length)
u64 addr;

/* Handle possible alignment issues */
memcpy(&addr, &gas->address, sizeof(addr));
if (!addr || !length)
return;

/* Resources are never freed */
if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
request_region(addr->address, length, desc);
else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
request_mem_region(addr->address, length, desc);
if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
request_region(addr, length, desc);
else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
request_mem_region(addr, length, desc);
}

static int __init acpi_reserve_resources(void)
Expand Down Expand Up @@ -427,35 +431,41 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size 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;

if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
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;

virt = acpi_os_map_memory(addr->address, addr->bit_width / 8);
virt = acpi_os_map_memory(addr, gas->bit_width / 8);
if (!virt)
return -EIO;

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;

if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
return;

if (!addr->address || !addr->bit_width)
/* Handle possible alignment issues */
memcpy(&addr, &gas->address, sizeof(addr));
if (!addr || !gas->bit_width)
return;

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) {
mutex_unlock(&acpi_ioremap_lock);
return;
Expand Down

0 comments on commit bc9ffce

Please sign in to comment.