Merge remote-tracking branches 'asoc/fix/atmel', 'asoc/fix/compress', 'asoc/fix/da721...
[cascardo/linux.git] / virt / kvm / arm / vgic / vgic-init.c
index 2c7f0d5..83777c1 100644 (file)
@@ -73,12 +73,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
        int i, vcpu_lock_idx = -1, ret;
        struct kvm_vcpu *vcpu;
 
-       mutex_lock(&kvm->lock);
-
-       if (irqchip_in_kernel(kvm)) {
-               ret = -EEXIST;
-               goto out;
-       }
+       if (irqchip_in_kernel(kvm))
+               return -EEXIST;
 
        /*
         * This function is also called by the KVM_CREATE_IRQCHIP handler,
@@ -87,10 +83,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
         * the proper checks already.
         */
        if (type == KVM_DEV_TYPE_ARM_VGIC_V2 &&
-               !kvm_vgic_global_state.can_emulate_gicv2) {
-               ret = -ENODEV;
-               goto out;
-       }
+               !kvm_vgic_global_state.can_emulate_gicv2)
+               return -ENODEV;
 
        /*
         * Any time a vcpu is run, vcpu_load is called which tries to grab the
@@ -138,9 +132,6 @@ out_unlock:
                vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
                mutex_unlock(&vcpu->mutex);
        }
-
-out:
-       mutex_unlock(&kvm->lock);
        return ret;
 }
 
@@ -157,6 +148,9 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
        struct kvm_vcpu *vcpu0 = kvm_get_vcpu(kvm, 0);
        int i;
 
+       INIT_LIST_HEAD(&dist->lpi_list_head);
+       spin_lock_init(&dist->lpi_list_lock);
+
        dist->spis = kcalloc(nr_spis, sizeof(struct vgic_irq), GFP_KERNEL);
        if (!dist->spis)
                return  -ENOMEM;
@@ -177,6 +171,7 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
                spin_lock_init(&irq->irq_lock);
                irq->vcpu = NULL;
                irq->target_vcpu = vcpu0;
+               kref_init(&irq->refcount);
                if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2)
                        irq->targets = 0;
                else
@@ -211,6 +206,7 @@ static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
                irq->vcpu = NULL;
                irq->target_vcpu = vcpu;
                irq->targets = 1U << vcpu->vcpu_id;
+               kref_init(&irq->refcount);
                if (vgic_irq_is_sgi(i)) {
                        /* SGIs */
                        irq->enabled = 1;
@@ -253,9 +249,16 @@ int vgic_init(struct kvm *kvm)
        if (ret)
                goto out;
 
+       if (vgic_has_its(kvm))
+               dist->msis_require_devid = true;
+
        kvm_for_each_vcpu(i, vcpu, kvm)
                kvm_vgic_vcpu_init(vcpu);
 
+       ret = kvm_vgic_setup_default_irq_routing(kvm);
+       if (ret)
+               goto out;
+
        dist->initialized = true;
 out:
        return ret;
@@ -271,7 +274,6 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
        dist->initialized = false;
 
        kfree(dist->spis);
-       kfree(dist->redist_iodevs);
        dist->nr_spis = 0;
 
        mutex_unlock(&kvm->lock);