From: Zhenzhong Duan Date: Tue, 6 Jan 2026 06:12:50 +0000 (-0500) Subject: vfio/iommufd: Force creating nesting parent HWPT X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3459c6bfaad6a3d0bef4d3ebc6753bb3e66c1ef;p=thirdparty%2Fqemu.git vfio/iommufd: Force creating nesting parent HWPT Call pci_device_get_viommu_flags() to get if vIOMMU supports VIOMMU_FLAG_WANT_NESTING_PARENT. If yes, create a nesting parent HWPT and add it to the container's hwpt_list, letting this parent HWPT cover the entire second stage mappings (GPA=>HPA). This allows a VFIO passthrough device to directly attach to this default HWPT and then to use the system address space and its listener. Introduce a vfio_device_get_viommu_flags_want_nesting() helper to facilitate this implementation. It is safe to do so because a vIOMMU will be able to fail in set_iommu_device() call, if something else related to the VFIO device or vIOMMU isn't compatible. Suggested-by: Nicolin Chen Suggested-by: Yi Liu Signed-off-by: Zhenzhong Duan Reviewed-by: Nicolin Chen Reviewed-by: Eric Auger Reviewed-by: Yi Liu Reviewed-by: Michael S. Tsirkin Link: https://lore.kernel.org/qemu-devel/20260106061304.314546-9-zhenzhong.duan@intel.com Signed-off-by: Cédric Le Goater --- diff --git a/hw/vfio/device.c b/hw/vfio/device.c index 19d1236ed7..100532f35d 100644 --- a/hw/vfio/device.c +++ b/hw/vfio/device.c @@ -23,6 +23,7 @@ #include "hw/vfio/vfio-device.h" #include "hw/vfio/pci.h" +#include "hw/core/iommu.h" #include "hw/core/hw-error.h" #include "trace.h" #include "qapi/error.h" @@ -515,6 +516,17 @@ void vfio_device_unprepare(VFIODevice *vbasedev) vbasedev->bcontainer = NULL; } +bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev) +{ + VFIOPCIDevice *vdev = vfio_pci_from_vfio_device(vbasedev); + + if (vdev) { + return !!(pci_device_get_viommu_flags(PCI_DEVICE(vdev)) & + VIOMMU_FLAG_WANT_NESTING_PARENT); + } + return false; +} + /* * Traditional ioctl() based io */ diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index 32e8615ad3..e5328c63a3 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -361,6 +361,15 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev, flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING; } + /* + * If vIOMMU requests VFIO's cooperation to create nesting parent HWPT, + * force to create it so that it could be reused by vIOMMU to create + * nested HWPT. + */ + if (vfio_device_get_viommu_flags_want_nesting(vbasedev)) { + flags |= IOMMU_HWPT_ALLOC_NEST_PARENT; + } + if (cpr_is_incoming()) { hwpt_id = vbasedev->cpr.hwpt_id; goto skip_alloc; diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h index 0fe6c60ba2..0bc877ff62 100644 --- a/include/hw/vfio/vfio-device.h +++ b/include/hw/vfio/vfio-device.h @@ -257,6 +257,8 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainer *bcontainer, void vfio_device_unprepare(VFIODevice *vbasedev); +bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev); + int vfio_device_get_region_info(VFIODevice *vbasedev, int index, struct vfio_region_info **info); int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type,