Re: [PATCH v2 0/2] KVM: arm64: vgic-its: Fix LPI double mapping and DISCARD

From: Fuad Tabba

Date: Wed Oct 14 2026 - 11:59:16 EST


Hi Marc,

On Wed, 14 Oct 2026 14:34:09 +0100, Marc Zyngier <maz@xxxxxxxxxx> wrote:
[...]
> I don't think this is right. Yes, it probably does enough request
> checks that we end-up with not getting it completely wrong, but the
> issues are that:
>
> - we have state change before we evaluate the requests
>
> - we mix request generation and state change in a single helper
>
> and we should be able to fix that so that there is only a single
> request checking point in the whole entry sequence.

Agreed, this is cleaner. With the flush after the single request
check, your run loop is what the second litmus test in my last email
[1] models (discard+halt+check), which comes out Never under the LKMM.
On QEMU, with your diff on top of v2, the guest doesn't take the
discarded LPI in any of 20 runs with the debug hooks forcing the race.
With NV, vgic_lpi_stress and my DISCARD test pass with the guest at
vEL2, but I don't have any tests that run an L2 guest.

[...]
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
[...]
> @@ -1334,18 +1330,19 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
> smp_store_mb(vcpu->mode, IN_GUEST_MODE);
>
> if (ret <= 0 || kvm_vcpu_exit_request(vcpu, &ret)) {
> - vcpu->mode = OUTSIDE_GUEST_MODE;
> isb(); /* Ensure work in x_flush_hwstate is committed */

I think you can drop this isb() too. It was added so that the early
exit's vgic sync would read back consistent GIC state after the flush
had written it (771621b0e2f8).

[...]
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
[...]
> @@ -2054,6 +2057,11 @@ void kvm_nested_flush_hwstate(struct kvm_vcpu *vcpu)
>
> if (unlikely(vcpu_test_and_clear_flag(vcpu, NESTED_SERROR_PENDING)))
> kvm_inject_serror_esr(vcpu, vcpu_get_vsesr(vcpu));
> +
> + vgic_v3_nested_update_mi(vcpu);
> +
> + if (vgic_state_is_nested(vcpu) && kvm_vgic_vcpu_pending_irq(vcpu))
> + kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);

This now runs before kvm_pmu_flush_hwstate(), so a PMU overflow raised
there isn't queued yet when the pending check runs, and the vCPU goes
round the loop once more (the injection's KVM_REQ_IRQ_PENDING still
stops the entry). Would it make sense to call
kvm_nested_flush_hwstate() after kvm_pmu_flush_hwstate() instead?

Patch 2 depends on your run-loop change, so I'll wait for it and for
your series with the pauses and the LPI-disabling fix, and rebase both
patches on top for v3.

Cheers,
/fuad

[1] https://lore.kernel.org/all/20261013143338.815377-1-fuad.tabba@xxxxxxxxx/