diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-08-13 14:58:06 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-08-13 14:58:06 +0100 |
commit | 88616ac08c303ae20a55fcd8f6e2882af9e43175 (patch) | |
tree | 585f9411087890e001ed49ee54fadf96c52b8bfa /xen/arch/x86/apic.c | |
parent | 01420271f83ad1ef64194bb022954ee443995b34 (diff) | |
download | xen-88616ac08c303ae20a55fcd8f6e2882af9e43175.tar.gz xen-88616ac08c303ae20a55fcd8f6e2882af9e43175.tar.bz2 xen-88616ac08c303ae20a55fcd8f6e2882af9e43175.zip |
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@intel.com>
Diffstat (limited to 'xen/arch/x86/apic.c')
-rw-r--r-- | xen/arch/x86/apic.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index 844f46ff01..ff8198d7a0 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -492,9 +492,21 @@ 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; + + 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); + } +} + +static void resume_x2apic(void) +{ struct IO_APIC_route_entry **ioapic_entries = NULL; ASSERT(x2apic_enabled); @@ -516,14 +528,7 @@ static void resume_x2apic(void) mask_IO_APIC_setup(ioapic_entries); iommu_enable_IR(); - - 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(); 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) |