VFIO needs to check VFIO_TYPE1_NESTING_IOMMU support with Kernel before further using it. e.g. requires to check IOMMU UAPI support. Referred patch from Eric Auger: https://patchwork.kernel.org/patch/11040499/ Cc: Kevin Tian <kevin.tian@xxxxxxxxx> Cc: Jacob Pan <jacob.jun.pan@xxxxxxxxxxxxxxx> Cc: Peter Xu <peterx@xxxxxxxxxx> Cc: Eric Auger <eric.auger@xxxxxxxxxx> Cc: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> Cc: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> Cc: Alex Williamson <alex.williamson@xxxxxxxxxx> Signed-off-by: Liu Yi L <yi.l.liu@xxxxxxxxx> Signed-off-by: Eric Auger <eric.auger@xxxxxxxxxx> Signed-off-by: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> --- hw/vfio/common.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 89c6a25..b85fbcf 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -1152,30 +1152,44 @@ static void vfio_put_address_space(VFIOAddressSpace *space) } /* - * vfio_get_iommu_type - selects the richest iommu_type (v2 first) + * vfio_get_iommu_type - selects the richest iommu_type (NESTING first) */ static int vfio_get_iommu_type(VFIOContainer *container, + bool want_nested, Error **errp) { - int iommu_types[] = { VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU, + int iommu_types[] = { VFIO_TYPE1_NESTING_IOMMU, + VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU, VFIO_SPAPR_TCE_v2_IOMMU, VFIO_SPAPR_TCE_IOMMU }; - int i; + int i, ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(iommu_types); i++) { if (ioctl(container->fd, VFIO_CHECK_EXTENSION, iommu_types[i])) { - return iommu_types[i]; + if (iommu_types[i] == VFIO_TYPE1_NESTING_IOMMU) { + if (!want_nested) { + continue; + } + } + ret = iommu_types[i]; + break; } } - error_setg(errp, "No available IOMMU models"); - return -EINVAL; + + if (ret < 0) { + error_setg(errp, "No available IOMMU models"); + } else if (want_nested && ret != VFIO_TYPE1_NESTING_IOMMU) { + error_setg(errp, "Nested mode requested but not supported"); + ret = -EINVAL; + } + return ret; } static int vfio_init_container(VFIOContainer *container, int group_fd, - Error **errp) + bool want_nested, Error **errp) { int iommu_type, ret; - iommu_type = vfio_get_iommu_type(container, errp); + iommu_type = vfio_get_iommu_type(container, want_nested, errp); if (iommu_type < 0) { return iommu_type; } @@ -1206,7 +1220,7 @@ static int vfio_init_container(VFIOContainer *container, int group_fd, } static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - Error **errp) + bool want_nested, Error **errp) { VFIOContainer *container; int ret, fd; @@ -1272,12 +1286,13 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, QLIST_INIT(&container->giommu_list); QLIST_INIT(&container->hostwin_list); - ret = vfio_init_container(container, group->fd, errp); + ret = vfio_init_container(container, group->fd, want_nested, errp); if (ret) { goto free_container_exit; } switch (container->iommu_type) { + case VFIO_TYPE1_NESTING_IOMMU: case VFIO_TYPE1v2_IOMMU: case VFIO_TYPE1_IOMMU: { @@ -1498,7 +1513,7 @@ VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, group->groupid = groupid; QLIST_INIT(&group->device_list); - if (vfio_connect_container(group, as, errp)) { + if (vfio_connect_container(group, as, want_nested, errp)) { error_prepend(errp, "failed to setup container for group %d: ", groupid); goto close_fd_exit; -- 2.7.4