KVM: x86: Add a common TSC scaling function
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kvm / ioapic.c
index 856f79105bb59fcb14650de8f2d35814115f646f..88d0a92d3f94676d2e68cdb19b2bdd35b49a7d15 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);
@@ -599,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 = {
@@ -628,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;
 }
 
@@ -666,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);