vfio/pci: Convert all PCI drivers to get_region_info_caps

Since the core function signature changes it has to flow up to all
drivers.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/19-v2-2a9e24d62f1b+e10a-vfio_get_region_info_op_jgg@nvidia.com
Signed-off-by: Alex Williamson <alex@shazbot.org>
This commit is contained in:
Jason Gunthorpe
2025-11-07 13:41:35 -04:00
committed by Alex Williamson
parent 973af0c40e
commit 1b0ecb5baf
11 changed files with 80 additions and 150 deletions

View File

@@ -1386,32 +1386,22 @@ static ssize_t hisi_acc_vfio_pci_read(struct vfio_device *core_vdev,
}
static int hisi_acc_vfio_ioctl_get_region(struct vfio_device *core_vdev,
struct vfio_region_info __user *arg)
struct vfio_region_info *info,
struct vfio_info_cap *caps)
{
struct vfio_pci_core_device *vdev =
container_of(core_vdev, struct vfio_pci_core_device, vdev);
struct vfio_region_info info;
unsigned long minsz;
minsz = offsetofend(struct vfio_region_info, offset);
if (info->index != VFIO_PCI_BAR2_REGION_INDEX)
return vfio_pci_ioctl_get_region_info(core_vdev, info, caps);
if (copy_from_user(&info, arg, minsz))
return -EFAULT;
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
if (info.argsz < minsz)
return -EINVAL;
info->size = hisi_acc_get_resource_len(vdev, info->index);
if (info.index != VFIO_PCI_BAR2_REGION_INDEX)
return vfio_pci_ioctl_get_region_info(core_vdev, arg);
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.size = hisi_acc_get_resource_len(vdev, info.index);
info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE |
info->flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE |
VFIO_REGION_INFO_FLAG_MMAP;
return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
return 0;
}
static int hisi_acc_vf_debug_check(struct seq_file *seq, struct vfio_device *vdev)
@@ -1610,7 +1600,7 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_migrn_ops = {
.open_device = hisi_acc_vfio_pci_open_device,
.close_device = hisi_acc_vfio_pci_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = hisi_acc_vfio_ioctl_get_region,
.get_region_info_caps = hisi_acc_vfio_ioctl_get_region,
.device_feature = vfio_pci_core_ioctl_feature,
.read = hisi_acc_vfio_pci_read,
.write = hisi_acc_vfio_pci_write,
@@ -1631,7 +1621,7 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_ops = {
.open_device = hisi_acc_vfio_pci_open_device,
.close_device = vfio_pci_core_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,

View File

@@ -1366,7 +1366,7 @@ static const struct vfio_device_ops mlx5vf_pci_ops = {
.open_device = mlx5vf_pci_open_device,
.close_device = mlx5vf_pci_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,

View File

@@ -205,34 +205,25 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
return 0;
}
static int
nvgrace_gpu_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info __user *arg)
static int nvgrace_gpu_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info *info,
struct vfio_info_cap *caps)
{
struct nvgrace_gpu_pci_core_device *nvdev =
container_of(core_vdev, struct nvgrace_gpu_pci_core_device,
core_device.vdev);
unsigned long minsz = offsetofend(struct vfio_region_info, offset);
struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
struct vfio_region_info_cap_sparse_mmap *sparse;
struct vfio_region_info info;
struct mem_region *memregion;
u32 size;
int ret;
if (copy_from_user(&info, arg, minsz))
return -EFAULT;
if (info.argsz < minsz)
return -EINVAL;
/*
* Request to determine the BAR region information. Send the
* GPU memory information.
*/
memregion = nvgrace_gpu_memregion(info.index, nvdev);
memregion = nvgrace_gpu_memregion(info->index, nvdev);
if (!memregion)
return vfio_pci_ioctl_get_region_info(core_vdev, arg);
return vfio_pci_ioctl_get_region_info(core_vdev, info, caps);
size = struct_size(sparse, areas, 1);
@@ -251,40 +242,22 @@ nvgrace_gpu_ioctl_get_region_info(struct vfio_device *core_vdev,
sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
sparse->header.version = 1;
ret = vfio_info_add_capability(&caps, &sparse->header, size);
ret = vfio_info_add_capability(caps, &sparse->header, size);
kfree(sparse);
if (ret)
return ret;
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
/*
* The region memory size may not be power-of-2 aligned.
* Given that the memory is a BAR and may not be
* aligned, roundup to the next power-of-2.
*/
info.size = memregion->bar_size;
info.flags = VFIO_REGION_INFO_FLAG_READ |
info->size = memregion->bar_size;
info->flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE |
VFIO_REGION_INFO_FLAG_MMAP;
if (caps.size) {
info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
} else {
vfio_info_cap_shift(&caps, sizeof(info));
if (copy_to_user((void __user *)arg +
sizeof(info), caps.buf,
caps.size)) {
kfree(caps.buf);
return -EFAULT;
}
info.cap_offset = sizeof(info);
}
kfree(caps.buf);
}
return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
return 0;
}
static long nvgrace_gpu_ioctl(struct vfio_device *core_vdev,
@@ -686,7 +659,7 @@ static const struct vfio_device_ops nvgrace_gpu_pci_ops = {
.open_device = nvgrace_gpu_open_device,
.close_device = nvgrace_gpu_close_device,
.ioctl = nvgrace_gpu_ioctl,
.get_region_info = nvgrace_gpu_ioctl_get_region_info,
.get_region_info_caps = nvgrace_gpu_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = nvgrace_gpu_read,
.write = nvgrace_gpu_write,
@@ -707,7 +680,7 @@ static const struct vfio_device_ops nvgrace_gpu_pci_core_ops = {
.open_device = nvgrace_gpu_open_device,
.close_device = vfio_pci_core_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,

View File

@@ -195,7 +195,7 @@ static const struct vfio_device_ops pds_vfio_ops = {
.open_device = pds_vfio_open_device,
.close_device = pds_vfio_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,

View File

@@ -609,7 +609,7 @@ static const struct vfio_device_ops qat_vf_pci_ops = {
.open_device = qat_vf_pci_open_device,
.close_device = qat_vf_pci_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,
.mmap = vfio_pci_core_mmap,

View File

@@ -132,7 +132,7 @@ static const struct vfio_device_ops vfio_pci_ops = {
.open_device = vfio_pci_open_device,
.close_device = vfio_pci_core_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,

View File

@@ -997,43 +997,35 @@ static int vfio_pci_ioctl_get_info(struct vfio_pci_core_device *vdev,
}
int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info __user *arg)
struct vfio_region_info *info,
struct vfio_info_cap *caps)
{
struct vfio_pci_core_device *vdev =
container_of(core_vdev, struct vfio_pci_core_device, vdev);
unsigned long minsz = offsetofend(struct vfio_region_info, offset);
struct pci_dev *pdev = vdev->pdev;
struct vfio_region_info info;
struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
int i, ret;
if (copy_from_user(&info, arg, minsz))
return -EFAULT;
if (info.argsz < minsz)
return -EINVAL;
switch (info.index) {
switch (info->index) {
case VFIO_PCI_CONFIG_REGION_INDEX:
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.size = pdev->cfg_size;
info.flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
info->size = pdev->cfg_size;
info->flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
break;
case VFIO_PCI_BAR0_REGION_INDEX ... VFIO_PCI_BAR5_REGION_INDEX:
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.size = pci_resource_len(pdev, info.index);
if (!info.size) {
info.flags = 0;
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
info->size = pci_resource_len(pdev, info->index);
if (!info->size) {
info->flags = 0;
break;
}
info.flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
if (vdev->bar_mmap_supported[info.index]) {
info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
if (info.index == vdev->msix_bar) {
ret = msix_mmappable_cap(vdev, &caps);
info->flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
if (vdev->bar_mmap_supported[info->index]) {
info->flags |= VFIO_REGION_INFO_FLAG_MMAP;
if (info->index == vdev->msix_bar) {
ret = msix_mmappable_cap(vdev, caps);
if (ret)
return ret;
}
@@ -1045,9 +1037,9 @@ int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
size_t size;
u16 cmd;
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.flags = 0;
info.size = 0;
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
info->flags = 0;
info->size = 0;
if (pci_resource_start(pdev, PCI_ROM_RESOURCE)) {
/*
@@ -1057,16 +1049,17 @@ int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
cmd = vfio_pci_memory_lock_and_enable(vdev);
io = pci_map_rom(pdev, &size);
if (io) {
info.flags = VFIO_REGION_INFO_FLAG_READ;
info->flags = VFIO_REGION_INFO_FLAG_READ;
/* Report the BAR size, not the ROM size. */
info.size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
info->size = pci_resource_len(pdev,
PCI_ROM_RESOURCE);
pci_unmap_rom(pdev, io);
}
vfio_pci_memory_unlock_and_restore(vdev, cmd);
} else if (pdev->rom && pdev->romlen) {
info.flags = VFIO_REGION_INFO_FLAG_READ;
info->flags = VFIO_REGION_INFO_FLAG_READ;
/* Report BAR size as power of two. */
info.size = roundup_pow_of_two(pdev->romlen);
info->size = roundup_pow_of_two(pdev->romlen);
}
break;
@@ -1075,10 +1068,10 @@ int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
if (!vdev->has_vga)
return -EINVAL;
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.size = 0xc0000;
info.flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
info->size = 0xc0000;
info->flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
break;
default: {
@@ -1087,52 +1080,34 @@ int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
.header.version = 1
};
if (info.index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
if (info->index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
return -EINVAL;
info.index = array_index_nospec(
info.index, VFIO_PCI_NUM_REGIONS + vdev->num_regions);
info->index = array_index_nospec(
info->index, VFIO_PCI_NUM_REGIONS + vdev->num_regions);
i = info.index - VFIO_PCI_NUM_REGIONS;
i = info->index - VFIO_PCI_NUM_REGIONS;
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.size = vdev->region[i].size;
info.flags = vdev->region[i].flags;
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
info->size = vdev->region[i].size;
info->flags = vdev->region[i].flags;
cap_type.type = vdev->region[i].type;
cap_type.subtype = vdev->region[i].subtype;
ret = vfio_info_add_capability(&caps, &cap_type.header,
ret = vfio_info_add_capability(caps, &cap_type.header,
sizeof(cap_type));
if (ret)
return ret;
if (vdev->region[i].ops->add_capability) {
ret = vdev->region[i].ops->add_capability(
vdev, &vdev->region[i], &caps);
vdev, &vdev->region[i], caps);
if (ret)
return ret;
}
}
}
if (caps.size) {
info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
} else {
vfio_info_cap_shift(&caps, sizeof(info));
if (copy_to_user(arg + 1, caps.buf, caps.size)) {
kfree(caps.buf);
return -EFAULT;
}
info.cap_offset = sizeof(*arg);
}
kfree(caps.buf);
}
return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
return 0;
}
EXPORT_SYMBOL_GPL(vfio_pci_ioctl_get_region_info);

View File

@@ -110,7 +110,8 @@ void virtiovf_migration_reset_done(struct pci_dev *pdev);
#ifdef CONFIG_VIRTIO_VFIO_PCI_ADMIN_LEGACY
int virtiovf_open_legacy_io(struct virtiovf_pci_core_device *virtvdev);
int virtiovf_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info __user *arg);
struct vfio_region_info *info,
struct vfio_info_cap *caps);
ssize_t virtiovf_pci_core_write(struct vfio_device *core_vdev,
const char __user *buf, size_t count,
loff_t *ppos);

View File

@@ -281,29 +281,19 @@ ssize_t virtiovf_pci_core_write(struct vfio_device *core_vdev, const char __user
}
int virtiovf_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info __user *arg)
struct vfio_region_info *info,
struct vfio_info_cap *caps)
{
struct virtiovf_pci_core_device *virtvdev = container_of(
core_vdev, struct virtiovf_pci_core_device, core_device.vdev);
unsigned long minsz = offsetofend(struct vfio_region_info, offset);
struct vfio_region_info info = {};
if (copy_from_user(&info, arg, minsz))
return -EFAULT;
if (info->index != VFIO_PCI_BAR0_REGION_INDEX)
return vfio_pci_ioctl_get_region_info(core_vdev, info, caps);
if (info.argsz < minsz)
return -EINVAL;
switch (info.index) {
case VFIO_PCI_BAR0_REGION_INDEX:
info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
info.size = virtvdev->bar0_virtual_buf_size;
info.flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
return copy_to_user(arg, &info, minsz) ? -EFAULT : 0;
default:
return vfio_pci_ioctl_get_region_info(core_vdev, arg);
}
info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index);
info->size = virtvdev->bar0_virtual_buf_size;
info->flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE;
return 0;
}
static int virtiovf_set_notify_addr(struct virtiovf_pci_core_device *virtvdev)

View File

@@ -88,7 +88,7 @@ static const struct vfio_device_ops virtiovf_vfio_pci_lm_ops = {
.open_device = virtiovf_pci_open_device,
.close_device = virtiovf_pci_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,
@@ -110,7 +110,7 @@ static const struct vfio_device_ops virtiovf_vfio_pci_tran_lm_ops = {
.open_device = virtiovf_pci_open_device,
.close_device = virtiovf_pci_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = virtiovf_pci_ioctl_get_region_info,
.get_region_info_caps = virtiovf_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = virtiovf_pci_core_read,
.write = virtiovf_pci_core_write,
@@ -132,7 +132,7 @@ static const struct vfio_device_ops virtiovf_vfio_pci_ops = {
.open_device = virtiovf_pci_open_device,
.close_device = vfio_pci_core_close_device,
.ioctl = vfio_pci_core_ioctl,
.get_region_info = vfio_pci_ioctl_get_region_info,
.get_region_info_caps = vfio_pci_ioctl_get_region_info,
.device_feature = vfio_pci_core_ioctl_feature,
.read = vfio_pci_core_read,
.write = vfio_pci_core_write,

View File

@@ -116,7 +116,8 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags,
void __user *arg, size_t argsz);
int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info __user *arg);
struct vfio_region_info *info,
struct vfio_info_cap *caps);
ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf,
size_t count, loff_t *ppos);
ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf,