|
|
@@ -19,6 +19,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"
|
|
|
|
|
|
@@ -175,12 +176,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;
|
|
|
@@ -220,7 +227,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 */
|
|
|
@@ -230,11 +236,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))
|
|
|
@@ -297,10 +298,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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|