Skip to content

Commit

Permalink
arm/arm64: KVM: Initialize the vgic on-demand when injecting IRQs
Browse files Browse the repository at this point in the history
Userspace assumes that it can wire up IRQ injections after having
created all VCPUs and after having created the VGIC, but potentially
before starting the first VCPU.  This can currently lead to lost IRQs
because the state of that IRQ injection is not stored anywhere and we
don't return an error to userspace.

We haven't seen this problem manifest itself yet, presumably because
guests reset the devices on boot, but this could cause issues with
migration and other non-standard startup configurations.

Reviewed-by: Marc Zyngier <[email protected]>
Signed-off-by: Christoffer Dall <[email protected]>
  • Loading branch information
chazy committed Dec 15, 2014
1 parent 716139d commit ca7d9c8
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions virt/kvm/arm/vgic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1694,16 +1694,26 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
bool level)
{
int ret = 0;
int vcpu_id;

if (likely(vgic_ready(kvm))) {
vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
if (vcpu_id >= 0)
/* kick the specified vcpu */
kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
if (unlikely(!vgic_initialized(kvm))) {
mutex_lock(&kvm->lock);
ret = vgic_init(kvm);
mutex_unlock(&kvm->lock);

if (ret)
goto out;
}

return 0;
vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
if (vcpu_id >= 0) {
/* kick the specified vcpu */
kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
}

out:
return ret;
}

static irqreturn_t vgic_maintenance_handler(int irq, void *data)
Expand Down

0 comments on commit ca7d9c8

Please sign in to comment.