aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2015-03-26 10:39:37 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2015-03-30 12:07:13 -0400
commitfb8f61abab48467ef670ef165ff664cdc94f742e (patch)
treed03dcb804024ebe6b324da921432dad668253cd1 /virt
parent0ba10d53920d030cd7772a9553b13b5ea1aa4115 (diff)
KVM: arm/arm64: prepare GICv3 emulation to use kvm_io_bus MMIO handling
Using the framework provided by the recent vgic.c changes, we register a kvm_io_bus device on mapping the virtual GICv3 resources. The distributor mapping is pretty straight forward, but the redistributors need some more love, since they need to be tagged with the respective redistributor (read: VCPU) they are connected with. We use the kvm_io_bus framework to register one devices per VCPU. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-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);