mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-07 16:17:41 -04:00
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: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Tested-by: Yanting Jiang <yanting.jiang@intel.com> Tested-by: Terrence Xu <terrence.xu@intel.com> Tested-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20230718105542.4138-3-yi.l.liu@intel.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
@@ -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,
|
||||
struct vfio_pci_hot_reset __user *arg)
|
||||
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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user