From: sashiko-bot@kernel.org
To: "Sairaj Kodilkar" <sarunkod@amd.com>
Cc: kvm@vger.kernel.org
Subject: Re: [RFC PATCH 4/5] kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload
Date: Fri, 26 Jun 2026 11:25:18 +0000 [thread overview]
Message-ID: <20260626112519.6A59C1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260626105906.14577-5-sarunkod@amd.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] `avic_remove_vcpu_from_gappi_wakeup_list` and `avic_add_vcpu_to_gappi_wakeup_list` acquire a raw spinlock without disabling interrupts, leading to a hard deadlock with the GAPPI IPI hardirq handler.
- [High] Uninitialized `svm->gappi_cpu` (-1) is unconditionally passed to `kvm_cpu_get_apicid()` and `avic_add_vcpu_to_gappi_wakeup_list()`, causing an out-of-bounds array read and a userspace-triggerable `WARN_ON`.
- [High] The GAPPI wakeup handler is registered with the core kernel but never unregistered, leading to a dangling pointer if the KVM module is unloaded.
- [Medium] The per-CPU GAPPI wakeup lists lack CPU hotplug support, resulting in permanently lost device interrupts and hanging vCPUs if a CPU is offlined.
--
commit 3af48ba2bd8326c04b2aa47ac47a9f53e0cd61a3
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.
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index e7a4c0e90e7a7..d238f65a8172b 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -889,6 +892,44 @@ int avic_init_vcpu(struct vcpu_svm *svm)
> return ret;
> }
>
> +static void avic_add_vcpu_to_gappi_wakeup_list(struct vcpu_svm *svm, int cpu)
> +{
> + struct list_head *wakeup_list;
> + raw_spinlock_t *spinlock;
> +
> + if (WARN_ON(cpu < 0))
> + return;
> +
> + wakeup_list = &per_cpu(gappi_vcpu_wakeup_list, cpu);
> + spinlock = &per_cpu(gappi_vcpu_wakeup_list_lock, cpu);
> + raw_spin_lock(spinlock);
> + if (list_empty(&svm->gappi_vcpu_wakeup_list))
> + list_add_tail(&svm->gappi_vcpu_wakeup_list, wakeup_list);
> + raw_spin_unlock(spinlock);
> +}
> +
> +static void avic_remove_vcpu_from_gappi_wakeup_list(struct vcpu_svm *svm, int cpu)
> +{
> + raw_spinlock_t *spinlock;
> +
> + if (WARN_ON(cpu < 0))
> + return;
> +
> + spinlock = &per_cpu(gappi_vcpu_wakeup_list_lock, cpu);
> + raw_spin_lock(spinlock);
> + if (!list_empty(&svm->gappi_vcpu_wakeup_list))
> + list_del_init(&svm->gappi_vcpu_wakeup_list);
> + raw_spin_unlock(spinlock);
> +}
[Severity: High]
Can this cause a hard deadlock with the GAPPI IPI hardirq handler?
When a user process destroys a VM, avic_destroy_vcpu() is called from
svm_vcpu_free() in normal thread context with interrupts enabled. If the
POSTED_INTR_WAKEUP_VECTOR IPI fires on the same CPU while this thread holds
the gappi_vcpu_wakeup_list_lock non-recursive raw spinlock, the interrupt
handler will spin forever attempting to acquire it.
Should these functions use raw_spin_lock_irqsave() to disable interrupts
during lock acquisition?
[ ... ]
> @@ -958,16 +1005,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]
Is it possible for svm->gappi_cpu to still be -1 here?
If userspace creates a VM but inhibits AVIC (for example, via an invalid
APIC ID), avic_vcpu_load() bails out early leaving svm->gappi_cpu as -1.
If userspace later assigns a device interrupt via KVM_IRQFD,
avic_pi_update_irte() will pass -1 to kvm_cpu_get_apicid().
This triggers a negative index array read yielding a garbage APIC ID, and
also hits the WARN_ON(cpu < 0) inside avic_add_vcpu_to_gappi_wakeup_list().
[ ... ]
> @@ -1353,6 +1436,7 @@ bool __init avic_hardware_setup(void)
> enable_ipiv = false;
>
> amd_iommu_register_ga_log_notifier(&avic_ga_log_notifier);
> + kvm_set_posted_intr_wakeup_handler(&avic_gappi_wakeup_handler);
>
> return true;
> }
[Severity: Medium]
Does the per-CPU GAPPI wakeup list need CPU hotplug coordination?
If a physical CPU is taken offline while a VM is running, any blocked
vCPUs queued on that offlined CPU's gappi_vcpu_wakeup_list might permanently
miss their GAPPI wakeups. Without a hotplug state notifier to migrate these
vCPUs, will they hang indefinitely?
[Severity: High]
Is there a missing module unload teardown for the wakeup handler?
This registers avic_gappi_wakeup_handler with the core kernel, but it
doesn't seem to be unregistered (via kvm_set_posted_intr_wakeup_handler(NULL))
during module teardown in avic_hardware_unsetup(). If the kvm-amd module
is unloaded, could a subsequent POSTED_INTR_WAKEUP_VECTOR jump to unmapped
memory and cause a kernel panic?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260626105906.14577-1-sarunkod@amd.com?part=4
next prev parent reply other threads:[~2026-06-26 11:25 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 10:59 [RFC PATCH 0/5] Add support for AMD IOMMU GAPPI Sairaj Kodilkar
2026-06-26 10:59 ` [RFC PATCH 1/5] iommu/amd: kvm/svm: Improve API between SVM and AMD IOMMU Sairaj Kodilkar
2026-06-26 10:59 ` [RFC PATCH 2/5] iommu/amd: Configure IRTE to use the GAPPI for posted interrupts Sairaj Kodilkar
2026-06-26 11:29 ` sashiko-bot
2026-06-26 10:59 ` [RFC PATCH 3/5] kvm/svm: Introduce per-CPU lock and wakeup queue Sairaj Kodilkar
2026-06-26 10:59 ` [RFC PATCH 4/5] kvm/svm: Update the per-CPU wakeup-list during vCPU load and unload Sairaj Kodilkar
2026-06-26 11:25 ` sashiko-bot [this message]
2026-06-26 10:59 ` [RFC PATCH 5/5] iommu/amd: Provide kernel command line option to enable GAPPI Sairaj Kodilkar
2026-06-26 11:25 ` 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=20260626112519.6A59C1F000E9@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.