KVM: x86: handle !lapic_in_kernel case in kvm_cpu_*_extint
[linux-2.6-microblaze.git] / arch / x86 / kvm / irq.c
index 99d118f..ee94671 100644 (file)
@@ -41,28 +41,9 @@ static int pending_userspace_extint(struct kvm_vcpu *v)
  * non-APIC source without intack.
  */
 static int kvm_cpu_has_extint(struct kvm_vcpu *v)
-{
-       u8 accept = kvm_apic_accept_pic_intr(v);
-
-       if (accept) {
-               if (irqchip_split(v->kvm))
-                       return pending_userspace_extint(v);
-               else
-                       return v->kvm->arch.vpic->output;
-       } else
-               return 0;
-}
-
-/*
- * check if there is injectable interrupt:
- * when virtual interrupt delivery enabled,
- * interrupt from apic will handled by hardware,
- * we don't need to check it here.
- */
-int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
 {
        /*
-        * FIXME: interrupt.injected represents an interrupt that it's
+        * FIXME: interrupt.injected represents an interrupt whose
         * side-effects have already been applied (e.g. bit from IRR
         * already moved to ISR). Therefore, it is incorrect to rely
         * on interrupt.injected to know if there is a pending
@@ -75,6 +56,23 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
        if (!lapic_in_kernel(v))
                return v->arch.interrupt.injected;
 
+       if (!kvm_apic_accept_pic_intr(v))
+               return 0;
+
+       if (irqchip_split(v->kvm))
+               return pending_userspace_extint(v);
+       else
+               return v->kvm->arch.vpic->output;
+}
+
+/*
+ * check if there is injectable interrupt:
+ * when virtual interrupt delivery enabled,
+ * interrupt from apic will handled by hardware,
+ * we don't need to check it here.
+ */
+int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
+{
        if (kvm_cpu_has_extint(v))
                return 1;
 
@@ -91,20 +89,6 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_injectable_intr);
  */
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
 {
-       /*
-        * FIXME: interrupt.injected represents an interrupt that it's
-        * side-effects have already been applied (e.g. bit from IRR
-        * already moved to ISR). Therefore, it is incorrect to rely
-        * on interrupt.injected to know if there is a pending
-        * interrupt in the user-mode LAPIC.
-        * This leads to nVMX/nSVM not be able to distinguish
-        * if it should exit from L2 to L1 on EXTERNAL_INTERRUPT on
-        * pending interrupt or should re-inject an injected
-        * interrupt.
-        */
-       if (!lapic_in_kernel(v))
-               return v->arch.interrupt.injected;
-
        if (kvm_cpu_has_extint(v))
                return 1;
 
@@ -118,16 +102,21 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
  */
 static int kvm_cpu_get_extint(struct kvm_vcpu *v)
 {
-       if (kvm_cpu_has_extint(v)) {
-               if (irqchip_split(v->kvm)) {
-                       int vector = v->arch.pending_external_vector;
-
-                       v->arch.pending_external_vector = -1;
-                       return vector;
-               } else
-                       return kvm_pic_read_irq(v->kvm); /* PIC */
-       } else
+       if (!kvm_cpu_has_extint(v)) {
+               WARN_ON(!lapic_in_kernel(v));
                return -1;
+       }
+
+       if (!lapic_in_kernel(v))
+               return v->arch.interrupt.nr;
+
+       if (irqchip_split(v->kvm)) {
+               int vector = v->arch.pending_external_vector;
+
+               v->arch.pending_external_vector = -1;
+               return vector;
+       } else
+               return kvm_pic_read_irq(v->kvm); /* PIC */
 }
 
 /*
@@ -135,13 +124,7 @@ static int kvm_cpu_get_extint(struct kvm_vcpu *v)
  */
 int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
 {
-       int vector;
-
-       if (!lapic_in_kernel(v))
-               return v->arch.interrupt.nr;
-
-       vector = kvm_cpu_get_extint(v);
-
+       int vector = kvm_cpu_get_extint(v);
        if (vector != -1)
                return vector;                  /* PIC */