diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-11-23 06:58:19 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-11-23 06:58:19 +0000 |
commit | 3cfaf63e09773f7046e35b9287a94323840fcacf (patch) | |
tree | 76bfa9dccf98f8a18ed1f1ffd824918684ed8e78 /xen/arch/x86/apic.c | |
parent | f38d55cb34b5c5853bb5b5c21537df6c68071876 (diff) | |
download | xen-3cfaf63e09773f7046e35b9287a94323840fcacf.tar.gz xen-3cfaf63e09773f7046e35b9287a94323840fcacf.tar.bz2 xen-3cfaf63e09773f7046e35b9287a94323840fcacf.zip |
x86: enable directed EOI
This patch enables directed EOI on latest processor. With this, the
broadcast of EOI would be suppressed upon LAPIC EOI, so VMM is
required to perform a directed EOI to the IOxAPIC generating the
interrupt by writting to its EOI register.(Pls. refer SDM 3A 10.5.5)
This is useful for ioapic_ack_old to avoid the spurious interrupt
storm, which is the reason why ioapic_ack_new is used.
Signed-Off-By: Zhai Edwin <edwin.zhai@intel.com>
Diffstat (limited to 'xen/arch/x86/apic.c')
-rw-r--r-- | xen/arch/x86/apic.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index 64be332ca6..4c4a3de0d4 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -68,6 +68,7 @@ static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enabl int apic_verbosity; int x2apic_enabled __read_mostly = 0; +int directed_eoi_enabled __read_mostly = 0; /* * The following vectors are part of the Linux architecture, there @@ -348,6 +349,7 @@ void disable_local_APIC(void) } } +extern int ioapic_ack_new; /* * This is to verify that we're looking at a real local APIC. * Check these against your board if the CPUs aren't getting @@ -388,6 +390,18 @@ int __init verify_local_APIC(void) return 0; /* + * Detecting directed EOI on BSP: + * If having directed EOI support in lapic, force to use ioapic_ack_old, + * and enable the directed EOI for intr handling. + */ + if ( reg0 & APIC_LVR_DIRECTED_EOI ) + { + ioapic_ack_new = 0; + directed_eoi_enabled = 1; + printk("Enabled directed EOI with ioapic_ack_old on!\n"); + } + + /* * The ID register is read/write in a real APIC. */ reg0 = apic_read(APIC_ID); @@ -575,6 +589,17 @@ void __devinit setup_local_APIC(void) * Set spurious IRQ vector */ value |= SPURIOUS_APIC_VECTOR; + + /* + * Enable directed EOI + */ + if ( directed_eoi_enabled ) + { + value |= APIC_SPIV_DIRECTED_EOI; + apic_printk(APIC_VERBOSE, "Suppress EOI broadcast on CPU#%d\n", + smp_processor_id()); + } + apic_write_around(APIC_SPIV, value); /* |