aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/acpi
diff options
context:
space:
mode:
authorTomasz Wroblewski <tomasz.wroblewski@citrix.com>2013-01-23 10:31:04 +0100
committerTomasz Wroblewski <tomasz.wroblewski@citrix.com>2013-01-23 10:31:04 +0100
commit529d5731e40e179e396397c633e10316a850044e (patch)
tree11e8507629429669ee00f8f4e93af056dfc15c50 /xen/drivers/acpi
parent00b70689c193b9cccb1fac3c3764bed77e152c4e (diff)
downloadxen-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.c48
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;
+}