aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/apic.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-11-23 06:58:19 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-11-23 06:58:19 +0000
commit3cfaf63e09773f7046e35b9287a94323840fcacf (patch)
tree76bfa9dccf98f8a18ed1f1ffd824918684ed8e78 /xen/arch/x86/apic.c
parentf38d55cb34b5c5853bb5b5c21537df6c68071876 (diff)
downloadxen-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.c25
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);
/*