From dc156adf0d1b9d9ea54a86ca803ac5202ab139c7 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 4 Apr 2014 12:38:26 +0800 Subject: ACPICA: Tables: Fix the issues in handling virtual addressed tables. When table is overridden or reloaded, acpi_tb_delete_table() is called where struct acpi_table_desc.Pointer will be NULL. It thus is impossible for virtual addressed tables to obtain the .Pointer again in acpi_tb_verify_table(). This patch stores virtual table addresses (ACPI_TABLE_ORIGIN_ALLOCATED, ACPI_TABLE_ORIGIN_UNKNOWN, ACPI_TABLE_ORIGIN_OVERRIDE) in the struct acpi_table_desc.Address field and refills the struct acpi_table_desc.Pointer using these addresses in acpi_tb_verify_table(). Note that if a table with ACPI_TABLE_ORIGIN_ALLOCATED set is actually freed, the .Address field should be invalidated and thus must be replaced with NULL to avoid wrong future validations occuring in acpi_tb_verify_table(). Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/tbinstal.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers/acpi/acpica/tbinstal.c') diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 73fffb0f3dd3..144076ac21f0 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -69,11 +69,26 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) /* Map the table if necessary */ if (!table_desc->pointer) { - if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) { + switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { + case ACPI_TABLE_ORIGIN_MAPPED: + table_desc->pointer = acpi_os_map_memory(table_desc->address, table_desc->length); + break; + + case ACPI_TABLE_ORIGIN_ALLOCATED: + case ACPI_TABLE_ORIGIN_UNKNOWN: + case ACPI_TABLE_ORIGIN_OVERRIDE: + + table_desc->pointer = + ACPI_CAST_PTR(struct acpi_table_header, + table_desc->address); + break; + + default: + + break; } if (!table_desc->pointer) { @@ -476,6 +491,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc) case ACPI_TABLE_ORIGIN_ALLOCATED: ACPI_FREE(table_desc->pointer); + table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); break; /* Not mapped or allocated, there is nothing we can do */ -- cgit v1.2.3