These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / x86 / kvm / irq.c
index a1ec6a5..097060e 100644 (file)
@@ -37,15 +37,28 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 }
 EXPORT_SYMBOL(kvm_cpu_has_pending_timer);
 
+/*
+ * check if there is a pending userspace external interrupt
+ */
+static int pending_userspace_extint(struct kvm_vcpu *v)
+{
+       return v->arch.pending_external_vector != -1;
+}
+
 /*
  * check if there is pending interrupt from
  * non-APIC source without intack.
  */
 static int kvm_cpu_has_extint(struct kvm_vcpu *v)
 {
-       if (kvm_apic_accept_pic_intr(v))
-               return pic_irqchip(v->kvm)->output;     /* PIC */
-       else
+       u8 accept = kvm_apic_accept_pic_intr(v);
+
+       if (accept) {
+               if (irqchip_split(v->kvm))
+                       return pending_userspace_extint(v);
+               else
+                       return pic_irqchip(v->kvm)->output;
+       } else
                return 0;
 }
 
@@ -57,13 +70,13 @@ static int kvm_cpu_has_extint(struct kvm_vcpu *v)
  */
 int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
 {
-       if (!irqchip_in_kernel(v->kvm))
+       if (!lapic_in_kernel(v))
                return v->arch.interrupt.pending;
 
        if (kvm_cpu_has_extint(v))
                return 1;
 
-       if (kvm_apic_vid_enabled(v->kvm))
+       if (kvm_vcpu_apic_vid_enabled(v))
                return 0;
 
        return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
@@ -75,7 +88,7 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
  */
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
 {
-       if (!irqchip_in_kernel(v->kvm))
+       if (!lapic_in_kernel(v))
                return v->arch.interrupt.pending;
 
        if (kvm_cpu_has_extint(v))
@@ -91,9 +104,16 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
  */
 static int kvm_cpu_get_extint(struct kvm_vcpu *v)
 {
-       if (kvm_cpu_has_extint(v))
-               return kvm_pic_read_irq(v->kvm); /* PIC */
-       return -1;
+       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
+               return -1;
 }
 
 /*
@@ -103,7 +123,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
 {
        int vector;
 
-       if (!irqchip_in_kernel(v->kvm))
+       if (!lapic_in_kernel(v))
                return v->arch.interrupt.nr;
 
        vector = kvm_cpu_get_extint(v);