On 10/15/2026 2:38 PM, Clément MATHIEU--DRIF wrote:
> [Some people who received this message don't often get email from
> [email protected]. Learn why this is important at
> https://aka.ms/LearnAboutSenderIdentification ]
>
> On Wed, 2026-10-14 at 11:04 +0530, Sairaj Kodilkar wrote:
>> Caution: External email. Do not open attachments or click links, unless this
>> email comes from a known sender and you know the content is safe.
>>
>>
>> kvm_arch_fixup_msi_route() and kvm_arch_add_msi_route_post() use
>> x86_iommu_get_default() whenever an IOMMU is present. This selects the
>> correct unit only when a single IOMMU is attached to the system bus.
>>
>> The following patches allow an IOMMU to attach to a different bus and
>> isolate the subset of devices below it. Each IOMMU then serves only part
>> of the PCI topology, so interrupt remapping must determine the IOMMU that
>> actually serves a given device.
>>
>> Add x86_iommu_device_get() to locate the IOMMU bus for a PCI device and
>> retrieve its X86IOMMUState through a new get_x86_iommu callback.
>>
>> Signed-off-by: Sairaj Kodilkar <[[email protected]](mailto:[email protected])>
>> ---
>> hw/i386/x86-iommu-stub.c | 5 +++++
>> hw/i386/x86-iommu.c | 16 ++++++++++++++++
>> include/hw/i386/x86-iommu.h | 6 ++++++
>> include/hw/pci/pci.h | 12 ++++++++++++
>> 4 files changed, 39 insertions(+)
>>
>> diff --git a/hw/i386/x86-iommu-stub.c b/hw/i386/x86-iommu-stub.c
>> index 781b5ff92227..b0383d2290b1 100644
>> --- a/hw/i386/x86-iommu-stub.c
>> +++ b/hw/i386/x86-iommu-stub.c
>> @@ -32,6 +32,11 @@ X86IOMMUState *x86_iommu_get_default(void)
>> return NULL;
>> }
>>
>> +X86IOMMUState *x86_iommu_device_get(PCIDevice *dev)
>> +{
>> + return NULL;
>> +}
>> +
>> bool x86_iommu_ir_supported(X86IOMMUState *s)
>> {
>> return false;
>> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
>> index a57445404ef8..601db5cfea09 100644
>> --- a/hw/i386/x86-iommu.c
>> +++ b/hw/i386/x86-iommu.c
>> @@ -26,6 +26,7 @@
>> #include "qemu/error-report.h"
>> #include "trace.h"
>> #include "system/kvm.h"
>> +#include "hw/pci/pci_bus.h"
>>
>> void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
>> iec_notify_fn fn, void *data)
>> @@ -90,6 +91,21 @@ X86IOMMUState *x86_iommu_get_default(void)
>> return NULL;
>> }
>>
>> +X86IOMMUState *x86_iommu_device_get(PCIDevice *dev)
>> +{
>> + PCIBus *iommu_bus;
>> + X86IOMMUState *iommu = NULL;
>> +
>> + pci_device_get_iommu_bus_devfn(dev, &iommu_bus, NULL, NULL);
>> +
>> + if (iommu_bus && iommu_bus->iommu_ops->get_x86_iommu) {
>> + iommu_bus->iommu_ops->get_x86_iommu(iommu_bus->iommu_opaque,
>> + (void **)&iommu);
>> + }
>> +
>> + return iommu;
>> +}
>> +
>> static void x86_iommu_realize(DeviceState *dev, Error **errp)
>> {
>> X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
>> diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h
>> index 0a1e1ba72571..eb575271e9d7 100644
>> --- a/include/hw/i386/x86-iommu.h
>> +++ b/include/hw/i386/x86-iommu.h
>> @@ -134,6 +134,12 @@ struct X86IOMMU_MSIMessage {
>> */
>> X86IOMMUState *x86_iommu_get_default(void);
>>
>> +/**
>> + * x86_iommu_device_get - get IOMMU device for given PCI device
>> + * @return: pointer to default IOMMU device
>> + */
>> +X86IOMMUState *x86_iommu_device_get(PCIDevice *dev);
>> +
>> /**
>> * x86_iommu_iec_register_notifier - register IEC (Interrupt Entry
>> * Cache) notifiers
>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>> index f2448e941a0b..f3c4c3a4db56 100644
>> --- a/include/hw/pci/pci.h
>> +++ b/include/hw/pci/pci.h
>> @@ -698,6 +698,18 @@ typedef struct PCIIOMMUOps {
>> * Returns: the guest physical address of the MSI doorbell.
>> */
>> uint64_t (*get_msi_direct_gpa)(PCIBus *bus, void *opaque, int devfn);
>> +
>> + /**
>> + * @get_x86_iommu: get parent x86-iommu for given hardware (AMD/Intel)
>> + *
>> + * Callback is required if IOMMU defines x86->int_remap()
>> + *
>> + * @opaque: the data passed to pci_setup_iommu()
>> + *
>> + * @x86_iommu: A pointer to store the x86-iommu object
>> + */
>> + int (*get_x86_iommu)(void *opaque, void **x86_iommu);
>
> Are you using void ** because the X86 type is not defined when building for
> another target?
> I'm not sure if the Qemu rules are strict about architecture isolation.
including x86-iommu.h inside pci.h will cause circular dependancy as
x86-iommu.h already depends on pci.h
>
> Do you have any idea about how acceptable this is?
At this point I am not sure and dont see any other way to do this
>
> Is there a reason why we could not expose the API in the same files as
> x86_iommu_get_default?
x86_iommu_get_default() uses machine state to fetch the iommu device,
because of which it does not depend on device/pci topology. Whereas, the
goal of this series is to have a PCI device isolation, so kvm layer has
to fetch device specific iommu by traversing pci topology using
pci_device_get_iommu_bus_devfn(). Hence we cannot expose the API in
x86_iommu_get_default().
Thanks
Sairaj
>
>> +
>> } PCIIOMMUOps;
>>
>> bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus,
>> --
>> 2.34.1
>>