KVM: arm/arm64: vgic: Consider priority and active state for pending irq
authorChristoffer Dall <christoffer.dall@arm.com>
Sat, 1 Dec 2018 21:21:47 +0000 (13:21 -0800)
committerMarc Zyngier <marc.zyngier@arm.com>
Wed, 19 Dec 2018 17:47:06 +0000 (17:47 +0000)
When checking if there are any pending IRQs for the VM, consider the
active state and priority of the IRQs as well.

Otherwise we could be continuously scheduling a guest hypervisor without
it seeing an IRQ.

Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
virt/kvm/arm/vgic/vgic.c

index f884a54b2601a416d5de02e09f93c423bbb12bd2..a6b135491b6cd1c5ee14177ff9951d7d176a658f 100644 (file)
@@ -908,6 +908,7 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
        struct vgic_irq *irq;
        bool pending = false;
        unsigned long flags;
+       struct vgic_vmcr vmcr;
 
        if (!vcpu->kvm->arch.vgic.enabled)
                return false;
@@ -915,11 +916,15 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
        if (vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last)
                return true;
 
+       vgic_get_vmcr(vcpu, &vmcr);
+
        spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);
 
        list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
                spin_lock(&irq->irq_lock);
-               pending = irq_is_pending(irq) && irq->enabled;
+               pending = irq_is_pending(irq) && irq->enabled &&
+                         !irq->active &&
+                         irq->priority < vmcr.pmr;
                spin_unlock(&irq->irq_lock);
 
                if (pending)