Re: [PATCH v5 16/49] KVM: arm64: gic-v5: Request doorbells when VPEs enter WFI
[email protected] Fri, 07 Aug 2026 14:17:08 +0000
| Newsgroups | dev.linux.lists.kvmarm,org.kernel.vger.kvm |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [High] ABBA deadlock between `rq_lock` and `desc->lock` in `vgic_v5_put` via `irq_set_affinity`. - [High] Stale `db_fired` state causes infinite VMEXIT loops upon subsequent WFIs. - [High] Guest-reachable WARN_ON due to host-side `irq_set_affinity` failures. -- --- Patch [16]: [PATCH v5 16/49] KVM: arm64: gic-v5: Request doorbells when VPEs enter WFI --- commit c40948b426a64dc48dae28e60304e7f29600ab3c Author: Sascha Bischoff <[email protected]> KVM: arm64: gic-v5: Request doorbells when VPEs enter WFI When a GICv5 VPE is made non-resident as part of the vcpu entering WFI, request a VPE doorbell so that KVM can be notified when a suitable SPI or LPI becomes pending for that VPE. > diff --git a/arch/arm64/kvm/hyp/vgic-v5-sr.c b/arch/arm64/kvm/hyp/vgic-v5-sr.c > --- a/arch/arm64/kvm/hyp/vgic-v5-sr.c > +++ b/arch/arm64/kvm/hyp/vgic-v5-sr.c > @@ -22,6 +22,15 @@ void __vgic_v5_make_resident(struct vgic_v5_cpu_if *cpu_if) > > void __vgic_v5_make_non_resident(struct vgic_v5_cpu_if *cpu_if) > { > + /* > + * Clear the db_fired state to ensure that we're ready for the next > + * doorbell when it is requested. If a doorbell firing caused us to > + * enter the guest, then we've already consumed that state at this > + * point, so this is safe to clear. Use WRITE_ONCE() to ensure we're not > + * racing with the doorbell firing and setting the state true again. > + */ > + WRITE_ONCE(cpu_if->gicv5_vpe.db_fired, false); [Severity: High] Will this state management regression leave the db_fired state stale for back-to-back WFIs? Since __vgic_v5_make_non_resident() is called from vgic_v5_put(), which is invoked upon host preemption or user exit (but not standard guest re-entry after kvm_vcpu_block), db_fired appears to remain true when the guest resumes. If the guest executes WFI again, kvm_vcpu_check_block() checks kvm_vgic_vcpu_pending_irq() in arch/arm64/kvm/vgic/vgic.c and observes db_fired is still true, which causes it to instantly abort blocking. This could result in the guest continuously spinning in VMEXITs. > diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c > --- a/arch/arm64/kvm/vgic/vgic-v5.c > +++ b/arch/arm64/kvm/vgic/vgic-v5.c [ ... ] > @@ -1099,6 +1099,46 @@ void vgic_v5_put(struct kvm_vcpu *vcpu) [ ... ] > + /* > + * Make the doorbell affine to this CPU, if it isn't > + * already. Actively check the cpumask first as it is > + * cheaper than changing the affinity every time. > + */ > + if (!cpumask_test_cpu(cpu, aff)) > + WARN_ON(irq_set_affinity(db_irq, cpumask_of(cpu))); [Severity: High] Does this introduce an ABBA deadlock regression between rq_lock and desc->lock? When a guest vCPU thread is preempted or enters WFI, the host scheduler's __schedule() holds the runqueue lock (rq_lock) while calling prepare_task_switch(). This triggers the sched_out preempt notifier, taking us through kvm_sched_out() -> kvm_arch_vcpu_put() -> kvm_vgic_put() and finally to vgic_v5_put(). Inside vgic_v5_put(), irq_set_affinity() acquires the hardware interrupt descriptor lock (desc->lock). Taking desc->lock while already holding rq_lock violates the locking hierarchy where desc->lock must be acquired before rq_lock. [Severity: High] Can a guest trigger this WARN_ON regression to cause a host denial of service? Calls to irq_set_affinity() can legitimately fail and return negative error codes due to hardware constraints (such as ITS socket-crossing limitations) or resource exhaustion. Since the guest controls when it executes WFI, it can reliably trigger this WARN_ON if the host scheduler places it on a restricted CPU. If panic_on_warn is enabled, this allows the guest to crash the host. -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=16