]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - virt/kvm/ioapic.c
KVM: Extract core of kvm_flush_remote_tlbs/kvm_reload_remote_mmus
[linux-2.6-omap-h63xx.git] / virt / kvm / ioapic.c
index c0d22870ee9c56137583c026b06dee47c66d58d8..23b81cf242af739675f01303eabb3cebb71b09a7 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "ioapic.h"
 #include "lapic.h"
+#include "irq.h"
 
 #if 0
 #define ioapic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg)
@@ -149,10 +150,11 @@ static int ioapic_inj_irq(struct kvm_ioapic *ioapic,
 static void ioapic_inj_nmi(struct kvm_vcpu *vcpu)
 {
        kvm_inject_nmi(vcpu);
+       kvm_vcpu_kick(vcpu);
 }
 
-static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
-                                      u8 dest_mode)
+u32 kvm_ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
+                                   u8 dest_mode)
 {
        u32 mask = 0;
        int i;
@@ -206,7 +208,8 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
                     "vector=%x trig_mode=%x\n",
                     dest, dest_mode, delivery_mode, vector, trig_mode);
 
-       deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode);
+       deliver_bitmask = kvm_ioapic_get_delivery_bitmask(ioapic, dest,
+                                                         dest_mode);
        if (!deliver_bitmask) {
                ioapic_debug("no target on destination\n");
                return 0;
@@ -285,26 +288,31 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
        }
 }
 
-static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi)
+static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi,
+                                   int trigger_mode)
 {
        union ioapic_redir_entry *ent;
 
        ent = &ioapic->redirtbl[gsi];
-       ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
 
-       ent->fields.remote_irr = 0;
-       if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
-               ioapic_service(ioapic, gsi);
+       kvm_notify_acked_irq(ioapic->kvm, gsi);
+
+       if (trigger_mode == IOAPIC_LEVEL_TRIG) {
+               ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
+               ent->fields.remote_irr = 0;
+               if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
+                       ioapic_service(ioapic, gsi);
+       }
 }
 
-void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
+void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
 {
        struct kvm_ioapic *ioapic = kvm->arch.vioapic;
        int i;
 
        for (i = 0; i < IOAPIC_NUM_PINS; i++)
                if (ioapic->redirtbl[i].fields.vector == vector)
-                       __kvm_ioapic_update_eoi(ioapic, i);
+                       __kvm_ioapic_update_eoi(ioapic, i, trigger_mode);
 }
 
 static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr,
@@ -380,7 +388,7 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
                break;
 #ifdef CONFIG_IA64
        case IOAPIC_REG_EOI:
-               kvm_ioapic_update_eoi(ioapic->kvm, data);
+               kvm_ioapic_update_eoi(ioapic->kvm, data, IOAPIC_LEVEL_TRIG);
                break;
 #endif