These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / x86 / kvm / ioapic.c
index 28146f0..88d0a92 100644 (file)
@@ -233,21 +233,7 @@ static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr)
 }
 
 
-static void update_handled_vectors(struct kvm_ioapic *ioapic)
-{
-       DECLARE_BITMAP(handled_vectors, 256);
-       int i;
-
-       memset(handled_vectors, 0, sizeof(handled_vectors));
-       for (i = 0; i < IOAPIC_NUM_PINS; ++i)
-               __set_bit(ioapic->redirtbl[i].fields.vector, handled_vectors);
-       memcpy(ioapic->handled_vectors, handled_vectors,
-              sizeof(handled_vectors));
-       smp_wmb();
-}
-
-void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap,
-                       u32 *tmr)
+void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
 {
        struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
        union kvm_ioapic_redirect_entry *e;
@@ -260,13 +246,11 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap,
                    kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index) ||
                    index == RTC_GSI) {
                        if (kvm_apic_match_dest(vcpu, NULL, 0,
-                               e->fields.dest_id, e->fields.dest_mode)) {
+                                    e->fields.dest_id, e->fields.dest_mode) ||
+                           (e->fields.trig_mode == IOAPIC_EDGE_TRIG &&
+                            kvm_apic_pending_eoi(vcpu, e->fields.vector)))
                                __set_bit(e->fields.vector,
                                        (unsigned long *)eoi_exit_bitmap);
-                               if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG)
-                                       __set_bit(e->fields.vector,
-                                               (unsigned long *)tmr);
-                       }
                }
        }
        spin_unlock(&ioapic->lock);
@@ -315,7 +299,6 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
                        e->bits |= (u32) val;
                        e->fields.remote_irr = 0;
                }
-               update_handled_vectors(ioapic);
                mask_after = e->fields.mask;
                if (mask_before != mask_after)
                        kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after);
@@ -349,6 +332,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
        irqe.delivery_mode = entry->fields.delivery_mode << 8;
        irqe.level = 1;
        irqe.shorthand = 0;
+       irqe.msi_redir_hint = false;
 
        if (irqe.trig_mode == IOAPIC_EDGE_TRIG)
                ioapic->irr_delivered |= 1 << irq;
@@ -598,7 +582,6 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
        ioapic->id = 0;
        memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS);
        rtc_irq_eoi_tracking_reset(ioapic);
-       update_handled_vectors(ioapic);
 }
 
 static const struct kvm_io_device_ops ioapic_mmio_ops = {
@@ -627,8 +610,10 @@ int kvm_ioapic_init(struct kvm *kvm)
        if (ret < 0) {
                kvm->arch.vioapic = NULL;
                kfree(ioapic);
+               return ret;
        }
 
+       kvm_vcpu_request_scan_ioapic(kvm);
        return ret;
 }
 
@@ -637,11 +622,9 @@ void kvm_ioapic_destroy(struct kvm *kvm)
        struct kvm_ioapic *ioapic = kvm->arch.vioapic;
 
        cancel_delayed_work_sync(&ioapic->eoi_inject);
-       if (ioapic) {
-               kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
-               kvm->arch.vioapic = NULL;
-               kfree(ioapic);
-       }
+       kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
+       kvm->arch.vioapic = NULL;
+       kfree(ioapic);
 }
 
 int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
@@ -667,7 +650,6 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
        memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
        ioapic->irr = 0;
        ioapic->irr_delivered = 0;
-       update_handled_vectors(ioapic);
        kvm_vcpu_request_scan_ioapic(kvm);
        kvm_ioapic_inject_all(ioapic, state->irr);
        spin_unlock(&ioapic->lock);