Re: [PATCH v3 2/8] KVM: add PCI MSI hypercall for VFIO passthrough
From: Jason Gunthorpe
Date: Thu Oct 29 2026 - 12:59:03 EST
On Thu, Oct 29, 2026 at 05:37:07PM +0100, Jose Ignacio Tornos Martinez wrote:
> Some PCI devices (e.g. Qualcomm WiFi adapters) have firmware that
> programs MSI addresses directly into device BAR registers, bypassing
> the standard PCI config MSI path. When these devices are passed
> through to VMs via VFIO, the firmware programs the guest virtual MSI
> address instead of the host physical IRTE address, causing DMAR faults
> and non-functional interrupts.
>
> Add a KVM hypercall (KVM_HC_PCI_MSI_ALLOC) that allows a guest to
> request the host's physical MSI address/data for a VFIO-assigned PCI
> device. The hypercall is dispatched from the x86 hypercall handler to
> a VFIO backend that:
>
> 1. Finds the host PCI device matching the guest's vendor:device ID
> using vfio_file_find_pci_device() (introduced in a previous patch)
> 2. Reads the host MSI address/data from the device's msi_desc or
> by walking the IRQ domain compose chain
> 3. Returns the result to the guest via a GPA response buffer
This is not quite what I suggested, this still relies on the host
setting up the msi using the trapped MSI emulation, which is the
primary hack..
Was it too hard to make this an 'allocate msi' operation?
> The VFIO handler is connected to the KVM instance via a function
> pointer (pci_msi_alloc) in struct kvm, set when the VFIO device is
> created and cleared on release. This avoids a hard dependency between
> KVM and VFIO subsystems.
I feel like VFIO shouldn't be involved here, for the purpose of MSI
all we need is to inform KVM what struct pci_device * is at a vBDF and
then KVM can do the interrupt bits. Maybe this is already happening?
> + case KVM_HC_PCI_MSI_ALLOC: {
> + struct msi_msg msg = {};
> + struct {
> + u32 address_lo;
> + u32 address_hi;
> + u32 data;
> + u32 reserved;
> + } resp;
> +
> + if (vcpu->kvm->pci_msi_alloc == NULL) {
> + ret = -KVM_ENOSYS;
> + break;
> + }
Yet here it is called alloc?
Nothing should use vendor/device ID either, it should all be drive on
vBDF.
> + irq = pci_irq_vector(pdev, vector);
> + if (irq <= 0) {
> + memset(msg, 0, sizeof(*msg));
> + return 0;
> + }
> +
> + irqd = irq_get_irq_data(irq);
> + if (!irqd) {
> + memset(msg, 0, sizeof(*msg));
> + return 0;
> + }
> +
> + desc = irq_get_msi_desc(irq);
> + if (desc) {
> + *msg = desc->msg;
And this isn't alloc, it is some query..
I think kvm maintainers would insist on a complete API here if this is
the direction.
I probably would not have selected this, it is why I suggested
virtio-msi or something that could be optional and seperate from the
core KVM guest ABI.
But maybe there is interest in doing it this way?
Jason