aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm/vgic.c
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@linaro.org>2013-09-23 17:55:55 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2013-12-21 13:01:06 -0500
commite1ba0207a1b3714bb3f000e506285ae5123cdfa7 (patch)
treed4a231a1c19b0ae85e391ad43634ee549caf9c34 /virt/kvm/arm/vgic.c
parent39735a3a390431bcf60f9174b7d64f787fd6afa9 (diff)
ARM: KVM: Allow creating the VGIC after VCPUs
Rework the VGIC initialization slightly to allow initialization of the vgic cpu-specific state even if the irqchip (the VGIC) hasn't been created by user space yet. This is safe, because the vgic data structures are already allocated when the CPU is allocated if VGIC support is compiled into the kernel. Further, the init process does not depend on any other information and the sacrifice is a slight performance degradation for creating VMs in the no-VGIC case. The reason is that the new device control API doesn't mandate creating the VGIC before creating the VCPU and it is unreasonable to require user space to create the VGIC before creating the VCPUs. At the same time move the irqchip_in_kernel check out of kvm_vcpu_first_run_init and into the init function to make the per-vcpu and global init functions symmetric and add comments on the exported functions making it a bit easier to understand the init flow by only looking at vgic.c. Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt/kvm/arm/vgic.c')
-rw-r--r--virt/kvm/arm/vgic.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 81e9481184a7..5e9df47778fb 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1243,15 +1243,19 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data)
1243 return IRQ_HANDLED; 1243 return IRQ_HANDLED;
1244} 1244}
1245 1245
1246/**
1247 * kvm_vgic_vcpu_init - Initialize per-vcpu VGIC state
1248 * @vcpu: pointer to the vcpu struct
1249 *
1250 * Initialize the vgic_cpu struct and vgic_dist struct fields pertaining to
1251 * this vcpu and enable the VGIC for this VCPU
1252 */
1246int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) 1253int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
1247{ 1254{
1248 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 1255 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
1249 struct vgic_dist *dist = &vcpu->kvm->arch.vgic; 1256 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1250 int i; 1257 int i;
1251 1258
1252 if (!irqchip_in_kernel(vcpu->kvm))
1253 return 0;
1254
1255 if (vcpu->vcpu_id >= VGIC_MAX_CPUS) 1259 if (vcpu->vcpu_id >= VGIC_MAX_CPUS)
1256 return -EBUSY; 1260 return -EBUSY;
1257 1261
@@ -1383,10 +1387,22 @@ out:
1383 return ret; 1387 return ret;
1384} 1388}
1385 1389
1390/**
1391 * kvm_vgic_init - Initialize global VGIC state before running any VCPUs
1392 * @kvm: pointer to the kvm struct
1393 *
1394 * Map the virtual CPU interface into the VM before running any VCPUs. We
1395 * can't do this at creation time, because user space must first set the
1396 * virtual CPU interface address in the guest physical address space. Also
1397 * initialize the ITARGETSRn regs to 0 on the emulated distributor.
1398 */
1386int kvm_vgic_init(struct kvm *kvm) 1399int kvm_vgic_init(struct kvm *kvm)
1387{ 1400{
1388 int ret = 0, i; 1401 int ret = 0, i;
1389 1402
1403 if (!irqchip_in_kernel(kvm))
1404 return 0;
1405
1390 mutex_lock(&kvm->lock); 1406 mutex_lock(&kvm->lock);
1391 1407
1392 if (vgic_initialized(kvm)) 1408 if (vgic_initialized(kvm))