Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jason Gunthorpe and committed by
Alex Williamson
1b0ecb5b 973af0c4

+80 -150
+10 -20
drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
··· 1386 1386 } 1387 1387 1388 1388 static int hisi_acc_vfio_ioctl_get_region(struct vfio_device *core_vdev, 1389 - struct vfio_region_info __user *arg) 1389 + struct vfio_region_info *info, 1390 + struct vfio_info_cap *caps) 1390 1391 { 1391 1392 struct vfio_pci_core_device *vdev = 1392 1393 container_of(core_vdev, struct vfio_pci_core_device, vdev); 1393 - struct vfio_region_info info; 1394 - unsigned long minsz; 1395 1394 1396 - minsz = offsetofend(struct vfio_region_info, offset); 1395 + if (info->index != VFIO_PCI_BAR2_REGION_INDEX) 1396 + return vfio_pci_ioctl_get_region_info(core_vdev, info, caps); 1397 1397 1398 - if (copy_from_user(&info, arg, minsz)) 1399 - return -EFAULT; 1398 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 1400 1399 1401 - if (info.argsz < minsz) 1402 - return -EINVAL; 1400 + info->size = hisi_acc_get_resource_len(vdev, info->index); 1403 1401 1404 - if (info.index != VFIO_PCI_BAR2_REGION_INDEX) 1405 - return vfio_pci_ioctl_get_region_info(core_vdev, arg); 1406 - 1407 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 1408 - 1409 - info.size = hisi_acc_get_resource_len(vdev, info.index); 1410 - 1411 - info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE | 1402 + info->flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE | 1412 1403 VFIO_REGION_INFO_FLAG_MMAP; 1413 - 1414 - return copy_to_user(arg, &info, minsz) ? -EFAULT : 0; 1404 + return 0; 1415 1405 } 1416 1406 1417 1407 static int hisi_acc_vf_debug_check(struct seq_file *seq, struct vfio_device *vdev) ··· 1600 1610 .open_device = hisi_acc_vfio_pci_open_device, 1601 1611 .close_device = hisi_acc_vfio_pci_close_device, 1602 1612 .ioctl = vfio_pci_core_ioctl, 1603 - .get_region_info = hisi_acc_vfio_ioctl_get_region, 1613 + .get_region_info_caps = hisi_acc_vfio_ioctl_get_region, 1604 1614 .device_feature = vfio_pci_core_ioctl_feature, 1605 1615 .read = hisi_acc_vfio_pci_read, 1606 1616 .write = hisi_acc_vfio_pci_write, ··· 1621 1631 .open_device = hisi_acc_vfio_pci_open_device, 1622 1632 .close_device = vfio_pci_core_close_device, 1623 1633 .ioctl = vfio_pci_core_ioctl, 1624 - .get_region_info = vfio_pci_ioctl_get_region_info, 1634 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 1625 1635 .device_feature = vfio_pci_core_ioctl_feature, 1626 1636 .read = vfio_pci_core_read, 1627 1637 .write = vfio_pci_core_write,
+1 -1
drivers/vfio/pci/mlx5/main.c
··· 1366 1366 .open_device = mlx5vf_pci_open_device, 1367 1367 .close_device = mlx5vf_pci_close_device, 1368 1368 .ioctl = vfio_pci_core_ioctl, 1369 - .get_region_info = vfio_pci_ioctl_get_region_info, 1369 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 1370 1370 .device_feature = vfio_pci_core_ioctl_feature, 1371 1371 .read = vfio_pci_core_read, 1372 1372 .write = vfio_pci_core_write,
+12 -39
drivers/vfio/pci/nvgrace-gpu/main.c
··· 205 205 return 0; 206 206 } 207 207 208 - static int 209 - nvgrace_gpu_ioctl_get_region_info(struct vfio_device *core_vdev, 210 - struct vfio_region_info __user *arg) 208 + static int nvgrace_gpu_ioctl_get_region_info(struct vfio_device *core_vdev, 209 + struct vfio_region_info *info, 210 + struct vfio_info_cap *caps) 211 211 { 212 212 struct nvgrace_gpu_pci_core_device *nvdev = 213 213 container_of(core_vdev, struct nvgrace_gpu_pci_core_device, 214 214 core_device.vdev); 215 - unsigned long minsz = offsetofend(struct vfio_region_info, offset); 216 - struct vfio_info_cap caps = { .buf = NULL, .size = 0 }; 217 215 struct vfio_region_info_cap_sparse_mmap *sparse; 218 - struct vfio_region_info info; 219 216 struct mem_region *memregion; 220 217 u32 size; 221 218 int ret; 222 - 223 - if (copy_from_user(&info, arg, minsz)) 224 - return -EFAULT; 225 - 226 - if (info.argsz < minsz) 227 - return -EINVAL; 228 219 229 220 /* 230 221 * Request to determine the BAR region information. Send the 231 222 * GPU memory information. 232 223 */ 233 - memregion = nvgrace_gpu_memregion(info.index, nvdev); 224 + memregion = nvgrace_gpu_memregion(info->index, nvdev); 234 225 if (!memregion) 235 - return vfio_pci_ioctl_get_region_info(core_vdev, arg); 226 + return vfio_pci_ioctl_get_region_info(core_vdev, info, caps); 236 227 237 228 size = struct_size(sparse, areas, 1); 238 229 ··· 242 251 sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP; 243 252 sparse->header.version = 1; 244 253 245 - ret = vfio_info_add_capability(&caps, &sparse->header, size); 254 + ret = vfio_info_add_capability(caps, &sparse->header, size); 246 255 kfree(sparse); 247 256 if (ret) 248 257 return ret; 249 258 250 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 259 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 251 260 /* 252 261 * The region memory size may not be power-of-2 aligned. 253 262 * Given that the memory is a BAR and may not be 254 263 * aligned, roundup to the next power-of-2. 255 264 */ 256 - info.size = memregion->bar_size; 257 - info.flags = VFIO_REGION_INFO_FLAG_READ | 265 + info->size = memregion->bar_size; 266 + info->flags = VFIO_REGION_INFO_FLAG_READ | 258 267 VFIO_REGION_INFO_FLAG_WRITE | 259 268 VFIO_REGION_INFO_FLAG_MMAP; 260 - 261 - if (caps.size) { 262 - info.flags |= VFIO_REGION_INFO_FLAG_CAPS; 263 - if (info.argsz < sizeof(info) + caps.size) { 264 - info.argsz = sizeof(info) + caps.size; 265 - info.cap_offset = 0; 266 - } else { 267 - vfio_info_cap_shift(&caps, sizeof(info)); 268 - if (copy_to_user((void __user *)arg + 269 - sizeof(info), caps.buf, 270 - caps.size)) { 271 - kfree(caps.buf); 272 - return -EFAULT; 273 - } 274 - info.cap_offset = sizeof(info); 275 - } 276 - kfree(caps.buf); 277 - } 278 - return copy_to_user(arg, &info, minsz) ? -EFAULT : 0; 269 + return 0; 279 270 } 280 271 281 272 static long nvgrace_gpu_ioctl(struct vfio_device *core_vdev, ··· 659 686 .open_device = nvgrace_gpu_open_device, 660 687 .close_device = nvgrace_gpu_close_device, 661 688 .ioctl = nvgrace_gpu_ioctl, 662 - .get_region_info = nvgrace_gpu_ioctl_get_region_info, 689 + .get_region_info_caps = nvgrace_gpu_ioctl_get_region_info, 663 690 .device_feature = vfio_pci_core_ioctl_feature, 664 691 .read = nvgrace_gpu_read, 665 692 .write = nvgrace_gpu_write, ··· 680 707 .open_device = nvgrace_gpu_open_device, 681 708 .close_device = vfio_pci_core_close_device, 682 709 .ioctl = vfio_pci_core_ioctl, 683 - .get_region_info = vfio_pci_ioctl_get_region_info, 710 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 684 711 .device_feature = vfio_pci_core_ioctl_feature, 685 712 .read = vfio_pci_core_read, 686 713 .write = vfio_pci_core_write,
+1 -1
drivers/vfio/pci/pds/vfio_dev.c
··· 195 195 .open_device = pds_vfio_open_device, 196 196 .close_device = pds_vfio_close_device, 197 197 .ioctl = vfio_pci_core_ioctl, 198 - .get_region_info = vfio_pci_ioctl_get_region_info, 198 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 199 199 .device_feature = vfio_pci_core_ioctl_feature, 200 200 .read = vfio_pci_core_read, 201 201 .write = vfio_pci_core_write,
+1 -1
drivers/vfio/pci/qat/main.c
··· 609 609 .open_device = qat_vf_pci_open_device, 610 610 .close_device = qat_vf_pci_close_device, 611 611 .ioctl = vfio_pci_core_ioctl, 612 - .get_region_info = vfio_pci_ioctl_get_region_info, 612 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 613 613 .read = vfio_pci_core_read, 614 614 .write = vfio_pci_core_write, 615 615 .mmap = vfio_pci_core_mmap,
+1 -1
drivers/vfio/pci/vfio_pci.c
··· 132 132 .open_device = vfio_pci_open_device, 133 133 .close_device = vfio_pci_core_close_device, 134 134 .ioctl = vfio_pci_core_ioctl, 135 - .get_region_info = vfio_pci_ioctl_get_region_info, 135 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 136 136 .device_feature = vfio_pci_core_ioctl_feature, 137 137 .read = vfio_pci_core_read, 138 138 .write = vfio_pci_core_write,
+39 -64
drivers/vfio/pci/vfio_pci_core.c
··· 997 997 } 998 998 999 999 int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev, 1000 - struct vfio_region_info __user *arg) 1000 + struct vfio_region_info *info, 1001 + struct vfio_info_cap *caps) 1001 1002 { 1002 1003 struct vfio_pci_core_device *vdev = 1003 1004 container_of(core_vdev, struct vfio_pci_core_device, vdev); 1004 - unsigned long minsz = offsetofend(struct vfio_region_info, offset); 1005 1005 struct pci_dev *pdev = vdev->pdev; 1006 - struct vfio_region_info info; 1007 - struct vfio_info_cap caps = { .buf = NULL, .size = 0 }; 1008 1006 int i, ret; 1009 1007 1010 - if (copy_from_user(&info, arg, minsz)) 1011 - return -EFAULT; 1012 - 1013 - if (info.argsz < minsz) 1014 - return -EINVAL; 1015 - 1016 - switch (info.index) { 1008 + switch (info->index) { 1017 1009 case VFIO_PCI_CONFIG_REGION_INDEX: 1018 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 1019 - info.size = pdev->cfg_size; 1020 - info.flags = VFIO_REGION_INFO_FLAG_READ | 1021 - VFIO_REGION_INFO_FLAG_WRITE; 1010 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 1011 + info->size = pdev->cfg_size; 1012 + info->flags = VFIO_REGION_INFO_FLAG_READ | 1013 + VFIO_REGION_INFO_FLAG_WRITE; 1022 1014 break; 1023 1015 case VFIO_PCI_BAR0_REGION_INDEX ... VFIO_PCI_BAR5_REGION_INDEX: 1024 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 1025 - info.size = pci_resource_len(pdev, info.index); 1026 - if (!info.size) { 1027 - info.flags = 0; 1016 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 1017 + info->size = pci_resource_len(pdev, info->index); 1018 + if (!info->size) { 1019 + info->flags = 0; 1028 1020 break; 1029 1021 } 1030 1022 1031 - info.flags = VFIO_REGION_INFO_FLAG_READ | 1032 - VFIO_REGION_INFO_FLAG_WRITE; 1033 - if (vdev->bar_mmap_supported[info.index]) { 1034 - info.flags |= VFIO_REGION_INFO_FLAG_MMAP; 1035 - if (info.index == vdev->msix_bar) { 1036 - ret = msix_mmappable_cap(vdev, &caps); 1023 + info->flags = VFIO_REGION_INFO_FLAG_READ | 1024 + VFIO_REGION_INFO_FLAG_WRITE; 1025 + if (vdev->bar_mmap_supported[info->index]) { 1026 + info->flags |= VFIO_REGION_INFO_FLAG_MMAP; 1027 + if (info->index == vdev->msix_bar) { 1028 + ret = msix_mmappable_cap(vdev, caps); 1037 1029 if (ret) 1038 1030 return ret; 1039 1031 } ··· 1037 1045 size_t size; 1038 1046 u16 cmd; 1039 1047 1040 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 1041 - info.flags = 0; 1042 - info.size = 0; 1048 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 1049 + info->flags = 0; 1050 + info->size = 0; 1043 1051 1044 1052 if (pci_resource_start(pdev, PCI_ROM_RESOURCE)) { 1045 1053 /* ··· 1049 1057 cmd = vfio_pci_memory_lock_and_enable(vdev); 1050 1058 io = pci_map_rom(pdev, &size); 1051 1059 if (io) { 1052 - info.flags = VFIO_REGION_INFO_FLAG_READ; 1060 + info->flags = VFIO_REGION_INFO_FLAG_READ; 1053 1061 /* Report the BAR size, not the ROM size. */ 1054 - info.size = pci_resource_len(pdev, PCI_ROM_RESOURCE); 1062 + info->size = pci_resource_len(pdev, 1063 + PCI_ROM_RESOURCE); 1055 1064 pci_unmap_rom(pdev, io); 1056 1065 } 1057 1066 vfio_pci_memory_unlock_and_restore(vdev, cmd); 1058 1067 } else if (pdev->rom && pdev->romlen) { 1059 - info.flags = VFIO_REGION_INFO_FLAG_READ; 1068 + info->flags = VFIO_REGION_INFO_FLAG_READ; 1060 1069 /* Report BAR size as power of two. */ 1061 - info.size = roundup_pow_of_two(pdev->romlen); 1070 + info->size = roundup_pow_of_two(pdev->romlen); 1062 1071 } 1063 1072 1064 1073 break; ··· 1068 1075 if (!vdev->has_vga) 1069 1076 return -EINVAL; 1070 1077 1071 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 1072 - info.size = 0xc0000; 1073 - info.flags = VFIO_REGION_INFO_FLAG_READ | 1074 - VFIO_REGION_INFO_FLAG_WRITE; 1078 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 1079 + info->size = 0xc0000; 1080 + info->flags = VFIO_REGION_INFO_FLAG_READ | 1081 + VFIO_REGION_INFO_FLAG_WRITE; 1075 1082 1076 1083 break; 1077 1084 default: { ··· 1080 1087 .header.version = 1 1081 1088 }; 1082 1089 1083 - if (info.index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions) 1090 + if (info->index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions) 1084 1091 return -EINVAL; 1085 - info.index = array_index_nospec( 1086 - info.index, VFIO_PCI_NUM_REGIONS + vdev->num_regions); 1092 + info->index = array_index_nospec( 1093 + info->index, VFIO_PCI_NUM_REGIONS + vdev->num_regions); 1087 1094 1088 - i = info.index - VFIO_PCI_NUM_REGIONS; 1095 + i = info->index - VFIO_PCI_NUM_REGIONS; 1089 1096 1090 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 1091 - info.size = vdev->region[i].size; 1092 - info.flags = vdev->region[i].flags; 1097 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 1098 + info->size = vdev->region[i].size; 1099 + info->flags = vdev->region[i].flags; 1093 1100 1094 1101 cap_type.type = vdev->region[i].type; 1095 1102 cap_type.subtype = vdev->region[i].subtype; 1096 1103 1097 - ret = vfio_info_add_capability(&caps, &cap_type.header, 1104 + ret = vfio_info_add_capability(caps, &cap_type.header, 1098 1105 sizeof(cap_type)); 1099 1106 if (ret) 1100 1107 return ret; 1101 1108 1102 1109 if (vdev->region[i].ops->add_capability) { 1103 1110 ret = vdev->region[i].ops->add_capability( 1104 - vdev, &vdev->region[i], &caps); 1111 + vdev, &vdev->region[i], caps); 1105 1112 if (ret) 1106 1113 return ret; 1107 1114 } 1108 1115 } 1109 1116 } 1110 - 1111 - if (caps.size) { 1112 - info.flags |= VFIO_REGION_INFO_FLAG_CAPS; 1113 - if (info.argsz < sizeof(info) + caps.size) { 1114 - info.argsz = sizeof(info) + caps.size; 1115 - info.cap_offset = 0; 1116 - } else { 1117 - vfio_info_cap_shift(&caps, sizeof(info)); 1118 - if (copy_to_user(arg + 1, caps.buf, caps.size)) { 1119 - kfree(caps.buf); 1120 - return -EFAULT; 1121 - } 1122 - info.cap_offset = sizeof(*arg); 1123 - } 1124 - 1125 - kfree(caps.buf); 1126 - } 1127 - 1128 - return copy_to_user(arg, &info, minsz) ? -EFAULT : 0; 1117 + return 0; 1129 1118 } 1130 1119 EXPORT_SYMBOL_GPL(vfio_pci_ioctl_get_region_info); 1131 1120
+2 -1
drivers/vfio/pci/virtio/common.h
··· 110 110 #ifdef CONFIG_VIRTIO_VFIO_PCI_ADMIN_LEGACY 111 111 int virtiovf_open_legacy_io(struct virtiovf_pci_core_device *virtvdev); 112 112 int virtiovf_pci_ioctl_get_region_info(struct vfio_device *core_vdev, 113 - struct vfio_region_info __user *arg); 113 + struct vfio_region_info *info, 114 + struct vfio_info_cap *caps); 114 115 ssize_t virtiovf_pci_core_write(struct vfio_device *core_vdev, 115 116 const char __user *buf, size_t count, 116 117 loff_t *ppos);
+8 -18
drivers/vfio/pci/virtio/legacy_io.c
··· 281 281 } 282 282 283 283 int virtiovf_pci_ioctl_get_region_info(struct vfio_device *core_vdev, 284 - struct vfio_region_info __user *arg) 284 + struct vfio_region_info *info, 285 + struct vfio_info_cap *caps) 285 286 { 286 287 struct virtiovf_pci_core_device *virtvdev = container_of( 287 288 core_vdev, struct virtiovf_pci_core_device, core_device.vdev); 288 - unsigned long minsz = offsetofend(struct vfio_region_info, offset); 289 - struct vfio_region_info info = {}; 290 289 291 - if (copy_from_user(&info, arg, minsz)) 292 - return -EFAULT; 290 + if (info->index != VFIO_PCI_BAR0_REGION_INDEX) 291 + return vfio_pci_ioctl_get_region_info(core_vdev, info, caps); 293 292 294 - if (info.argsz < minsz) 295 - return -EINVAL; 296 - 297 - switch (info.index) { 298 - case VFIO_PCI_BAR0_REGION_INDEX: 299 - info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index); 300 - info.size = virtvdev->bar0_virtual_buf_size; 301 - info.flags = VFIO_REGION_INFO_FLAG_READ | 302 - VFIO_REGION_INFO_FLAG_WRITE; 303 - return copy_to_user(arg, &info, minsz) ? -EFAULT : 0; 304 - default: 305 - return vfio_pci_ioctl_get_region_info(core_vdev, arg); 306 - } 293 + info->offset = VFIO_PCI_INDEX_TO_OFFSET(info->index); 294 + info->size = virtvdev->bar0_virtual_buf_size; 295 + info->flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE; 296 + return 0; 307 297 } 308 298 309 299 static int virtiovf_set_notify_addr(struct virtiovf_pci_core_device *virtvdev)
+3 -3
drivers/vfio/pci/virtio/main.c
··· 88 88 .open_device = virtiovf_pci_open_device, 89 89 .close_device = virtiovf_pci_close_device, 90 90 .ioctl = vfio_pci_core_ioctl, 91 - .get_region_info = vfio_pci_ioctl_get_region_info, 91 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 92 92 .device_feature = vfio_pci_core_ioctl_feature, 93 93 .read = vfio_pci_core_read, 94 94 .write = vfio_pci_core_write, ··· 110 110 .open_device = virtiovf_pci_open_device, 111 111 .close_device = virtiovf_pci_close_device, 112 112 .ioctl = vfio_pci_core_ioctl, 113 - .get_region_info = virtiovf_pci_ioctl_get_region_info, 113 + .get_region_info_caps = virtiovf_pci_ioctl_get_region_info, 114 114 .device_feature = vfio_pci_core_ioctl_feature, 115 115 .read = virtiovf_pci_core_read, 116 116 .write = virtiovf_pci_core_write, ··· 132 132 .open_device = virtiovf_pci_open_device, 133 133 .close_device = vfio_pci_core_close_device, 134 134 .ioctl = vfio_pci_core_ioctl, 135 - .get_region_info = vfio_pci_ioctl_get_region_info, 135 + .get_region_info_caps = vfio_pci_ioctl_get_region_info, 136 136 .device_feature = vfio_pci_core_ioctl_feature, 137 137 .read = vfio_pci_core_read, 138 138 .write = vfio_pci_core_write,
+2 -1
include/linux/vfio_pci_core.h
··· 116 116 int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags, 117 117 void __user *arg, size_t argsz); 118 118 int vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev, 119 - struct vfio_region_info __user *arg); 119 + struct vfio_region_info *info, 120 + struct vfio_info_cap *caps); 120 121 ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf, 121 122 size_t count, loff_t *ppos); 122 123 ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf,