]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
vtd: Reinstate ACPI DMAR on system shutdown or S3/S4/S5.
authorKeir Fraser <keir@xen.org>
Fri, 17 Dec 2010 10:48:30 +0000 (10:48 +0000)
committerKeir Fraser <keir@xen.org>
Fri, 17 Dec 2010 10:48:30 +0000 (10:48 +0000)
Signed-off-by: Keir Fraser <keir@xen.org>
xen-unstable changeset:   22570:f2dba7ff0828
xen-unstable date:        Fri Dec 17 10:46:43 2010 +0000

xen/arch/x86/acpi/power.c
xen/arch/x86/shutdown.c
xen/arch/x86/tboot.c
xen/common/kexec.c
xen/drivers/passthrough/vtd/dmar.c
xen/include/xen/acpi.h

index e6847b3e4f3afaf6a8c3589e9e833b332e4a60cd..f9e2973bd57cff06146b526f94edc1d660fe4829 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <xen/config.h>
 #include <asm/io.h>
-#include <asm/acpi.h>
 #include <xen/acpi.h>
 #include <xen/errno.h>
 #include <xen/iocap.h>
@@ -159,6 +158,8 @@ static int enter_state(u32 state)
 
     freeze_domains();
 
+    acpi_dmar_reinstate();
+
     disable_nonboot_cpus();
     if ( num_online_cpus() != 1 )
     {
@@ -229,6 +230,7 @@ static int enter_state(u32 state)
     cpufreq_add_cpu(0);
     microcode_resume_cpu(0);
     enable_nonboot_cpus();
+    acpi_dmar_zap();
     thaw_domains();
     spin_unlock(&pm_lock);
     return error;
index 135e6ebc63216ab767111f3e85caeace4b321547..371990add6fa4e4c621c6adafda8fd998ca0b985 100644 (file)
@@ -308,6 +308,8 @@ void machine_restart(unsigned int delay_millisecs)
     console_start_sync();
     spin_debug_disable();
 
+    acpi_dmar_reinstate();
+
     local_irq_enable();
 
     /* Ensure we are the boot CPU. */
index 4e86146f7da4eae47f7360d838ba8a91e3332f60..5e50bfc4e024bb43ea396a12d40114dccff40f8b 100644 (file)
@@ -5,6 +5,7 @@
 #include <xen/sched.h>
 #include <xen/domain_page.h>
 #include <xen/iommu.h>
+#include <xen/acpi.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
 #include <asm/processor.h>
@@ -479,13 +480,7 @@ int __init tboot_parse_dmar_table(acpi_table_handler dmar_handler)
 
     /* acpi_parse_dmar() zaps APCI DMAR signature in TXT heap table */
     /* but dom0 will read real table, so must zap it there too */
-    dmar_table = NULL;
-    acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table);
-    if ( dmar_table != NULL )
-    {
-        dmar_table->signature[0] = 'X';
-        dmar_table->checksum -= 'X'-'D';
-    }
+    acpi_dmar_zap();
 
     return rc;
 }
index da508800304ac054cf4771f35ee7dffa704c39b1..768bfd34d54394614439c31f85fe4af409a5d72e 100644 (file)
@@ -109,20 +109,13 @@ crash_xen_info_t *kexec_crash_save_info(void)
     return out;
 }
 
-static int acpi_dmar_reinstate(struct acpi_table_header *table)
-{
-    table->signature[0] = 'D';
-    table->checksum += 'X'-'D';
-    return 0;
-}
-
 static void kexec_common_shutdown(void)
 {
     watchdog_disable();
     console_start_sync();
     spin_debug_disable();
     one_cpu_only();
-    acpi_table_parse(ACPI_SIG_DMAR, acpi_dmar_reinstate);
+    acpi_dmar_reinstate();
 }
 
 void kexec_crash(void)
index d8edf03e5393a5db076b3575425e6e0798f3f1a5..1c7f9f3027f97409233b29dfa7c52fcbd6fa7c5b 100644 (file)
@@ -768,3 +768,34 @@ int __init acpi_dmar_init(void)
 {
     return parse_dmar_table(acpi_parse_dmar);
 }
+
+static struct acpi_table_header *get_dmar(void)
+{
+    struct acpi_table_header *dmar_table = NULL;
+    unsigned long flags;
+
+    /* Disabling IRQs avoids cross-CPU TLB flush in map_pages_to_xen(). */
+    local_irq_save(flags);
+    acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table);
+    local_irq_restore(flags);
+
+    return dmar_table;
+}
+
+void acpi_dmar_reinstate(void)
+{
+    struct acpi_table_header *dmar_table = get_dmar();
+    if ( dmar_table == NULL )
+        return;
+    dmar_table->signature[0] = 'D';
+    dmar_table->checksum += 'X'-'D';
+}
+
+void acpi_dmar_zap(void)
+{
+    struct acpi_table_header *dmar_table = get_dmar();
+    if ( dmar_table == NULL )
+        return;
+    dmar_table->signature[0] = 'X';
+    dmar_table->checksum -= 'X'-'D';
+}
index 43b81536bf17bebf511c8b740b6045e37699a3a4..aa812d34e876c794348c0f8079a8ea2aeae78e6d 100644 (file)
@@ -421,4 +421,7 @@ extern int pnpacpi_disabled;
 
 void acpi_reboot(void);
 
+void acpi_dmar_zap(void);
+void acpi_dmar_reinstate(void);
+
 #endif /*_LINUX_ACPI_H*/