From: sashiko-bot@kernel.org
To: "Sairaj Kodilkar" <sarunkod@amd.com>
Cc: kvm@vger.kernel.org
Subject: Re: [RFC PATCH v2 4/5] kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload
Date: Wed, 08 Jul 2026 09:37:15 +0000 [thread overview]
Message-ID: <20260708093715.9B9CD1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260708091408.12106-5-sarunkod@amd.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Missing CPU hotplug teardown logic for `gappi_vcpu_wakeup_list` causes indefinitely stalled vCPUs when a physical CPU is taken offline.
- [High] Host-userspace reachable `WARN_ON(cpu < 0)` via uninitialized `svm->gappi_cpu` when setting up posted interrupts for AVIC-inhibited VMs.
- [High] Unconditional call to `avic_remove_vcpu_from_gappi_wakeup_list()` triggers a spurious `WARN_ON` when GAPPI is disabled.
- [Medium] Mixing `goto`-based error handling with `guard()` scope-based cleanup in `avic_pi_update_irte()` violates subsystem guidelines.
--
--- Patch [4]: [RFC PATCH v2 4/5] kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload ---
commit 943f44c8b99a66a1765989cd046e31b1a7a04469
Author: Sairaj Kodilkar <sarunkod@amd.com>
kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload
When a vCPU is unloaded from a physical CPU enqueue it on that CPU's
GAPPI wakeup list. Remove the vCPU from the wakeup list when it is loaded
on to a CPU again.
Also enqueue from avic_pi_update_irte() when vCPU is not running and
ir_list is still empty. This handles the condition where vCPU load skips
the per-CPU wakeup-list update when ir_list is empty.
The GAPPI wakeup handler walks this CPU's list and wakes vCPUs that still
have a pending IRR. Install it with kvm_set_posted_intr_wakeup_handler()
so deliveries on POSTED_INTR_WAKEUP_VECTOR invoke it.
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index e7a4c0e90e7a7..8185841d9b816 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
[ ... ]
> @@ -899,13 +938,18 @@ static void svm_ir_list_del(struct kvm_kernel_irqfd *irqfd)
> {
> struct kvm_vcpu *vcpu = irqfd->irq_bypass_vcpu;
> unsigned long flags;
> + struct vcpu_svm *svm;
>
> if (!vcpu)
> return;
>
> - raw_spin_lock_irqsave(&to_svm(vcpu)->ir_list_lock, flags);
> + svm = to_svm(vcpu);
> +
> + raw_spin_lock_irqsave(&svm->ir_list_lock, flags);
> list_del(&irqfd->vcpu_list);
> - raw_spin_unlock_irqrestore(&to_svm(vcpu)->ir_list_lock, flags);
> + if (list_empty(&svm->ir_list))
> + avic_remove_vcpu_from_gappi_wakeup_list(svm, svm->gappi_cpu);
[Severity: High]
If GAPPI is globally disabled (amd_iommu_gappi == false), svm->gappi_cpu
remains at its initial value of -1 for the vCPU's entire lifetime.
When the last irqfd is deleted in svm_ir_list_del(), this calls
avic_remove_vcpu_from_gappi_wakeup_list() unconditionally without checking
if GAPPI is actually enabled.
Since cpu is -1, does this trigger the WARN_ON(cpu < 0) when host userspace
detaches an irqfd or shuts down a VM with assigned devices?
> + raw_spin_unlock_irqrestore(&svm->ir_list_lock, flags);
> }
>
> int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
[ ... ]
> @@ -958,16 +1003,18 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
> } else {
> posted_intr = !!(entry & AVIC_PHYSICAL_ID_ENTRY_GA_LOG_INTR);
> pi_data.flags = posted_intr << AMD_IOMMU_FLAG_POSTED_INTR_SHIFT;
> - /* GAPPI is disabled at this point (amd_iommu_gappi is
> - * enabled in the following patches) hence keep the
> - * apicid as 0.
> - */
> - pi_data.apicid = 0;
> + if (amd_iommu_gappi) {
> + pi_data.apicid = kvm_cpu_get_apicid(svm->gappi_cpu);
> + if (list_empty(&svm->ir_list)) {
> + avic_add_vcpu_to_gappi_wakeup_list(svm, svm->gappi_cpu);
> + is_vcpu_waiting = true;
> + }
> + }
> }
[Severity: High]
svm->gappi_cpu is initialized to -1. If AVIC is disabled or inhibited for
the VM, kvm_vcpu_apicv_active() is false and avic_vcpu_load() is never
called, leaving svm->gappi_cpu as -1.
When userspace configures an IRQFD and the global amd_iommu_gappi flag is
true, this passes -1 to avic_add_vcpu_to_gappi_wakeup_list().
Could this trigger the host-userspace reachable WARN_ON(cpu < 0) in
avic_add_vcpu_to_gappi_wakeup_list()?
>
> ret = irq_set_vcpu_affinity(host_irq, &pi_data);
> if (ret)
> - return ret;
> + goto gappi_err_out;
[Severity: Medium]
This introduces goto-based error handling in avic_pi_update_irte(), which
already uses guard(raw_spinlock_irqsave)(&svm->ir_list_lock) earlier in
the function.
Does mixing goto-based cleanup labels and guard() declarations violate the
subsystem guidelines for cleanup function compatibility?
>
> /*
> * Revert to legacy mode if the IOMMU didn't provide metadata
[ ... ]
> @@ -1310,6 +1376,21 @@ static bool __init avic_want_avic_enabled(void)
> return true;
> }
>
> +static void avic_gappi_wakeup_handler(void)
> +{
> + int cpu = smp_processor_id();
> + struct list_head *vcpu_wakeup_list = &per_cpu(gappi_vcpu_wakeup_list, cpu);
> + raw_spinlock_t *spinlock = &per_cpu(gappi_vcpu_wakeup_list_lock, cpu);
> + struct vcpu_svm *svm;
> +
> + raw_spin_lock(spinlock);
> + list_for_each_entry(svm, vcpu_wakeup_list, gappi_vcpu_wakeup_list) {
> + if (kvm_lapic_find_highest_irr(&svm->vcpu) >= 0)
> + kvm_vcpu_wake_up(&svm->vcpu);
> + }
> + raw_spin_unlock(spinlock);
> +}
> +
[Severity: High]
The per-CPU wakeup list is processed here in avic_gappi_wakeup_handler(),
but this handler will never run for an offline CPU.
If a physical CPU is hot-unplugged, the IOMMU's GAPPI hardware doorbell
interrupts sent to that CPU are dropped.
Since there is no CPU hotplug teardown logic registered (e.g., via
cpuhp_setup_state() in avic_hardware_setup()) to drain the list or migrate
the vCPUs to an online CPU, will any vCPUs left on its list miss their
wakeup events and stall indefinitely?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260708091408.12106-1-sarunkod@amd.com?part=4
next prev parent reply other threads:[~2026-07-08 9:37 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 9:14 [RFC PATCH v2 0/5] Add support for AMD IOMMU GAPPI Sairaj Kodilkar
2026-07-08 9:14 ` [RFC PATCH v2 1/5] iommu/amd: kvm/svm: Improve API between SVM and AMD IOMMU Sairaj Kodilkar
2026-07-08 13:36 ` Sean Christopherson
2026-07-09 6:39 ` Sairaj Kodilkar
2026-07-10 17:19 ` Sean Christopherson
2026-07-08 9:14 ` [RFC PATCH v2 2/5] iommu/amd: Configure IRTE to use the GAPPI for posted interrupts Sairaj Kodilkar
2026-07-08 9:37 ` sashiko-bot
2026-07-08 9:14 ` [RFC PATCH v2 3/5] kvm/svm: Introduce per-CPU lock and wakeup queue Sairaj Kodilkar
2026-07-08 13:36 ` Sean Christopherson
2026-07-08 9:14 ` [RFC PATCH v2 4/5] kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload Sairaj Kodilkar
2026-07-08 9:37 ` sashiko-bot [this message]
2026-07-08 13:38 ` Sean Christopherson
2026-07-08 9:14 ` [RFC PATCH v2 5/5] iommu/amd: Provide kernel command line option to enable GAPPI Sairaj Kodilkar
2026-07-08 9:40 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260708093715.9B9CD1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=sarunkod@amd.com \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.