]> git.hungrycats.org Git - linux/commitdiff
KVM: arm/arm64: vgic-v3: Do not use Active+Pending state for a HW interrupt
authorMarc Zyngier <marc.zyngier@arm.com>
Tue, 2 May 2017 13:30:40 +0000 (14:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 May 2017 13:46:23 +0000 (15:46 +0200)
commit 3d6e77ad1489650afa20da92bb589c8778baa8da 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: 59529f69f504 ("KVM: arm/arm64: vgic-new: Add GICv3 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-v3.c

index be0f4c3e0142e04216cb28e1f965487d52d0b4c9..abd3d4a1cb49e20624b0cc5556ad2756f2f4e1a7 100644 (file)
@@ -149,6 +149,13 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        if (irq->hw) {
                val |= ICH_LR_HW;
                val |= ((u64)irq->hwintid) << ICH_LR_PHYS_ID_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 &= ~ICH_LR_PENDING_BIT;
        } else {
                if (irq->config == VGIC_CONFIG_LEVEL)
                        val |= ICH_LR_EOI;