Skip to content

Commit 7b95382

Browse files
author
Marc Zyngier
committed
KVM: arm64: vgic-v4: Restore pending state on host userspace write
When the VMM writes to ISPENDR0 to set the state pending state of an SGI, we fail to convey this to the HW if this SGI is already backed by a GICv4.1 vSGI. This is a bit of a corner case, as this would only occur if the vgic state is changed on an already running VM, but this can apparently happen across a guest reset driven by the VMM. Fix this by always writing out the pending_latch value to the HW, and reseting it to false. Reported-by: Kunkun Jiang <jiangkunkun@huawei.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Zenghui Yu <yuzenghui@huawei.com> Cc: stable@vger.kernel.org # 5.10+ Link: https://lore.kernel.org/r/7e7f2c0c-448b-10a9-8929-4b8f4f6e2a32@huawei.com
1 parent 2cc14f5 commit 7b95382

1 file changed

Lines changed: 17 additions & 10 deletions

File tree

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -365,19 +365,26 @@ static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
365365
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
366366

367367
raw_spin_lock_irqsave(&irq->irq_lock, flags);
368-
if (test_bit(i, &val)) {
369-
/*
370-
* pending_latch is set irrespective of irq type
371-
* (level or edge) to avoid dependency that VM should
372-
* restore irq config before pending info.
373-
*/
374-
irq->pending_latch = true;
375-
vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
376-
} else {
368+
369+
/*
370+
* pending_latch is set irrespective of irq type
371+
* (level or edge) to avoid dependency that VM should
372+
* restore irq config before pending info.
373+
*/
374+
irq->pending_latch = test_bit(i, &val);
375+
376+
if (irq->hw && vgic_irq_is_sgi(irq->intid)) {
377+
irq_set_irqchip_state(irq->host_irq,
378+
IRQCHIP_STATE_PENDING,
379+
irq->pending_latch);
377380
irq->pending_latch = false;
378-
raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
379381
}
380382

383+
if (irq->pending_latch)
384+
vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
385+
else
386+
raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
387+
381388
vgic_put_irq(vcpu->kvm, irq);
382389
}
383390

0 commit comments

Comments
 (0)