Index: hv/xen/arch/x86/apic.c
===================================================================
--- hv.orig/xen/arch/x86/apic.c
+++ hv/xen/arch/x86/apic.c
@@ -68,6 +68,7 @@ static int enable_local_apic __initdata 
 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);
 
     /*
Index: hv/xen/arch/x86/io_apic.c
===================================================================
--- hv.orig/xen/arch/x86/io_apic.c
+++ hv/xen/arch/x86/io_apic.c
@@ -197,6 +197,30 @@ static void unmask_IO_APIC_irq (unsigned
     spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
+static void __eoi_IO_APIC_irq(unsigned int irq)
+{
+    struct irq_pin_list *entry = irq_2_pin + irq;
+    unsigned int pin, vector = IO_APIC_VECTOR(irq);
+
+    for (;;) {
+        pin = entry->pin;
+        if (pin == -1)
+            break;
+        io_apic_eoi(entry->apic, vector);
+        if (!entry->next)
+            break;
+        entry = irq_2_pin + entry->next;
+    }
+}
+
+static void eoi_IO_APIC_irq(unsigned int irq)
+{
+    unsigned long flags;
+    spin_lock_irqsave(&ioapic_lock, flags);
+    __eoi_IO_APIC_irq(irq);
+    spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
 static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
 {
     struct IO_APIC_route_entry entry;
@@ -1464,7 +1488,8 @@ static void mask_and_ack_level_ioapic_ir
     if ( ioapic_ack_new )
         return;
 
-    mask_IO_APIC_irq(irq);
+    if ( !directed_eoi_enabled )
+        mask_IO_APIC_irq(irq);
 
 /*
  * It appears there is an erratum which affects at least version 0x11
@@ -1511,8 +1536,14 @@ static void end_level_ioapic_irq (unsign
 
     if ( !ioapic_ack_new )
     {
-        if ( !(irq_desc[irq].status & IRQ_DISABLED) )
+        if ( irq_desc[irq].status & IRQ_DISABLED )
+            return;
+
+        if ( directed_eoi_enabled )
+            eoi_IO_APIC_irq(irq);
+        else
             unmask_IO_APIC_irq(irq);
+
         return;
     }
 
Index: hv/xen/include/asm-x86/apic.h
===================================================================
--- hv.orig/xen/include/asm-x86/apic.h
+++ hv/xen/include/asm-x86/apic.h
@@ -23,6 +23,7 @@
 
 extern int apic_verbosity;
 extern int x2apic_enabled;
+extern int directed_eoi_enabled;
 
 extern void enable_x2apic(void);
 
Index: hv/xen/include/asm-x86/apicdef.h
===================================================================
--- hv.orig/xen/include/asm-x86/apicdef.h
+++ hv/xen/include/asm-x86/apicdef.h
@@ -16,6 +16,7 @@
 #define			SET_xAPIC_ID(x)		(((x)<<24))
 #define		APIC_LVR	0x30
 #define			APIC_LVR_MASK		0xFF00FF
+#define			APIC_LVR_DIRECTED_EOI	(1 << 24)
 #define			GET_APIC_VERSION(x)	((x)&0xFF)
 #define			GET_APIC_MAXLVT(x)	(((x)>>16)&0xFF)
 #define			APIC_INTEGRATED(x)	((x)&0xF0)
@@ -39,6 +40,7 @@
 #define		APIC_SPIV	0xF0
 #define			APIC_SPIV_FOCUS_DISABLED	(1<<9)
 #define			APIC_SPIV_APIC_ENABLED		(1<<8)
+#define			APIC_SPIV_DIRECTED_EOI		(1<<12)
 #define		APIC_ISR	0x100
 #define         APIC_ISR_NR     0x8     /* Number of 32 bit ISR registers. */
 #define		APIC_TMR	0x180
Index: hv/xen/include/asm-x86/io_apic.h
===================================================================
--- hv.orig/xen/include/asm-x86/io_apic.h
+++ hv/xen/include/asm-x86/io_apic.h
@@ -147,6 +147,11 @@ static inline void io_apic_write(unsigne
 	*(IO_APIC_BASE(apic)+4) = value;
 }
 
+static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
+{
+    *(IO_APIC_BASE(apic)+16) = vector;
+}
+
 /*
  * Re-write a value: to be used for read-modify-write
  * cycles where the read already set up the index register.
