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. Do you have any idea about how acceptable this is? Is there a reason why we could not expose the API in the same files as x86_iommu_get_default? > + > } PCIIOMMUOps; > > bool pci_device_get_iommu_bus_devfn(PCIDevice *dev, PCIBus **piommu_bus, > -- > 2.34.1 >
