aboutsummaryrefslogtreecommitdiff
path: root/virt/kvm/arm/vgic/vgic-init.c
diff options
context:
space:
mode:
authorEric Auger <eric.auger@linaro.org>2015-12-21 15:04:42 +0100
committerChristoffer Dall <christoffer.dall@linaro.org>2016-05-20 15:40:07 +0200
commitb0442ee227e826afc4df16cdfb8bd6eef6a8f425 (patch)
treea04cc19ffafb2067309337f6dba14032e34da403 /virt/kvm/arm/vgic/vgic-init.c
parentad275b8bb1e659b14120174d87e3c1fdc22e9978 (diff)
downloadlinux-stericsson-b0442ee227e826afc4df16cdfb8bd6eef6a8f425.tar.gz
KVM: arm/arm64: vgic-new: vgic_init: implement map_resources
map_resources is the last initialization step. It is executed on first VCPU run. At that stage the code checks that userspace has provided the base addresses for the relevant VGIC regions, which depend on the type of VGIC that is exposed to the guest. Also we check if the two regions overlap. If the checks succeeded, we register the respective register frames with the kvm_io_bus framework. If we emulate a GICv2, the function also forces vgic_init execution if it has not been executed yet. Also we map the virtual GIC CPU interface onto the guest's CPU interface. Signed-off-by: Eric Auger <eric.auger@linaro.org> Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt/kvm/arm/vgic/vgic-init.c')
-rw-r--r--virt/kvm/arm/vgic/vgic-init.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index bed3240bd634..a1442f7c9c4d 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -323,6 +323,34 @@ int vgic_lazy_init(struct kvm *kvm)
return ret;
}
+/* RESOURCE MAPPING */
+
+/**
+ * Map the MMIO regions depending on the VGIC model exposed to the guest
+ * called on the first VCPU run.
+ * Also map the virtual CPU interface into the VM.
+ * v2/v3 derivatives call vgic_init if not already done.
+ * vgic_ready() returns true if this function has succeeded.
+ * @kvm: kvm struct pointer
+ */
+int kvm_vgic_map_resources(struct kvm *kvm)
+{
+ struct vgic_dist *dist = &kvm->arch.vgic;
+ int ret = 0;
+
+ mutex_lock(&kvm->lock);
+ if (!irqchip_in_kernel(kvm))
+ goto out;
+
+ if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2)
+ ret = vgic_v2_map_resources(kvm);
+ else
+ ret = vgic_v3_map_resources(kvm);
+out:
+ mutex_unlock(&kvm->lock);
+ return ret;
+}
+
/* GENERIC PROBE */
static void vgic_init_maintenance_interrupt(void *info)