Merge tag 'pinctrl-v5.3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[sfrench/cifs-2.6.git] / virt / kvm / arm / vgic / vgic-init.c
index bdbc297d06fb4676559dab05137a03d916d58273..e621b5d45b278b6e1d03f997849422ad3a94fe97 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/cpu.h>
 #include <linux/kvm_host.h>
 #include <kvm/arm_vgic.h>
+#include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
 #include "vgic.h"
 
@@ -164,12 +165,18 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
                irq->vcpu = NULL;
                irq->target_vcpu = vcpu0;
                kref_init(&irq->refcount);
-               if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) {
+               switch (dist->vgic_model) {
+               case KVM_DEV_TYPE_ARM_VGIC_V2:
                        irq->targets = 0;
                        irq->group = 0;
-               } else {
+                       break;
+               case KVM_DEV_TYPE_ARM_VGIC_V3:
                        irq->mpidr = 0;
                        irq->group = 1;
+                       break;
+               default:
+                       kfree(dist->spis);
+                       return -EINVAL;
                }
        }
        return 0;
@@ -209,7 +216,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
                irq->intid = i;
                irq->vcpu = NULL;
                irq->target_vcpu = vcpu;
-               irq->targets = 1U << vcpu->vcpu_id;
                kref_init(&irq->refcount);
                if (vgic_irq_is_sgi(i)) {
                        /* SGIs */
@@ -219,11 +225,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
                        /* PPIs */
                        irq->config = VGIC_CONFIG_LEVEL;
                }
-
-               if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
-                       irq->group = 1;
-               else
-                       irq->group = 0;
        }
 
        if (!irqchip_in_kernel(vcpu->kvm))
@@ -286,10 +287,19 @@ int vgic_init(struct kvm *kvm)
 
                for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) {
                        struct vgic_irq *irq = &vgic_cpu->private_irqs[i];
-                       if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+                       switch (dist->vgic_model) {
+                       case KVM_DEV_TYPE_ARM_VGIC_V3:
                                irq->group = 1;
-                       else
+                               irq->mpidr = kvm_vcpu_get_mpidr_aff(vcpu);
+                               break;
+                       case KVM_DEV_TYPE_ARM_VGIC_V2:
                                irq->group = 0;
+                               irq->targets = 1U << idx;
+                               break;
+                       default:
+                               ret = -EINVAL;
+                               goto out;
+                       }
                }
        }