On 11/17/25 10:37 AM, Zhenzhong Duan wrote: > Currently we don't support nested translation for passthrough device with > emulated device under same PCI bridge, because they require different address > space when x-flts=on. > > In theory, we do support if devices under same PCI bridge are all passthrough > devices. But emulated device can be hotplugged under same bridge. To simplify, > just forbid passthrough device under PCI bridge no matter if there is, or will > be emulated devices under same bridge. This is acceptable because PCIE bridge > is more popular than PCI bridge now. > > Suggested-by: Yi Liu <[email protected]> > Signed-off-by: Zhenzhong Duan <[email protected]> As this looks like a simple move compared to v7, feel free to keep my Reviewed-by: Eric Auger <[email protected]> and thanks for the heads up Eric > --- > hw/i386/intel_iommu_accel.h | 4 ++-- > hw/i386/intel_iommu.c | 7 ++++--- > hw/i386/intel_iommu_accel.c | 12 +++++++++++- > 3 files changed, 17 insertions(+), 6 deletions(-) > > diff --git a/hw/i386/intel_iommu_accel.h b/hw/i386/intel_iommu_accel.h > index c5274e342c..7ebf137a1a 100644 > --- a/hw/i386/intel_iommu_accel.h > +++ b/hw/i386/intel_iommu_accel.h > @@ -13,11 +13,11 @@ > #include CONFIG_DEVICES > > #ifdef CONFIG_VTD_ACCEL > -bool vtd_check_hiod_accel(IntelIOMMUState *s, HostIOMMUDevice *hiod, > +bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod, > Error **errp); > #else > static inline bool vtd_check_hiod_accel(IntelIOMMUState *s, > - HostIOMMUDevice *hiod, > + VTDHostIOMMUDevice *vtd_hiod, > Error **errp) > { > error_setg(errp, > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c > index d3c8a75878..4ebf56a74f 100644 > --- a/hw/i386/intel_iommu.c > +++ b/hw/i386/intel_iommu.c > @@ -4571,9 +4571,10 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, > PCIBus *bus, > return vtd_dev_as; > } > > -static bool vtd_check_hiod(IntelIOMMUState *s, HostIOMMUDevice *hiod, > +static bool vtd_check_hiod(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod, > Error **errp) > { > + HostIOMMUDevice *hiod = vtd_hiod->hiod; > HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_GET_CLASS(hiod); > int ret; > > @@ -4597,7 +4598,7 @@ static bool vtd_check_hiod(IntelIOMMUState *s, > HostIOMMUDevice *hiod, > return true; > } > > - return vtd_check_hiod_accel(s, hiod, errp); > + return vtd_check_hiod_accel(s, vtd_hiod, errp); > } > > static bool vtd_dev_set_iommu_device(PCIBus *bus, void *opaque, int devfn, > @@ -4633,7 +4634,7 @@ static bool vtd_dev_set_iommu_device(PCIBus *bus, void > *opaque, int devfn, > vtd_hiod->iommu_state = s; > vtd_hiod->hiod = hiod; > > - if (!vtd_check_hiod(s, hiod, errp)) { > + if (!vtd_check_hiod(s, vtd_hiod, errp)) { > g_free(vtd_hiod); > vtd_iommu_unlock(s); > return false; > diff --git a/hw/i386/intel_iommu_accel.c b/hw/i386/intel_iommu_accel.c > index 6846c6ec4d..ead6c42879 100644 > --- a/hw/i386/intel_iommu_accel.c > +++ b/hw/i386/intel_iommu_accel.c > @@ -12,12 +12,16 @@ > #include "system/iommufd.h" > #include "intel_iommu_internal.h" > #include "intel_iommu_accel.h" > +#include "hw/pci/pci_bus.h" > > -bool vtd_check_hiod_accel(IntelIOMMUState *s, HostIOMMUDevice *hiod, > +bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod, > Error **errp) > { > + HostIOMMUDevice *hiod = vtd_hiod->hiod; > struct HostIOMMUDeviceCaps *caps = &hiod->caps; > struct iommu_hw_info_vtd *vtd = &caps->vendor_caps.vtd; > + PCIBus *bus = vtd_hiod->bus; > + PCIDevice *pdev = bus->devices[vtd_hiod->devfn]; > > if (!object_dynamic_cast(OBJECT(hiod), TYPE_HOST_IOMMU_DEVICE_IOMMUFD)) { > error_setg(errp, "Need IOMMUFD backend when x-flts=on"); > @@ -36,6 +40,12 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s, > HostIOMMUDevice *hiod, > return false; > } > > + if (pci_device_get_iommu_bus_devfn(pdev, &bus, NULL, NULL)) { > + error_setg(errp, "Host device downstream to a PCI bridge is " > + "unsupported when x-flts=on"); > + return false; > + } > + > error_setg(errp, > "host IOMMU is incompatible with guest first stage > translation"); > return false;
