# 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
|