Scan the pci bus to make sure there's no vfio-pci device attached before vIOMMU is realized.
Suggested-by: Igor Mammedov <imamm...@redhat.com> Signed-off-by: Peter Xu <pet...@redhat.com> --- hw/i386/x86-iommu.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c index 86ad03972e..58abce7edc 100644 --- a/hw/i386/x86-iommu.c +++ b/hw/i386/x86-iommu.c @@ -21,6 +21,7 @@ #include "hw/sysbus.h" #include "hw/i386/x86-iommu.h" #include "hw/qdev-properties.h" +#include "hw/vfio/pci.h" #include "hw/i386/pc.h" #include "qapi/error.h" #include "qemu/error-report.h" @@ -103,6 +104,16 @@ IommuType x86_iommu_get_type(void) return x86_iommu_default->type; } +static void x86_iommu_pci_dev_hook(PCIBus *bus, PCIDevice *dev, void *opaque) +{ + Error **errp = (Error **)opaque; + + if (object_dynamic_cast(OBJECT(dev), TYPE_VFIO_PCI)) { + error_setg(errp, "Device '%s' must be specified before vIOMMUs", + TYPE_VFIO_PCI); + } +} + static void x86_iommu_realize(DeviceState *dev, Error **errp) { X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev); @@ -120,6 +131,12 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp) return; } + /* Make sure there's no special device plugged before vIOMMU */ + pci_for_each_device_all(x86_iommu_pci_dev_hook, (void *)errp); + if (*errp) { + return; + } + /* If the user didn't specify IR, choose a default value for it */ if (x86_iommu->intr_supported == ON_OFF_AUTO_AUTO) { x86_iommu->intr_supported = irq_all_kernel ? @@ -151,6 +168,7 @@ static Property x86_iommu_properties[] = { static void x86_iommu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = x86_iommu_realize; device_class_set_props(dc, x86_iommu_properties); } -- 2.32.0