Directed EOI is specified by x2APIC, but is available even when lapic is
in xAPIC mode.

Signed-off-by: Gleb Natapov <[email protected]>
---
 arch/x86/include/asm/apicdef.h |    2 ++
 arch/x86/kvm/lapic.c           |   13 ++++++++-----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 7ddb36a..74ca38f 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -14,6 +14,7 @@
 
 #define        APIC_LVR        0x30
 #define                APIC_LVR_MASK           0xFF00FF
+#define                APIC_LVR_DIRECTED_EOI   (1 << 24)
 #define                GET_APIC_VERSION(x)     ((x) & 0xFFu)
 #define                GET_APIC_MAXLVT(x)      (((x) >> 16) & 0xFFu)
 #ifdef CONFIG_X86_32
@@ -40,6 +41,7 @@
 #define                APIC_DFR_CLUSTER                0x0FFFFFFFul
 #define                APIC_DFR_FLAT                   0xFFFFFFFFul
 #define        APIC_SPIV       0xF0
+#define                APIC_SPIV_DIRECTED_EOI          (1 << 12)
 #define                APIC_SPIV_FOCUS_DISABLED        (1 << 9)
 #define                APIC_SPIV_APIC_ENABLED          (1 << 8)
 #define        APIC_ISR        0x100
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 2e02865..db0c6ae 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -54,7 +54,8 @@
 
 #define APIC_LVT_NUM                   6
 /* 14 is the version for Xeon and Pentium 8.4.8*/
-#define APIC_VERSION                   (0x14UL | ((APIC_LVT_NUM - 1) << 16))
+#define APIC_VERSION                   (0x14UL | ((APIC_LVT_NUM - 1) << 16) | \
+                                        APIC_LVR_DIRECTED_EOI)
 #define LAPIC_MMIO_LENGTH              (1 << 12)
 /* followed define is not in apicdef.h */
 #define APIC_SHORT_MASK                        0xc0000
@@ -442,9 +443,11 @@ static void apic_set_eoi(struct kvm_lapic *apic)
                trigger_mode = IOAPIC_LEVEL_TRIG;
        else
                trigger_mode = IOAPIC_EDGE_TRIG;
-       mutex_lock(&apic->vcpu->kvm->irq_lock);
-       kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
-       mutex_unlock(&apic->vcpu->kvm->irq_lock);
+       if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) {
+               mutex_lock(&apic->vcpu->kvm->irq_lock);
+               kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
+               mutex_unlock(&apic->vcpu->kvm->irq_lock);
+       }
 }
 
 static void apic_send_ipi(struct kvm_lapic *apic)
@@ -683,7 +686,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
                break;
 
        case APIC_SPIV:
-               apic_set_reg(apic, APIC_SPIV, val & 0x3ff);
+               apic_set_reg(apic, APIC_SPIV, val & 0xfff);
                if (!(val & APIC_SPIV_APIC_ENABLED)) {
                        int i;
                        u32 lvt_val;
-- 
1.6.2.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to