aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Zyngier <[email protected]>2017-05-02 14:30:39 +0100
committerChristoffer Dall <[email protected]>2017-05-15 11:31:43 +0200
commitddf42d068f8802de122bb7efdfcb3179336053f1 (patch)
tree3b9667a892f676fb3cd552749dd7e9beb4ee8092
parent501ad27c67ed0b90df465f23d33e9aed64058a47 (diff)
KVM: arm/arm64: vgic-v2: Do not use Active+Pending state for a HW interrupt
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). Cc: [email protected] Fixes: 140b086dd197 ("KVM: arm/arm64: vgic-new: Add GICv2 world switch backend") Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Christoffer Dall <[email protected]> Signed-off-by: Christoffer Dall <[email protected]>
-rw-r--r--virt/kvm/arm/vgic/vgic-v2.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index a65757aab6d3..504b4bd0d651 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -149,6 +149,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;