aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm/vgic-v3-emul.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/arm/vgic-v3-emul.c')
-rw-r--r--virt/kvm/arm/vgic-v3-emul.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
index 2f03a36a9312..eb1a797cb9c1 100644
--- a/virt/kvm/arm/vgic-v3-emul.c
+++ b/virt/kvm/arm/vgic-v3-emul.c
@@ -758,6 +758,9 @@ static int vgic_v3_map_resources(struct kvm *kvm,
758{ 758{
759 int ret = 0; 759 int ret = 0;
760 struct vgic_dist *dist = &kvm->arch.vgic; 760 struct vgic_dist *dist = &kvm->arch.vgic;
761 gpa_t rdbase = dist->vgic_redist_base;
762 struct vgic_io_device *iodevs = NULL;
763 int i;
761 764
762 if (!irqchip_in_kernel(kvm)) 765 if (!irqchip_in_kernel(kvm))
763 return 0; 766 return 0;
@@ -783,7 +786,41 @@ static int vgic_v3_map_resources(struct kvm *kvm,
783 goto out; 786 goto out;
784 } 787 }
785 788
786 kvm->arch.vgic.ready = true; 789 ret = vgic_register_kvm_io_dev(kvm, dist->vgic_dist_base,
790 GIC_V3_DIST_SIZE, vgic_v3_dist_ranges,
791 -1, &dist->dist_iodev);
792 if (ret)
793 goto out;
794
795 iodevs = kcalloc(dist->nr_cpus, sizeof(iodevs[0]), GFP_KERNEL);
796 if (!iodevs) {
797 ret = -ENOMEM;
798 goto out_unregister;
799 }
800
801 for (i = 0; i < dist->nr_cpus; i++) {
802 ret = vgic_register_kvm_io_dev(kvm, rdbase,
803 SZ_128K, vgic_redist_ranges,
804 i, &iodevs[i]);
805 if (ret)
806 goto out_unregister;
807 rdbase += GIC_V3_REDIST_SIZE;
808 }
809
810 dist->redist_iodevs = iodevs;
811 dist->ready = true;
812 goto out;
813
814out_unregister:
815 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &dist->dist_iodev.dev);
816 if (iodevs) {
817 for (i = 0; i < dist->nr_cpus; i++) {
818 if (iodevs[i].dev.ops)
819 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS,
820 &iodevs[i].dev);
821 }
822 }
823
787out: 824out:
788 if (ret) 825 if (ret)
789 kvm_vgic_destroy(kvm); 826 kvm_vgic_destroy(kvm);