When LPI support is enabled at redistributor level, VGIC will potentially load the correspond LPI penging table and sync it into the pending_latch. To avoid keeping the 'consumed' pending bits lying around in guest memory (though they're not used), let's clear them after synchronization. The similar work had been done in vgic_v3_lpi_sync_pending_status(). Signed-off-by: Zenghui Yu <yuzenghui@xxxxxxxxxx> --- virt/kvm/arm/vgic/vgic-its.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index d53d34a33e35..905760bfa404 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c @@ -435,6 +435,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) for (i = 0; i < nr_irqs; i++) { int byte_offset, bit_nr; + bool status; byte_offset = intids[i] / BITS_PER_BYTE; bit_nr = intids[i] % BITS_PER_BYTE; @@ -447,22 +448,32 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) ret = kvm_read_guest_lock(vcpu->kvm, pendbase + byte_offset, &pendmask, 1); - if (ret) { - kfree(intids); - return ret; - } + if (ret) + goto out; last_byte_offset = byte_offset; } + status = pendmask & (1 << bit_nr); + irq = vgic_get_irq(vcpu->kvm, NULL, intids[i]); raw_spin_lock_irqsave(&irq->irq_lock, flags); - irq->pending_latch = pendmask & (1U << bit_nr); + irq->pending_latch = status; vgic_queue_irq_unlock(vcpu->kvm, irq, flags); vgic_put_irq(vcpu->kvm, irq); + + if (status) { + /* clear consumed data */ + pendmask &= ~(1 << bit_nr); + ret = kvm_write_guest_lock(vcpu->kvm, + pendbase + byte_offset, + &pendmask, 1); + if (ret) + goto out; + } } +out: kfree(intids); - return ret; } -- 2.19.1 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm