[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.2] fix acpi_dmar_zap/reinstate() (fixes S3 regression)



commit 2ea6abb8e60cf557b20b8a9904deb73433103d9b
Author:     Tomasz Wroblewski <tomasz.wroblewski@xxxxxxxxxx>
AuthorDate: Tue Feb 12 13:41:37 2013 +0100
Commit:     Tomasz Wroblewski <tomasz.wroblewski@xxxxxxxxxx>
CommitDate: Tue Feb 12 13:41:37 2013 +0100

    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@xxxxxxxxxx>
    
    Added call to acpi_tb_verify_table(). Fixed page count passed to
    map_pages_to_xen(). Cosmetic changes.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    xen-unstable changeset: 26443:9efe4c0bf9c8
    xen-unstable date: Wed Jan 23 09:31:04 UTC 2013
---
 xen/drivers/acpi/tables/tbxface.c  |   48 ++++++++++++++++++++++++++++++++++++
 xen/drivers/passthrough/vtd/dmar.c |   13 +++++++++-
 xen/include/acpi/acpixf.h          |    3 ++
 3 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/xen/drivers/acpi/tables/tbxface.c 
b/xen/drivers/acpi/tables/tbxface.c
index df6eeba..1602bb2 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;
+}
diff --git a/xen/drivers/passthrough/vtd/dmar.c 
b/xen/drivers/passthrough/vtd/dmar.c
index 3fbc5e6..73ad1d7 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -786,7 +786,18 @@ out:
 
 int __init acpi_dmar_init(void)
 {
-    acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table);
+    acpi_physical_address dmar_addr;
+    acpi_native_uint dmar_len;
+
+    if ( ACPI_SUCCESS(acpi_get_table_phys(ACPI_SIG_DMAR, 0,
+                                          &dmar_addr, &dmar_len)) )
+    {
+        map_pages_to_xen((unsigned long)__va(dmar_addr), PFN_DOWN(dmar_addr),
+                         PFN_UP(dmar_addr + dmar_len) - PFN_DOWN(dmar_addr),
+                         PAGE_HYPERVISOR);
+        dmar_table = __va(dmar_addr);
+    }
+
     return parse_dmar_table(acpi_parse_dmar);
 }
 
diff --git a/xen/include/acpi/acpixf.h b/xen/include/acpi/acpixf.h
index cd2b4fb..7ae1f07 100644
--- a/xen/include/acpi/acpixf.h
+++ b/xen/include/acpi/acpixf.h
@@ -77,6 +77,9 @@ acpi_status
 acpi_get_table(acpi_string signature,
               acpi_native_uint instance, struct acpi_table_header **out_table);
 
+acpi_status
+acpi_get_table_phys(acpi_string signature, acpi_native_uint instance,
+                    acpi_physical_address *addr, acpi_native_uint *len);
 /*
  * Namespace and name interfaces
  */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.2

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.