History

vfio: Move IOMMU_CAP_CACHE_COHERENCY test to after we know we have a group

The test isn't going to work if a group doesn't exist. Normally this isn't a problem since VFIO isn't going to create a device if there is no group, but the special CONFIG_VFIO_NOIOMMU behavior allows bypassing this prevention. The new cap test effectively forces a group and breaks this config option. Move the cap test to vfio_group_find_or_alloc() which is the earliest time we know we have a group available and thus are not running in noiommu mode.

Jason Gunthorpe committed 4 years ago

Commit afe4e371 parent 88084a31 file · +10 −7Browse files

Unified · Split

drivers/vfio/vfio.c+10−7
@@ -549,6 +549,16 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev) · 548 unmodified lines
549 if (!iommu_group)549 if (!iommu_group)
550 return ERR_PTR(-EINVAL);550 return ERR_PTR(-EINVAL);
551 551
552 /*
553 * VFIO always sets IOMMU_CACHE because we offer no way for userspace to
554 * restore cache coherency. It has to be checked here because it is only
555 * valid for cases where we are using iommu groups.
556 */
557 if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) {
558 iommu_group_put(iommu_group);
559 return ERR_PTR(-EINVAL);
560 }
561
552 group = vfio_group_get_from_iommu(iommu_group);562 group = vfio_group_get_from_iommu(iommu_group);
553 if (!group)563 if (!group)
554 group = vfio_create_group(iommu_group, VFIO_IOMMU);564 group = vfio_create_group(iommu_group, VFIO_IOMMU);
@@ -601,13 +611,6 @@ static int __vfio_register_dev(struct vfio_device *device, · 46 unmodified lines
601 611
602int vfio_register_group_dev(struct vfio_device *device)612int vfio_register_group_dev(struct vfio_device *device)
603{613{
604 /*
605 * VFIO always sets IOMMU_CACHE because we offer no way for userspace to
606 * restore cache coherency.
607 */
608 if (!iommu_capable(device->dev->bus, IOMMU_CAP_CACHE_COHERENCY))
609 return -EINVAL;
610
611 return __vfio_register_dev(device,614 return __vfio_register_dev(device,
612 vfio_group_find_or_alloc(device->dev));615 vfio_group_find_or_alloc(device->dev));
613}616}