summaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm/vgic
diff options
context:
space:
mode:
authorChristoffer Dall2018-12-01 22:21:47 +0100
committerMarc Zyngier2018-12-19 18:47:06 +0100
commit9009782a4937ad0f4a4be6945080d7fa77fa4092 (patch)
treeea52938946cddf7a2c694e2731e3d3388ea2f7bc /virt/kvm/arm/vgic
parentKVM: arm/arm64: vgic: Fix off-by-one bug in vgic_get_irq() (diff)
downloadkernel-qcow2-linux-9009782a4937ad0f4a4be6945080d7fa77fa4092.tar.gz
kernel-qcow2-linux-9009782a4937ad0f4a4be6945080d7fa77fa4092.tar.xz
kernel-qcow2-linux-9009782a4937ad0f4a4be6945080d7fa77fa4092.zip
KVM: arm/arm64: vgic: Consider priority and active state for pending irq
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>
Diffstat (limited to 'virt/kvm/arm/vgic')
-rw-r--r--virt/kvm/arm/vgic/vgic.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index f884a54b2601..a6b135491b6c 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -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)