@@ -144,6 +144,7 @@ struct vgic_vm_ops {
bool (*queue_sgi)(struct kvm_vcpu *, int irq);
void (*add_sgi_source)(struct kvm_vcpu *, int irq, int source);
int (*init_model)(struct kvm *);
+ void (*destroy_model)(struct kvm *);
int (*map_resources)(struct kvm *, const struct vgic_params *);
};
@@ -862,6 +862,14 @@ static int vgic_v3_init_model(struct kvm *kvm)
return 0;
}
+static void vgic_v3_destroy_model(struct kvm *kvm)
+{
+ struct vgic_dist *dist = &kvm->arch.vgic;
+
+ kfree(dist->irq_spi_mpidr);
+ dist->irq_spi_mpidr = NULL;
+}
+
/* GICv3 does not keep track of SGI sources anymore. */
static void vgic_v3_add_sgi_source(struct kvm_vcpu *vcpu, int irq, int source)
{
@@ -874,6 +882,7 @@ void vgic_v3_init_emulation(struct kvm *kvm)
dist->vm_ops.queue_sgi = vgic_v3_queue_sgi;
dist->vm_ops.add_sgi_source = vgic_v3_add_sgi_source;
dist->vm_ops.init_model = vgic_v3_init_model;
+ dist->vm_ops.destroy_model = vgic_v3_destroy_model;
dist->vm_ops.map_resources = vgic_v3_map_resources;
kvm->arch.max_vcpus = KVM_MAX_VCPUS;
@@ -100,6 +100,14 @@ int kvm_vgic_map_resources(struct kvm *kvm)
return kvm->arch.vgic.vm_ops.map_resources(kvm, vgic);
}
+static void vgic_destroy_model(struct kvm *kvm)
+{
+ struct vgic_vm_ops *vm_ops = &kvm->arch.vgic.vm_ops;
+
+ if (vm_ops->destroy_model)
+ vm_ops->destroy_model(kvm);
+}
+
/*
* struct vgic_bitmap contains a bitmap made of unsigned longs, but
* extracts u32s out of them.
@@ -1629,6 +1637,8 @@ void kvm_vgic_destroy(struct kvm *kvm)
struct kvm_vcpu *vcpu;
int i;
+ vgic_destroy_model(kvm);
+
kvm_for_each_vcpu(i, vcpu, kvm)
kvm_vgic_vcpu_destroy(vcpu);
@@ -1645,7 +1655,6 @@ void kvm_vgic_destroy(struct kvm *kvm)
}
kfree(dist->irq_sgi_sources);
kfree(dist->irq_spi_cpu);
- kfree(dist->irq_spi_mpidr);
kfree(dist->irq_spi_target);
kfree(dist->irq_pending_on_cpu);
kfree(dist->irq_active_on_cpu);