Commit 6e6c513f authored by Yi Liu's avatar Yi Liu Committed by Alex Williamson
Browse files

vfio/pci: Move the existing hot reset logic to be a helper



This prepares to add another method for hot reset. The major hot reset logic
are moved to vfio_pci_ioctl_pci_hot_reset_groups().

No functional change is intended.

Suggested-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Tested-by: default avatarYanting Jiang <yanting.jiang@intel.com>
Tested-by: default avatarTerrence Xu <terrence.xu@intel.com>
Tested-by: default avatarZhenzhong Duan <zhenzhong.duan@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20230718105542.4138-3-yi.l.liu@intel.com


Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent c60f9320
Loading
Loading
Loading
Loading
+32 −23
Original line number Diff line number Diff line
@@ -1296,29 +1296,16 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info(
	return ret;
}

static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
static int
vfio_pci_ioctl_pci_hot_reset_groups(struct vfio_pci_core_device *vdev,
				    int array_count, bool slot,
				    struct vfio_pci_hot_reset __user *arg)
{
	unsigned long minsz = offsetofend(struct vfio_pci_hot_reset, count);
	struct vfio_pci_hot_reset hdr;
	int32_t *group_fds;
	struct file **files;
	struct vfio_pci_group_info info;
	bool slot = false;
	int file_idx, count = 0, ret = 0;

	if (copy_from_user(&hdr, arg, minsz))
		return -EFAULT;

	if (hdr.argsz < minsz || hdr.flags)
		return -EINVAL;

	/* Can we do a slot or bus reset or neither? */
	if (!pci_probe_reset_slot(vdev->pdev->slot))
		slot = true;
	else if (pci_probe_reset_bus(vdev->pdev->bus))
		return -ENODEV;

	/*
	 * We can't let userspace give us an arbitrarily large buffer to copy,
	 * so verify how many we think there could be.  Note groups can have
@@ -1330,11 +1317,11 @@ static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
		return ret;

	/* Somewhere between 1 and count is OK */
	if (!hdr.count || hdr.count > count)
	if (!array_count || array_count > count)
		return -EINVAL;

	group_fds = kcalloc(hdr.count, sizeof(*group_fds), GFP_KERNEL);
	files = kcalloc(hdr.count, sizeof(*files), GFP_KERNEL);
	group_fds = kcalloc(array_count, sizeof(*group_fds), GFP_KERNEL);
	files = kcalloc(array_count, sizeof(*files), GFP_KERNEL);
	if (!group_fds || !files) {
		kfree(group_fds);
		kfree(files);
@@ -1342,7 +1329,7 @@ static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
	}

	if (copy_from_user(group_fds, arg->group_fds,
			   hdr.count * sizeof(*group_fds))) {
			   array_count * sizeof(*group_fds))) {
		kfree(group_fds);
		kfree(files);
		return -EFAULT;
@@ -1352,7 +1339,7 @@ static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
	 * Get the group file for each fd to ensure the group is held across
	 * the reset
	 */
	for (file_idx = 0; file_idx < hdr.count; file_idx++) {
	for (file_idx = 0; file_idx < array_count; file_idx++) {
		struct file *file = fget(group_fds[file_idx]);

		if (!file) {
@@ -1376,7 +1363,7 @@ static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
	if (ret)
		goto hot_reset_release;

	info.count = hdr.count;
	info.count = array_count;
	info.files = files;

	ret = vfio_pci_dev_set_hot_reset(vdev->vdev.dev_set, &info);
@@ -1389,6 +1376,28 @@ static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
	return ret;
}

static int vfio_pci_ioctl_pci_hot_reset(struct vfio_pci_core_device *vdev,
					struct vfio_pci_hot_reset __user *arg)
{
	unsigned long minsz = offsetofend(struct vfio_pci_hot_reset, count);
	struct vfio_pci_hot_reset hdr;
	bool slot = false;

	if (copy_from_user(&hdr, arg, minsz))
		return -EFAULT;

	if (hdr.argsz < minsz || hdr.flags)
		return -EINVAL;

	/* Can we do a slot or bus reset or neither? */
	if (!pci_probe_reset_slot(vdev->pdev->slot))
		slot = true;
	else if (pci_probe_reset_bus(vdev->pdev->bus))
		return -ENODEV;

	return vfio_pci_ioctl_pci_hot_reset_groups(vdev, hdr.count, slot, arg);
}

static int vfio_pci_ioctl_ioeventfd(struct vfio_pci_core_device *vdev,
				    struct vfio_device_ioeventfd __user *arg)
{