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

[Xen-changelog] [xen-unstable] x2APIC: Improve x2APIC suspend/resume



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1281707886 -3600
# Node ID 3cee41690fa26853acb0be65065c52f6029ca599
# Parent  01d185dab39e9be399b203bec91870e04f576c23
x2APIC: Improve x2APIC suspend/resume

x2apic depends on interrupt remapping, so it should disable interrupt
remapping behind x2apic disabling. And also this patch wraps
__enable_x2apic to get rid of duplicated code.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/arch/x86/apic.c                    |   74 ++++++++++++++-------------------
 xen/drivers/passthrough/vtd/intremap.c |   18 ++++++++
 xen/drivers/passthrough/vtd/iommu.c    |    9 ++--
 xen/include/xen/iommu.h                |    1 
 4 files changed, 56 insertions(+), 46 deletions(-)

diff -r 01d185dab39e -r 3cee41690fa2 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Fri Aug 13 14:57:35 2010 +0100
+++ b/xen/arch/x86/apic.c       Fri Aug 13 14:58:06 2010 +0100
@@ -492,30 +492,9 @@ static void apic_pm_activate(void)
     apic_pm_state.active = 1;
 }
 
-static void resume_x2apic(void)
+static void __enable_x2apic(void)
 {
     uint64_t msr_content;
-    struct IO_APIC_route_entry **ioapic_entries = NULL;
-
-    ASSERT(x2apic_enabled);
-
-    ioapic_entries = alloc_ioapic_entries();
-    if ( !ioapic_entries )
-    {
-        printk("Allocate ioapic_entries failed\n");
-        goto out;
-    }
-
-    if ( save_IO_APIC_setup(ioapic_entries) )
-    {
-        printk("Saving IO-APIC state failed\n");
-        goto out;
-    }
-
-    mask_8259A();
-    mask_IO_APIC_setup(ioapic_entries);
-
-    iommu_enable_IR();
 
     rdmsrl(MSR_IA32_APICBASE, msr_content);
     if ( !(msr_content & MSR_IA32_APICBASE_EXTD) )
@@ -524,6 +503,32 @@ static void resume_x2apic(void)
         msr_content = (uint32_t)msr_content;
         wrmsrl(MSR_IA32_APICBASE, msr_content);
     }
+}
+
+static void resume_x2apic(void)
+{
+    struct IO_APIC_route_entry **ioapic_entries = NULL;
+
+    ASSERT(x2apic_enabled);
+
+    ioapic_entries = alloc_ioapic_entries();
+    if ( !ioapic_entries )
+    {
+        printk("Allocate ioapic_entries failed\n");
+        goto out;
+    }
+
+    if ( save_IO_APIC_setup(ioapic_entries) )
+    {
+        printk("Saving IO-APIC state failed\n");
+        goto out;
+    }
+
+    mask_8259A();
+    mask_IO_APIC_setup(ioapic_entries);
+
+    iommu_enable_IR();
+    __enable_x2apic();
 
     restore_IO_APIC_setup(ioapic_entries);
     unmask_8259A();
@@ -739,9 +744,10 @@ int lapic_suspend(void)
     apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
     apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
     apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
-    
+
     local_irq_save(flags);
     disable_local_APIC();
+    iommu_disable_IR();
     local_irq_restore(flags);
     return 0;
 }
@@ -1041,16 +1047,8 @@ static void enable_bsp_x2apic(void)
 
     if ( !x2apic_preenabled )
     {
-        uint64_t msr_content;
-        rdmsrl(MSR_IA32_APICBASE, msr_content);
-        if ( !(msr_content & MSR_IA32_APICBASE_EXTD) )
-        {
-            msr_content |= MSR_IA32_APICBASE_ENABLE |
-                           MSR_IA32_APICBASE_EXTD;
-            msr_content = (uint32_t)msr_content;
-            wrmsrl(MSR_IA32_APICBASE, msr_content);
-            printk("x2APIC mode enabled.\n");
-        }
+        __enable_x2apic();
+        printk("x2APIC mode enabled.\n");
     }
 
 restore_out:
@@ -1064,20 +1062,12 @@ out:
 
 static void enable_ap_x2apic(void)
 {
-    uint64_t msr_content;
-
     ASSERT(smp_processor_id() != 0);
 
     /* APs only enable x2apic when BSP did so. */
     BUG_ON(!x2apic_enabled);
 
-    rdmsrl(MSR_IA32_APICBASE, msr_content);
-    if ( !(msr_content & MSR_IA32_APICBASE_EXTD) )
-    {
-        msr_content |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD;
-        msr_content = (uint32_t)msr_content;
-        wrmsrl(MSR_IA32_APICBASE, msr_content);
-    }
+    __enable_x2apic();
 }
 
 void enable_x2apic(void)
diff -r 01d185dab39e -r 3cee41690fa2 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Fri Aug 13 14:57:35 2010 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Fri Aug 13 14:58:06 2010 +0100
@@ -873,6 +873,24 @@ int iommu_enable_IR(void)
 }
 
 /*
+ * This function is used to disable Interrutp remapping when
+ * suspend local apic
+ */
+void iommu_disable_IR(void)
+{
+    struct acpi_drhd_unit *drhd;
+
+    if ( !iommu_supports_eim() )
+        return;
+
+    for_each_drhd_unit ( drhd )
+        disable_intremap(drhd->iommu);
+
+    for_each_drhd_unit ( drhd )
+        disable_qinval(drhd->iommu);
+}
+
+/*
  * Check if interrupt remapping is enabled or not
  * return 1: enabled
  * return 0: not enabled
diff -r 01d185dab39e -r 3cee41690fa2 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Fri Aug 13 14:57:35 2010 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Fri Aug 13 14:58:06 2010 +0100
@@ -2127,10 +2127,11 @@ static void vtd_suspend(void)
 
         iommu_disable_translation(iommu);
 
-        if ( iommu_intremap )
-            disable_intremap(iommu);
-
-        if ( iommu_qinval )
+        /* If interrupt remapping is enabled, queued invalidation
+         * will be disabled following interupt remapping disabling
+         * in local apic suspend
+         */
+        if ( !iommu_intremap && iommu_qinval )
             disable_qinval(iommu);
     }
 }
diff -r 01d185dab39e -r 3cee41690fa2 xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h   Fri Aug 13 14:57:35 2010 +0100
+++ b/xen/include/xen/iommu.h   Fri Aug 13 14:58:06 2010 +0100
@@ -59,6 +59,7 @@ int iommu_setup(void);
 int iommu_setup(void);
 int iommu_supports_eim(void);
 int iommu_enable_IR(void);
+void iommu_disable_IR(void);
 int intremap_enabled(void);
 
 int iommu_add_device(struct pci_dev *pdev);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.