summaryrefslogtreecommitdiff
path: root/virt/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-07-08 12:09:00 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-07-03 19:49:06 -0700
commit79f03a7665abcb4121a091a0f2008ea83c4bb0d1 (patch)
treef418f9c7012a773a9f8a1e51f28cc7b50bc89359 /virt/kvm
parentbe255a24d4599e3aae60007e1cbc499f61a092fa (diff)
KVM: ARM: vgic: plug irq injection race
commit 71afaba4a2e98bb7bdeba5078370ab43d46e67a1 upstream. [Since we don't backport commit 227844f (arm/arm64: KVM: Rename irq_state to irq_pending) for linux-3.14.y, here we still use vgic_update_irq_state instead of vgic_update_irq_pending.] As it stands, nothing prevents userspace from injecting an interrupt before the guest's GIC is actually initialized. This goes unnoticed so far (as everything is pretty much statically allocated), but ends up exploding in a spectacular way once we switch to a more dynamic allocation (the GIC data structure isn't there yet). The fix is to test for the "ready" flag in the VGIC distributor before trying to inject the interrupt. Note that in order to avoid breaking userspace, we have to ignore what is essentially an error. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/arm/vgic.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 1316e558db64..21873187b513 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1387,7 +1387,8 @@ out:
int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
bool level)
{
- if (vgic_update_irq_state(kvm, cpuid, irq_num, level))
+ if (likely(vgic_initialized(kvm)) &&
+ vgic_update_irq_state(kvm, cpuid, irq_num, level))
vgic_kick_vcpus(kvm);
return 0;