deferred interrupts should be the highest priority in the system

Signed-off-by: Gregory Haskins <[EMAIL PROTECTED]>
---

 drivers/kvm/kvm.h |   24 +++++-------------------
 drivers/kvm/svm.c |   19 +++++++++++++++----
 drivers/kvm/vmx.c |   19 +++++++++++++++----
 3 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 62c4c4d..59e6c74 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -168,6 +168,7 @@ typedef enum {
        kvm_cpuirq_extint,
        kvm_cpuirq_smi,
        kvm_cpuirq_nmi,
+       kvm_cpuirq_deferred,
        kvm_cpuirq_invalid, /* must always be last */
 } kvm_cpuirq_t;
 
@@ -473,12 +474,7 @@ struct kvm_vcpu {
  */
 static inline int __kvm_vcpu_irq_pending(struct kvm_vcpu *vcpu)
 {
-       int pending = vcpu->irq.pending;
-
-       if (vcpu->irq.deferred != -1)
-               __set_bit(kvm_cpuirq_localint, &pending);
-
-       return pending;
+       return vcpu->irq.pending;
 }
 
 static inline int kvm_vcpu_irq_pending(struct kvm_vcpu *vcpu)
@@ -499,24 +495,13 @@ static inline int kvm_vcpu_irq_pending(struct kvm_vcpu 
*vcpu)
 static inline int kvm_vcpu_irq_pop(struct kvm_vcpu *vcpu,
                                   struct kvm_irqack_data *data)
 {
-       int ret = 0;
-
        if (vcpu->irq.deferred != -1) {
-               ret = kvm_irqdevice_ack(&vcpu->irq.dev, KVM_IRQACK_FLAG_PEEK,
-                                       data);
                data->flags |= KVM_IRQACKDATA_VECTOR_VALID;
                data->vector = vcpu->irq.deferred;
                vcpu->irq.deferred = -1;
-       } else
-               ret = kvm_irqdevice_ack(&vcpu->irq.dev, 0, data);
+       }
 
-       /*
-        * If there are no more interrupts we must clear the status flag
-        */
-       if (!(data->flags & KVM_IRQACKDATA_VECTOR_PENDING))
-               __clear_bit(kvm_cpuirq_localint, &vcpu->irq.pending);
-
-       return ret;
+       return 0;
 }
 
 static inline void __kvm_vcpu_irq_push(struct kvm_vcpu *vcpu, int irq)
@@ -524,6 +509,7 @@ static inline void __kvm_vcpu_irq_push(struct kvm_vcpu 
*vcpu, int irq)
        BUG_ON(vcpu->irq.deferred != -1); /* We can only hold one deferred */
 
        vcpu->irq.deferred = irq;
+       __set_bit(kvm_cpuirq_deferred, &vcpu->irq.pending);
 }
 
 static inline void kvm_vcpu_irq_push(struct kvm_vcpu *vcpu, int irq)
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 02854f4..2128f38 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1399,12 +1399,10 @@ static void do_intr_requests(struct kvm_vcpu *vcpu,
 
                switch (pin) {
                case kvm_cpuirq_localint:
-                       r = kvm_vcpu_irq_pop(vcpu, &ack);
+                       r = kvm_irqdevice_ack(&vcpu->irq.dev, 0, &ack);
                        break;
                case kvm_cpuirq_extint:
                        r = kvm_irqdevice_ack(&vcpu->kvm->isa_irq, 0, &ack);
-                       if (!(ack.flags & KVM_IRQACKDATA_VECTOR_PENDING))
-                               __clear_bit(pin, &vcpu->irq.pending);
                        break;
                case kvm_cpuirq_nmi:
                        /*
@@ -1414,7 +1412,9 @@ static void do_intr_requests(struct kvm_vcpu *vcpu,
                         */
                        ack.flags |= KVM_IRQACKDATA_VECTOR_VALID;
                        ack.vector = 2;
-                       __clear_bit(pin, &vcpu->irq.pending);
+                       break;
+               case kvm_cpuirq_deferred:
+                       r = kvm_vcpu_irq_pop(vcpu, &ack);
                        break;
                default:
                        panic("KVM: unknown interrupt pin raised: %d\n", pin);
@@ -1423,6 +1423,9 @@ static void do_intr_requests(struct kvm_vcpu *vcpu,
 
                BUG_ON(r < 0);
 
+               if (!(ack.flags & KVM_IRQACKDATA_VECTOR_PENDING))
+                       __clear_bit(pin, &vcpu->irq.pending);
+
                if (ack.flags & KVM_IRQACKDATA_VECTOR_VALID) {
                        control = &vcpu->svm->vmcb->control;
 #if 0
@@ -1485,6 +1488,14 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
                        printk(KERN_WARNING "KVM: dropping unhandled SMI\n");
                        __clear_bit(pin, &vcpu->irq.pending);
                        break;
+               case kvm_cpuirq_deferred:
+                       do_intr_requests(vcpu, kvm_run, pin);
+                       /*
+                        * We dont allow any more injections to occur if we
+                        * have a deferred interrupt
+                        */
+                       pending = 0;
+                       break;
                case kvm_cpuirq_invalid:
                        /* drop */
                        break;
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 62db2e0..144acf5 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1511,12 +1511,10 @@ static void do_intr_requests(struct kvm_vcpu *vcpu,
 
                switch (pin) {
                case kvm_cpuirq_localint:
-                       r = kvm_vcpu_irq_pop(vcpu, &ack);
+                       r = kvm_irqdevice_ack(&vcpu->irq.dev, 0, &ack);
                        break;
                case kvm_cpuirq_extint:
                        r = kvm_irqdevice_ack(&vcpu->kvm->isa_irq, 0, &ack);
-                       if (!(ack.flags & KVM_IRQACKDATA_VECTOR_PENDING))
-                               __clear_bit(pin, &vcpu->irq.pending);
                        break;
                case kvm_cpuirq_nmi:
                        /*
@@ -1528,7 +1526,9 @@ static void do_intr_requests(struct kvm_vcpu *vcpu,
                         */
                        ack.flags |= KVM_IRQACKDATA_VECTOR_VALID;
                        ack.vector = 2;
-                       __clear_bit(pin, &vcpu->irq.pending);
+                       break;
+               case kvm_cpuirq_deferred:
+                       r = kvm_vcpu_irq_pop(vcpu, &ack);
                        break;
                default:
                        panic("KVM: unknown interrupt pin raised: %d\n", pin);
@@ -1537,6 +1537,9 @@ static void do_intr_requests(struct kvm_vcpu *vcpu,
 
                BUG_ON(r < 0);
 
+               if (!(ack.flags & KVM_IRQACKDATA_VECTOR_PENDING))
+                       __clear_bit(pin, &vcpu->irq.pending);
+
                if (ack.flags & KVM_IRQACKDATA_VECTOR_VALID) {
                        if (vcpu->rmode.active)
                                inject_rmode_irq(vcpu, ack.vector);
@@ -1608,6 +1611,14 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
                        else
                                do_intr_requests(vcpu, kvm_run, pin);
                        break;
+               case kvm_cpuirq_deferred:
+                       do_intr_requests(vcpu, kvm_run, pin);
+                       /*
+                        * We dont allow any more injections to occur if we
+                        * have a deferred interrupt
+                        */
+                       pending = 0;
+                       break;
                case kvm_cpuirq_invalid:
                        /* drop */
                        break;


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to