From: sashiko-bot@kernel.org
To: "Jose Ignacio Tornos Martinez" <jtornosm@redhat.com>
Cc: linux-pci@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v3 3/8] PCI: add KVM MSI domain guest module
Date: Thu, 29 Oct 2026 17:06:50 +0000 [thread overview]
Message-ID: <sashiko-outbox-189718@kernel.org> (raw)
In-Reply-To: <20261029163713.1366077-4-jtornosm@redhat.com>
Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:
- [High] PCI: kvm-msi: use-after-free on module unload in kvm_pci_msi_exit()
- [High] PCI: kvm-msi: broken IRQ affinity in kvm_pcie_init_dev_msi_info()
- [High] PCI: kvm-msi: host MSI message corrupts guest config in kvm_compose_msi_msg()
- [High] PCI: kvm-msi: global kvm_msi_ctx clobbered in kvm_pcie_domain_alloc()
- [High] PCI: kvm-msi: init failure in kvm_pci_msi_init() breaks hotplug and modprobe
- [High] PCI: kvm-msi: race and use-after-free on kvm_data in kvm_pcie_domain_free()
- [Medium] PCI: kvm-msi: missing stubs in pci-kvm-msi.h break modular link
- [Medium] PCI: kvm-msi: kvm_pci_msi_wait_ready() polls until timeout on hypercall error
- [Medium] PCI: kvm-msi: missing device_lock() in kvm_msi_attach_device()
--
commit 56d70781d8bf9094f446115196e63d6a77876b7c
Author: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
PCI: add KVM MSI domain guest module
This commit adds a guest-side PCI MSI IRQ domain driver for KVM virtual
machines that intercepts MSI composition and provides kvm_pci_msi_wait_ready()
and kvm_pci_msi_get_address() to obtain host physical MSI addresses via a KVM
hypercall for devices whose firmware programs MSI addresses into BAR registers.
> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index d246bbe37948e..cdf65d1c26741 100644
> --- a/drivers/pci/controller/Kconfig
> +++ b/drivers/pci/controller/Kconfig
> @@ -248,6 +248,18 @@ config PCI_HYPERV_INTERFACE
> drivers to have a common interface with the Hyper-V PCI frontend
> driver.
>
> +config PCI_KVM_MSI_DOMAIN
> + tristate "KVM PCI passthrough MSI domain"
> + depends on X86_64 && KVM_GUEST && PCI_MSI
> + select IRQ_MSI_LIB
[ ... ]
> diff --git a/drivers/pci/controller/pci-kvm-msi.c b/drivers/pci/controller/pci-kvm-msi.c
> new file mode 100644
> index 0000000000000..e2b0a4114aa88
> --- /dev/null
> +++ b/drivers/pci/controller/pci-kvm-msi.c
[ ... ]
> +struct kvm_msi_ctx {
> + struct pci_dev *pdev;
> + struct irq_domain *domain;
> + u32 devid;
> + unsigned int first_virq;
> + unsigned int nr_irqs;
> +};
> +
> +static struct kvm_msi_ctx kvm_msi_ctx;
> +
> +int kvm_pci_msi_wait_ready(struct pci_dev *pdev, unsigned long timeout_ms)
> +{
> + struct kvm_msi_response resp = {};
> + struct kvm_msi_irq_data *kvm_data;
> + unsigned int max_retries;
> + struct irq_data *irqd;
> + struct msi_desc *desc;
> + unsigned int retries;
> + long hret;
> + int i;
> +
> + if (!kvm_para_available())
> + return 0;
> +
> + if (!kvm_msi_domain)
> + return 0;
> +
> + if (!pdev || !kvm_msi_ctx.pdev || kvm_msi_ctx.pdev != pdev)
> + return 0;
> +
> + max_retries = timeout_ms / KVM_MSI_POLL_INTERVAL_MS;
> + if (!max_retries)
> + max_retries = 1;
> +
> + for (retries = 0; retries < max_retries; retries++) {
> + memset(&resp, 0, sizeof(resp));
> + hret = kvm_hypercall3(KVM_HC_PCI_MSI_ALLOC,
> + kvm_msi_ctx.devid, 0,
> + slow_virt_to_phys(&resp));
> +
> + if (hret == 0 && resp.address_lo != 0)
> + goto ready;
> +
> + msleep(KVM_MSI_POLL_INTERVAL_MS);
> + }
> +
> + pr_err("kvm-pci-msi: %s wait timed out after %lu ms\n",
> + pci_name(pdev), timeout_ms);
> + return -ETIMEDOUT;
[Severity: Medium]
Should kvm_pci_msi_wait_ready() in drivers/pci/controller/pci-kvm-msi.c
check for negative hypercall return values before sleeping and retrying?
In ____kvm_emulate_hypercall() in arch/x86/kvm/x86.c, KVM_HC_PCI_MSI_ALLOC
returns negative error codes on permanent failures, such as -KVM_ENOSYS when
the host kernel does not implement the hypercall or has no kvm-vfio device
(vcpu->kvm->pci_msi_alloc == NULL), and -KVM_EINVAL when the PCI device is not
found in kvm-vfio. It returns 0 with msg.address_lo == 0 only when the VFIO
device exists on the host and is waiting for MSI enablement.
Because the polling loop only checks whether hret == 0 && resp.address_lo != 0
and ignores hret < 0, running a guest on an older KVM host or with a device
not backed by kvm-vfio will sleep for the full timeout_ms duration on every
device power-up or reset and log a timeout error.
> +
> +ready:
> + pr_info("kvm-pci-msi: %s host addr=%08x:%08x data=%08x\n",
> + pci_name(pdev), resp.address_hi, resp.address_lo,
> + resp.data);
> +
> + for (i = 0; i < kvm_msi_ctx.nr_irqs; i++) {
> + irqd = irq_domain_get_irq_data(kvm_msi_ctx.domain,
> + kvm_msi_ctx.first_virq + i);
> + if (!irqd)
> + continue;
> + kvm_data = irqd->chip_data;
> + if (!kvm_data)
> + continue;
> +
> + kvm_data->msg.address_lo = resp.address_lo;
> + kvm_data->msg.address_hi = resp.address_hi;
> + kvm_data->msg.data = resp.data + i;
> + kvm_data->cached = true;
> + }
> +
> + desc = irq_get_msi_desc(pdev->irq);
> + if (desc) {
> + desc->msg.address_lo = resp.address_lo;
> + desc->msg.address_hi = resp.address_hi;
> + desc->msg.data = resp.data;
> + }
> +
> + return 1;
> +}
> +EXPORT_SYMBOL_GPL(kvm_pci_msi_wait_ready);
[ ... ]
> +static void kvm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> +{
> + struct kvm_msi_irq_data *kvm_data = data->chip_data;
> +
> + if (kvm_data && kvm_data->cached) {
> + *msg = kvm_data->msg;
> + return;
> + }
> +
> + kvm_parent_compose_msi_msg(data, msg);
> +}
[Severity: High]
Won't overwriting desc->msg in kvm_pci_msi_wait_ready() and returning the
cached host physical MSI message from kvm_compose_msi_msg() in
drivers/pci/controller/pci-kvm-msi.c corrupt the guest's virtual PCI MSI
config space when MSI state is restored or recomposed?
In a KVM guest with VFIO passthrough, the PCI config space MSI capability
(PCI_MSI_ADDRESS_LO, PCI_MSI_ADDRESS_HI, PCI_MSI_DATA) is emulated by QEMU
VFIO. QEMU traps guest config writes from __pci_write_msi_msg(), decodes them
as a guest virtual APIC MSI message (guest vCPU APIC ID and guest IDT vector),
and updates KVM's GSI routing table (KVM_SET_GSI_ROUTING). Only the device's
BAR MMIO registers programmed by firmware need the host's physical IOMMU IRTE
MSI address and data.
Because kvm_pci_msi_wait_ready() overwrites desc->msg with the host's physical
IRTE address/data and sets kvm_data->cached = true so kvm_compose_msi_msg()
returns kvm_data->msg, any subsequent PCI config space write by the guest MSI
core will write the host's physical IRTE message into QEMU's emulated PCI
config space:
1. On PCI reset or resume, __pci_restore_msi_state() calls
__pci_write_msi_msg(entry, &entry->msg), writing the overwritten desc->msg
to PCI config space.
2. If an IRQ is freed and re-requested (msi_domain_activate()) or recomposed
(msi_domain_set_affinity()), irq_chip_compose_msi_msg() calls
kvm_compose_msi_msg(), which returns the cached host IRTE message to
pci_msi_domain_write_msg() -> __pci_write_msi_msg().
On Intel VT-d interrupt remapping, the host IRTE data for subhandle 0 is 0, so
QEMU interprets the config space write as a guest APIC MSI targeting guest
vector 0, corrupting KVM GSI routing and breaking interrupt delivery to the
guest.
> +
> +static struct irq_chip kvm_msi_irq_chip = {
> + .name = "KVM-MSI",
> + .irq_compose_msi_msg = kvm_compose_msi_msg,
> + .irq_set_affinity = irq_chip_set_affinity_parent,
> + .irq_ack = irq_chip_ack_parent,
> +};
> +
> +static int kvm_pcie_domain_alloc(struct irq_domain *d, unsigned int virq,
> + unsigned int nr_irqs, void *arg)
> +{
> + struct irq_alloc_info *info = arg;
> + struct kvm_msi_irq_data *kvm_data;
> + struct msi_desc *desc;
> + struct pci_dev *pdev;
> + u32 devid;
> + int ret;
> + int i;
> +
> + ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, arg);
> + if (ret < 0)
> + return ret;
> +
> + desc = info->desc;
> + if (!desc || !desc->dev || !dev_is_pci(desc->dev)) {
> + ret = -EINVAL;
> + goto err_free_parent;
> + }
> +
> + pdev = to_pci_dev(desc->dev);
> + devid = ((u32)pdev->vendor << 16) | pdev->device;
> +
> + for (i = 0; i < nr_irqs; i++) {
> + kvm_data = kzalloc_obj(*kvm_data);
> + if (!kvm_data) {
> + ret = -ENOMEM;
> + goto err_free_data;
> + }
> +
> + kvm_data->devid = devid;
> + kvm_data->vector = desc->msi_index + i;
> +
> + irq_domain_set_info(d, virq + i, virq + i,
> + &kvm_msi_irq_chip, kvm_data,
> + handle_edge_irq, NULL, "KVM-MSI");
> + }
> +
> + kvm_msi_ctx.pdev = pdev;
> + kvm_msi_ctx.devid = devid;
> + kvm_msi_ctx.first_virq = virq;
> + kvm_msi_ctx.nr_irqs = nr_irqs;
> + kvm_msi_ctx.domain = d;
[Severity: High]
What happens in kvm_pcie_domain_alloc() in drivers/pci/controller/pci-kvm-msi.c
when more than one matching PCI device is present in the VM, or when a device
allocates multiple MSI-X vectors?
1. kvm_pci_msi_init() and kvm_msi_bus_notify() attach kvm_msi_domain to all
PCI devices matching kvm_msi_devids, but kvm_msi_ctx is a single global
structure that kvm_pcie_domain_alloc() overwrites on every allocation. If
a second matching device probes and allocates MSI vectors, it overwrites
kvm_msi_ctx.pdev, causing subsequent calls to kvm_pci_msi_wait_ready() or
runtime calls to kvm_pci_msi_get_address() for the first device to fail the
kvm_msi_ctx.pdev != pdev check and return 0.
2. kvm_pcie_msi_parent_ops sets MSI_FLAG_PCI_MSIX in supported_flags. For
MSI-X, __msi_domain_alloc_irqs() calls __irq_domain_alloc_irqs() ->
kvm_pcie_domain_alloc() once per MSI-X descriptor with nr_irqs = 1. Each
vector allocation overwrites kvm_msi_ctx.first_virq = virq and
kvm_msi_ctx.nr_irqs = 1, losing all earlier vectors so
kvm_pci_msi_wait_ready() only populates the last vector with vector 0's
data (and irq_get_msi_desc(pdev->irq) returns NULL for MSI-X because
pdev->irq is not set).
3. Conversely, for Multi-MSI, kvm_pcie_msi_parent_ops.supported_flags omits
MSI_FLAG_MULTI_PCI_MSI, so msi_lib_init_dev_msi_info() masks out
MSI_FLAG_MULTI_PCI_MSI from pci_msi_template even when the parent domain
supports it.
> +
> + return 0;
> +
> +err_free_data:
> + for (i--; i >= 0; i--) {
> + kvm_data = irq_data_get_irq_chip_data(
> + irq_domain_get_irq_data(d, virq + i));
> + kfree(kvm_data);
> + }
> +err_free_parent:
> + irq_domain_free_irqs_parent(d, virq, nr_irqs);
> + return ret;
> +}
> +
> +static void kvm_pcie_domain_free(struct irq_domain *d, unsigned int virq,
> + unsigned int nr_irqs)
> +{
> + struct kvm_msi_irq_data *kvm_data;
> + int i;
> +
> + if (kvm_msi_ctx.first_virq == virq) {
> + kvm_msi_ctx.pdev = NULL;
> + kvm_msi_ctx.nr_irqs = 0;
> + }
> +
> + for (i = 0; i < nr_irqs; i++) {
> + kvm_data = irq_data_get_irq_chip_data(
> + irq_domain_get_irq_data(d, virq + i));
> + kfree(kvm_data);
> + }
> + irq_domain_free_irqs_top(d, virq, nr_irqs);
> +}
[Severity: High]
Can kvm_pci_msi_wait_ready() or kvm_pci_msi_get_address() race with
kvm_pcie_domain_free() in drivers/pci/controller/pci-kvm-msi.c and trigger a
use-after-free on kvm_data?
kvm_pcie_domain_alloc() and kvm_pcie_domain_free() run under
domain->root->mutex, whereas kvm_pci_msi_wait_ready() and
kvm_pci_msi_get_address() read kvm_msi_ctx, call irq_domain_get_irq_data(),
and dereference irqd->chip_data (kvm_data) without holding any lock.
In kvm_pci_msi_wait_ready(), kvm_msi_ctx.pdev != pdev is checked only once at
entry before the loop calls msleep(KVM_MSI_POLL_INTERVAL_MS). Meanwhile,
kvm_pcie_domain_free() calls kfree(kvm_data) before irq_domain_free_irqs_top()
clears irq_data->chip_data and unmaps the virq. If a device's IRQs are freed
(or another device probes or unwinds) while kvm_pci_msi_wait_ready() is
sleeping or while kvm_pci_msi_get_address() is running, they can read or write
freed kvm_data memory.
> +
> +static const struct irq_domain_ops kvm_pcie_domain_ops = {
> + .alloc = kvm_pcie_domain_alloc,
> + .free = kvm_pcie_domain_free,
> +};
> +
> +static bool kvm_pcie_init_dev_msi_info(struct device *dev,
> + struct irq_domain *domain,
> + struct irq_domain *real_parent,
> + struct msi_domain_info *info)
> +{
> + struct irq_chip *chip = info->chip;
> +
> + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) {
> + pr_err("kvm-pci-msi: msi_lib_init_dev_msi_info failed for %s\n",
> + dev_name(dev));
> + return false;
> + }
> +
> + info->ops->msi_prepare = pci_msi_prepare;
> +
> + chip->irq_set_affinity = irq_chip_set_affinity_parent;
> + chip->irq_retrigger = irq_chip_retrigger_hierarchy;
> + chip->flags |= IRQCHIP_MOVE_DEFERRED;
> +
> + return true;
> +}
[Severity: High]
Does overwriting chip->irq_set_affinity with irq_chip_set_affinity_parent in
kvm_pcie_init_dev_msi_info() in drivers/pci/controller/pci-kvm-msi.c break
guest MSI interrupt delivery whenever IRQ affinity is set or changed?
In msi_lib_init_dev_msi_info() in drivers/irqchip/irq-msi-lib.c, the
per-device MSI irq_chip's irq_set_affinity callback is initialized to
msi_domain_set_affinity():
if (!chip->irq_set_affinity && !(info->flags & MSI_FLAG_NO_AFFINITY))
chip->irq_set_affinity = msi_domain_set_affinity;
msi_domain_set_affinity() calls parent->chip->irq_set_affinity() and then
calls irq_chip_compose_msi_msg() and irq_chip_write_msi_msg()
(pci_msi_domain_write_msg() -> __pci_write_msi_msg()) so that the updated
guest virtual APIC target CPU and vector are written to PCI config space and
trapped by QEMU VFIO to update KVM's GSI routing.
By overwriting chip->irq_set_affinity on the per-device MSI chip with
irq_chip_set_affinity_parent (while kvm_msi_irq_chip also uses
irq_chip_set_affinity_parent), any affinity change (such as
ath11k_pci_set_irq_affinity_hint() -> irq_set_affinity_and_hint() during probe
or irqbalance in userspace) delegates directly to x86_vector_domain's
apic_set_affinity(). That allocates a new guest vector/CPU and returns
IRQ_SET_MASK_OK without ever composing or writing the new MSI message to PCI
config space, leaving msi_desc->msg and QEMU/KVM GSI routing pointing to the
old guest vector.
[ ... ]
> +static void kvm_msi_attach_device(struct pci_dev *pdev)
> +{
> + if (pdev->driver) {
> + dev_warn(&pdev->dev,
> + "kvm-pci-msi: driver already bound (%s), unbind/rebind needed\n",
> + pdev->driver->name);
> + return;
> + }
> +
> + dev_info(&pdev->dev,
> + "kvm-pci-msi: attaching KVM MSI domain [%04x:%04x]\n",
> + pdev->vendor, pdev->device);
> + dev_set_msi_domain(&pdev->dev, kvm_msi_domain);
> +}
[Severity: Medium]
Can kvm_msi_attach_device() in drivers/pci/controller/pci-kvm-msi.c race with
concurrent driver probe or unbind when called from kvm_pci_msi_init() without
holding device_lock(&pdev->dev)?
In drivers/pci/pci-driver.c, local_pci_probe() and pci_device_remove() set and
clear pdev->driver under device_lock(&pdev->dev). When kvm_pci_msi_init()
iterates over existing PCI devices with for_each_pci_dev(pdev) and calls
kvm_msi_attach_device(pdev) without holding device_lock(&pdev->dev), a
concurrent unbind or failed probe can clear pdev->driver between the
if (pdev->driver) check and the pdev->driver->name dereference, or a
concurrent probe can race with dev_set_msi_domain(&pdev->dev, kvm_msi_domain)
while setting up MSI vectors.
[ ... ]
> +static int __init kvm_pci_msi_init(void)
> +{
> + struct pci_dev *pdev = NULL;
> + struct pci_dev *first = NULL;
> + int ret;
> +
> + if (!kvm_para_available())
> + return -ENODEV;
> +
> + for_each_pci_dev(pdev) {
> + if (pci_match_id(kvm_msi_devids, pdev)) {
> + first = pdev;
> + break;
> + }
> + }
> +
> + if (!first) {
> + pr_info("kvm-pci-msi: no matching devices found\n");
> + return -ENODEV;
> + }
> +
> + ret = kvm_msi_create_domain(first);
> + pci_dev_put(first);
> + if (ret)
> + return ret;
> +
> + pdev = NULL;
> + for_each_pci_dev(pdev) {
> + if (pci_match_id(kvm_msi_devids, pdev))
> + kvm_msi_attach_device(pdev);
> + }
> +
> + bus_register_notifier(&pci_bus_type, &kvm_msi_nb);
> +
> + pr_info("kvm-pci-msi: ready, domain created for %zu device types\n",
> + ARRAY_SIZE(kvm_msi_devids) - 1);
> + return 0;
> +}
[Severity: High]
Won't returning -ENODEV from kvm_pci_msi_init() in
drivers/pci/controller/pci-kvm-msi.c prevent dependent wireless drivers from
loading and break PCI hotplug?
1. When CONFIG_PCI_KVM_MSI_DOMAIN=m, consumer modules (such as ath11k_pci.ko
and ath12k.ko) reference the exported symbols kvm_pci_msi_wait_ready() and
kvm_pci_msi_get_address(). When modprobe loads pci-kvm-msi.ko on baremetal
(!kvm_para_available()) or when no device in kvm_msi_devids is currently
present (!first, for example with other ath11k/ath12k PCI IDs or before
hotplug), kvm_pci_msi_init() returns -ENODEV. That causes pci-kvm-msi.ko
to fail to load, which in turn prevents ath11k_pci.ko and ath12k.ko from
loading due to unresolved symbols.
2. Because bus_register_notifier(&pci_bus_type, &kvm_msi_nb) is only reached
if a matching PCI device already exists when kvm_pci_msi_init() runs,
hotplugging a matching VFIO PCI device later will never attach
kvm_msi_domain.
3. In kvm_msi_attach_device(), if pdev->driver is already bound at init time,
it warns that unbind/rebind is needed and skips dev_set_msi_domain().
However, kvm_msi_bus_notify() only acts on BUS_NOTIFY_ADD_DEVICE (which
fires on device_add(), not on driver unbind/rebind), so unbinding and
rebinding the driver never attaches kvm_msi_domain.
> +
> +static void __exit kvm_pci_msi_exit(void)
> +{
> + struct fwnode_handle *fwnode;
> +
> + bus_unregister_notifier(&pci_bus_type, &kvm_msi_nb);
> +
> + if (kvm_msi_domain) {
> + fwnode = kvm_msi_domain->fwnode;
> + irq_domain_remove(kvm_msi_domain);
> + irq_domain_free_fwnode(fwnode);
> + kvm_msi_domain = NULL;
> + }
> +}
[Severity: High]
Doesn't kvm_pci_msi_exit() in drivers/pci/controller/pci-kvm-msi.c leave
dangling pointers to the freed kvm_msi_domain on attached PCI devices when the
module is unloaded?
During kvm_pci_msi_init() and kvm_msi_bus_notify(), kvm_msi_attach_device()
overwrites pdev->dev.msi.domain with kvm_msi_domain via dev_set_msi_domain()
without saving the original parent MSI domain. In addition, when a driver
allocates MSI vectors via pci_alloc_irq_vectors() ->
pci_setup_msi_device_domain() -> msi_create_device_irq_domain(), a per-device
child irq_domain is created in pdev->dev.msi.data->__domains with
domain->parent pointing to kvm_msi_domain, and that child domain persists
across pci_free_irq_vectors() and driver unbind until the pci_dev is removed.
When kvm_pci_msi_exit() runs on module unload, it calls
irq_domain_remove(kvm_msi_domain) (which frees kvm_msi_domain) without
removing per-device child MSI domains or restoring pdev->dev.msi.domain on
attached PCI devices:
1. Any subsequent driver probe, MSI allocation (msi_create_device_irq_domain()
dereferencing parent = dev->msi.domain and
parent->msi_parent_ops->init_dev_msi_info), or PCI device removal will
dereference the freed kvm_msi_domain and unmapped module callbacks.
2. Reloading pci-kvm-msi after rmmod causes kvm_msi_create_domain() to call
dev_get_msi_domain(&ref_dev->dev), which returns the freed kvm_msi_domain
from the previous load and passes it as info.parent to
msi_create_parent_irq_domain().
> diff --git a/include/linux/pci-kvm-msi.h b/include/linux/pci-kvm-msi.h
> new file mode 100644
> index 0000000000000..cc615e913a3bf
> --- /dev/null
> +++ b/include/linux/pci-kvm-msi.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* SPDX-FileCopyrightText: Copyright Red Hat */
> +
> +#ifndef _LINUX_PCI_KVM_MSI_H
> +#define _LINUX_PCI_KVM_MSI_H
> +
> +#include <linux/pci.h>
> +
> +int kvm_pci_msi_wait_ready(struct pci_dev *pdev, unsigned long timeout_ms);
> +int kvm_pci_msi_get_address(struct pci_dev *pdev, u32 *addr_lo, u32 *addr_hi,
> + u32 *data);
> +
> +#endif /* _LINUX_PCI_KVM_MSI_H */
[Severity: Medium]
Should include/linux/pci-kvm-msi.h provide static inline fallback stubs
guarded by IS_REACHABLE(CONFIG_PCI_KVM_MSI_DOMAIN)?
Because PCI_KVM_MSI_DOMAIN is a tristate Kconfig option, a built-in consumer
driver (=y) calling kvm_pci_msi_wait_ready() or kvm_pci_msi_get_address()
under IS_ENABLED(CONFIG_PCI_KVM_MSI_DOMAIN) when CONFIG_PCI_KVM_MSI_DOMAIN=m
(or an unguarded caller when CONFIG_PCI_KVM_MSI_DOMAIN=n) will fail to link
vmlinux with undefined references to kvm_pci_msi_wait_ready() and
kvm_pci_msi_get_address().
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029163713.1366077-1-jtornosm@redhat.com?part=3
next prev parent reply other threads:[~2026-10-29 17:06 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 16:37 [PATCH v3 0/8] PCI/KVM/VFIO: MSI address passthrough for Qualcomm WiFi devices Jose Ignacio Tornos Martinez
2026-10-29 16:37 ` [PATCH v3 1/8] vfio: add helper to find PCI device by vendor/device ID Jose Ignacio Tornos Martinez
2026-10-29 16:53 ` sashiko-bot
2026-10-29 16:37 ` [PATCH v3 2/8] KVM: add PCI MSI hypercall for VFIO passthrough Jose Ignacio Tornos Martinez
2026-10-29 16:58 ` Jason Gunthorpe
2026-10-29 16:59 ` sashiko-bot
2026-10-29 16:37 ` [PATCH v3 3/8] PCI: add KVM MSI domain guest module Jose Ignacio Tornos Martinez
2026-10-29 17:06 ` sashiko-bot [this message]
2026-10-29 16:37 ` [PATCH v3 4/8] ath11k: add PCIe link recovery retry Jose Ignacio Tornos Martinez
2026-10-29 16:37 ` [PATCH v3 5/8] ath11k: use KVM MSI domain for VM passthrough Jose Ignacio Tornos Martinez
2026-10-29 16:54 ` sashiko-bot
2026-10-29 17:00 ` Jason Gunthorpe
2026-10-29 16:37 ` [PATCH v3 6/8] ath12k: add PCIe link recovery retry Jose Ignacio Tornos Martinez
2026-10-29 16:37 ` [PATCH v3 7/8] ath12k: use KVM MSI domain for VM passthrough Jose Ignacio Tornos Martinez
2026-10-29 17:04 ` sashiko-bot
2026-10-29 16:37 ` [PATCH v3 8/8] PCI: add QCN9274 to reset quirks and KVM MSI domain Jose Ignacio Tornos Martinez
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=sashiko-outbox-189718@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=jtornosm@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox