]> git.hungrycats.org Git - linux/commitdiff
KVM: arm/arm64: vgic-v2: Do not use Active+Pending state for a HW interrupt
authorMarc Zyngier <marc.zyngier@arm.com>
Tue, 2 May 2017 13:30:39 +0000 (14:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 May 2017 13:46:23 +0000 (15:46 +0200)
commit ddf42d068f8802de122bb7efdfcb3179336053f1 upstream.

When an interrupt is injected with the HW bit set (indicating that
deactivation should be propagated to the physical distributor),
special care must be taken so that we never mark the corresponding
LR with the Active+Pending state (as the pending state is kept in
the physycal distributor).

Fixes: 140b086dd197 ("KVM: arm/arm64: vgic-new: Add GICv2 world switch backend")
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
virt/kvm/arm/vgic/vgic-v2.c

index b637d9c7afe3ff51b9e8dfdcd947ee37ef2df029..2f54ce6d3a516e311738714b8ca81ac8d79f3d69 100644 (file)
@@ -181,6 +181,13 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        if (irq->hw) {
                val |= GICH_LR_HW;
                val |= irq->hwintid << GICH_LR_PHYSID_CPUID_SHIFT;
+               /*
+                * Never set pending+active on a HW interrupt, as the
+                * pending state is kept at the physical distributor
+                * level.
+                */
+               if (irq->active && irq_is_pending(irq))
+                       val &= ~GICH_LR_PENDING_BIT;
        } else {
                if (irq->config == VGIC_CONFIG_LEVEL)
                        val |= GICH_LR_EOI;