Commit e8214ed5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'vfio-v6.17-rc1-v2' of https://github.com/awilliam/linux-vfio

Pull VFIO updates from Alex Williamson:

 - Fix imbalance where the no-iommu/cdev device path skips too much on
   open, failing to increment a reference, but still decrements the
   reference on close. Add bounds checking to prevent such underflows
   (Jacob Pan)

 - Fill missing detach_ioas op for pds_vfio_pci, fixing probe failure
   when used with IOMMUFD (Brett Creeley)

 - Split SR-IOV VFs to separate dev_set, avoiding unnecessary
   serialization between VFs that appear on the same bus (Alex
   Williamson)

 - Fix a theoretical integer overflow is the mlx5-vfio-pci variant
   driver (Artem Sadovnikov)

 - Implement missing VF token checking support via vfio cdev/IOMMUFD
   interface (Jason Gunthorpe)

 - Update QAT vfio-pci variant driver to claim latest VF devices
   (Małgorzata Mielnik)

 - Add a cond_resched() call to avoid holding the CPU too long during
   DMA mapping operations (Keith Busch)

* tag 'vfio-v6.17-rc1-v2' of https://github.com/awilliam/linux-vfio:
  vfio/type1: conditional rescheduling while pinning
  vfio/qat: add support for intel QAT 6xxx virtual functions
  vfio/qat: Remove myself from VFIO QAT PCI driver maintainers
  vfio/pci: Do vf_token checks for VFIO_DEVICE_BIND_IOMMUFD
  vfio/mlx5: fix possible overflow in tracking max message size
  vfio/pci: Separate SR-IOV VF dev_set
  vfio/pds: Fix missing detach_ioas op
  vfio: Prevent open_count decrement to negative
  vfio: Fix unbalanced vfio_df_close call in no-iommu mode
parents cca7a0aa b1779e4f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -26455,7 +26455,6 @@ S: Maintained
F:	drivers/vfio/platform/
VFIO QAT PCI DRIVER
M:	Xin Zeng <xin.zeng@intel.com>
M:	Giovanni Cabiddu <giovanni.cabiddu@intel.com>
L:	kvm@vger.kernel.org
L:	qat-linux@intel.com
+35 −3
Original line number Diff line number Diff line
@@ -60,22 +60,50 @@ static void vfio_df_get_kvm_safe(struct vfio_device_file *df)
	spin_unlock(&df->kvm_ref_lock);
}

static int vfio_df_check_token(struct vfio_device *device,
			       const struct vfio_device_bind_iommufd *bind)
{
	uuid_t uuid;

	if (!device->ops->match_token_uuid) {
		if (bind->flags & VFIO_DEVICE_BIND_FLAG_TOKEN)
			return -EINVAL;
		return 0;
	}

	if (!(bind->flags & VFIO_DEVICE_BIND_FLAG_TOKEN))
		return device->ops->match_token_uuid(device, NULL);

	if (copy_from_user(&uuid, u64_to_user_ptr(bind->token_uuid_ptr),
			   sizeof(uuid)))
		return -EFAULT;
	return device->ops->match_token_uuid(device, &uuid);
}

long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,
				struct vfio_device_bind_iommufd __user *arg)
{
	const u32 VALID_FLAGS = VFIO_DEVICE_BIND_FLAG_TOKEN;
	struct vfio_device *device = df->device;
	struct vfio_device_bind_iommufd bind;
	unsigned long minsz;
	u32 user_size;
	int ret;

	static_assert(__same_type(arg->out_devid, df->devid));

	minsz = offsetofend(struct vfio_device_bind_iommufd, out_devid);

	if (copy_from_user(&bind, arg, minsz))
		return -EFAULT;
	ret = get_user(user_size, &arg->argsz);
	if (ret)
		return ret;
	if (user_size < minsz)
		return -EINVAL;
	ret = copy_struct_from_user(&bind, minsz, arg, user_size);
	if (ret)
		return ret;

	if (bind.argsz < minsz || bind.flags || bind.iommufd < 0)
	if (bind.iommufd < 0 || bind.flags & ~VALID_FLAGS)
		return -EINVAL;

	/* BIND_IOMMUFD only allowed for cdev fds */
@@ -93,6 +121,10 @@ long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,
		goto out_unlock;
	}

	ret = vfio_df_check_token(device, &bind);
	if (ret)
		goto out_unlock;

	df->iommufd = iommufd_ctx_from_fd(bind.iommufd);
	if (IS_ERR(df->iommufd)) {
		ret = PTR_ERR(df->iommufd);
+3 −4
Original line number Diff line number Diff line
@@ -192,12 +192,11 @@ static int vfio_df_group_open(struct vfio_device_file *df)
		 * implies they expected translation to exist
		 */
		if (!capable(CAP_SYS_RAWIO) ||
		    vfio_iommufd_device_has_compat_ioas(device, df->iommufd))
		    vfio_iommufd_device_has_compat_ioas(device, df->iommufd)) {
			ret = -EPERM;
		else
			ret = 0;
			goto out_put_kvm;
		}
	}

	ret = vfio_df_open(df);
	if (ret)
+4 −0
Original line number Diff line number Diff line
@@ -25,6 +25,10 @@ int vfio_df_iommufd_bind(struct vfio_device_file *df)

	lockdep_assert_held(&vdev->dev_set->lock);

	/* Returns 0 to permit device opening under noiommu mode */
	if (vfio_device_is_noiommu(vdev))
		return 0;

	return vdev->ops->bind_iommufd(vdev, ictx, &df->devid);
}

+1 −0
Original line number Diff line number Diff line
@@ -1583,6 +1583,7 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_ops = {
	.mmap = vfio_pci_core_mmap,
	.request = vfio_pci_core_request,
	.match = vfio_pci_core_match,
	.match_token_uuid = vfio_pci_core_match_token_uuid,
	.bind_iommufd = vfio_iommufd_physical_bind,
	.unbind_iommufd = vfio_iommufd_physical_unbind,
	.attach_ioas = vfio_iommufd_physical_attach_ioas,
Loading