Call pci_device_get_viommu_cap() to get if vIOMMU supports VIOMMU_CAP_STAGE1, if yes, create nested parent domain which could be reused by vIOMMU to create nested domain.
Suggested-by: Nicolin Chen <nicol...@nvidia.com> Suggested-by: Yi Liu <yi.l....@intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- hw/vfio/iommufd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index d3efef71af..83a632bdee 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -20,6 +20,7 @@ #include "trace.h" #include "qapi/error.h" #include "system/iommufd.h" +#include "hw/iommu.h" #include "hw/qdev-core.h" #include "hw/vfio/vfio-cpr.h" #include "system/reset.h" @@ -352,6 +353,19 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev, flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING; } + /* + * If vIOMMU supports stage-1 translation, force to create nested parent + * domain which could be reused by vIOMMU to create nested domain. + */ + if (vbasedev->type == VFIO_DEVICE_TYPE_PCI) { + VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); + + hw_caps = pci_device_get_viommu_cap(&vdev->pdev); + if (hw_caps & VIOMMU_CAP_STAGE1) { + flags |= IOMMU_HWPT_ALLOC_NEST_PARENT; + } + } + if (!iommufd_backend_alloc_hwpt(iommufd, vbasedev->devid, container->ioas_id, flags, IOMMU_HWPT_DATA_NONE, 0, NULL, -- 2.34.1