# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1283154652 -3600
# Node ID 9e4a0de7e8f85b59f4c731feed3952d2063a6ad2
# Parent a2eb61f077ab84cfce053c74b62e3ffb6eb665ef
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-unstable changeset: 3cee41690fa2
xen-unstable date: Fri Aug 13 14:58:06 2010 +0100
---
xen/arch/x86/apic.c | 72 ++++++++++++++-------------------
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(+), 44 deletions(-)
diff -r a2eb61f077ab -r 9e4a0de7e8f8 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c Mon Aug 30 08:47:20 2010 +0100
+++ b/xen/arch/x86/apic.c Mon Aug 30 08:50:52 2010 +0100
@@ -493,30 +493,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) )
@@ -525,6 +504,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();
@@ -740,9 +745,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;
}
@@ -1039,15 +1045,8 @@ static void enable_bsp_x2apic(void)
if ( !x2apic_preenabled )
{
- u32 lo, hi;
-
- rdmsr(MSR_IA32_APICBASE, lo, hi);
- if ( !(lo & MSR_IA32_APICBASE_EXTD) )
- {
- lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD;
- wrmsr(MSR_IA32_APICBASE, lo, 0);
- printk("x2APIC mode enabled.\n");
- }
+ __enable_x2apic();
+ printk("x2APIC mode enabled.\n");
}
restore_out:
@@ -1061,19 +1060,12 @@ out:
static void enable_ap_x2apic(void)
{
- u32 lo, hi;
-
ASSERT(smp_processor_id() != 0);
/* APs only enable x2apic when BSP did so. */
BUG_ON(!x2apic_enabled);
- rdmsr(MSR_IA32_APICBASE, lo, hi);
- if ( !(lo & MSR_IA32_APICBASE_EXTD) )
- {
- lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD;
- wrmsr(MSR_IA32_APICBASE, lo, 0);
- }
+ __enable_x2apic();
}
void enable_x2apic(void)
diff -r a2eb61f077ab -r 9e4a0de7e8f8 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c Mon Aug 30 08:47:20 2010 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c Mon Aug 30 08:50:52 2010 +0100
@@ -871,6 +871,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 a2eb61f077ab -r 9e4a0de7e8f8 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Mon Aug 30 08:47:20 2010 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c Mon Aug 30 08:50:52 2010 +0100
@@ -2122,10 +2122,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 a2eb61f077ab -r 9e4a0de7e8f8 xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h Mon Aug 30 08:47:20 2010 +0100
+++ b/xen/include/xen/iommu.h Mon Aug 30 08:50:52 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
|