diff options
author | Tomasz Wroblewski <tomasz.wroblewski@citrix.com> | 2013-01-23 10:31:04 +0100 |
---|---|---|
committer | Tomasz Wroblewski <tomasz.wroblewski@citrix.com> | 2013-01-23 10:31:04 +0100 |
commit | 529d5731e40e179e396397c633e10316a850044e (patch) | |
tree | 11e8507629429669ee00f8f4e93af056dfc15c50 /xen/drivers/acpi | |
parent | 00b70689c193b9cccb1fac3c3764bed77e152c4e (diff) | |
download | xen-529d5731e40e179e396397c633e10316a850044e.tar.gz xen-529d5731e40e179e396397c633e10316a850044e.tar.bz2 xen-529d5731e40e179e396397c633e10316a850044e.zip |
fix acpi_dmar_zap/reinstate() (fixes S3 regression)
Fix S3 regression introduced by cs 23013:65d26504e843 (ACPI: large
cleanup). The dmar virtual pointer returned from acpi_get_table cannot
be safely stored away and used later, as the underlying
acpi_os_map_memory / __acpi_map_table functions overwrite the mapping
causing it to point to different tables than dmar (last fetched table is
used). This subsequently causes acpi_dmar_reinstate() and
acpi_dmar_zap() to write data to wrong table, causing its corruption and
problems with consecutive s3 resumes.
Added a new function to fetch ACPI table physical address, and
establishing separate static mapping for dmar_table pointer instead of
using acpi_get_table().
Signed-off-by: Tomasz Wroblewski <tomasz.wroblewski@citrix.com>
Added call to acpi_tb_verify_table(). Fixed page count passed to
map_pages_to_xen(). Cosmetic changes.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Committed-by: Jan Beulich <jbeulich@suse.com>
Diffstat (limited to 'xen/drivers/acpi')
-rw-r--r-- | xen/drivers/acpi/tables/tbxface.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/xen/drivers/acpi/tables/tbxface.c b/xen/drivers/acpi/tables/tbxface.c index df6eeba7e1..1602bb2837 100644 --- a/xen/drivers/acpi/tables/tbxface.c +++ b/xen/drivers/acpi/tables/tbxface.c @@ -205,3 +205,51 @@ acpi_get_table(char *signature, return (AE_NOT_FOUND); } + +/****************************************************************************** + * + * FUNCTION: acpi_get_table_phys + * + * PARAMETERS: signature - ACPI signature of needed table + * instance - Which instance (for SSDTs) + * addr - Where the table's physical address is returned + * len - Where the length of table is returned + * + * RETURN: Status, pointer and length of table + * + * DESCRIPTION: Finds physical address and length of ACPI table + * + *****************************************************************************/ +acpi_status __init +acpi_get_table_phys(acpi_string signature, acpi_native_uint instance, + acpi_physical_address *addr, acpi_native_uint *len) +{ + acpi_native_uint i, j; + acpi_status status; + + if (!signature || !addr || !len) + return AE_BAD_PARAMETER; + + for (i = j = 0; i < acpi_gbl_root_table_list.count; i++) { + if (!ACPI_COMPARE_NAME( + &acpi_gbl_root_table_list.tables[i].signature, + signature)) + continue; + + if (++j < instance) + continue; + + status = + acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); + if (ACPI_SUCCESS(status)) { + *addr = acpi_gbl_root_table_list.tables[i].address; + *len = acpi_gbl_root_table_list.tables[i].length; + } + + acpi_gbl_root_table_list.tables[i].pointer = NULL; + + return status; + } + + return AE_NOT_FOUND; +} |