diff options
Diffstat (limited to 'drivers/vfio/pci/vfio_pci.c')
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 50cdedfca9fe..a89fa5d4e877 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c | |||
@@ -289,14 +289,37 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev) | |||
289 | if (ret) { | 289 | if (ret) { |
290 | dev_warn(&vdev->pdev->dev, | 290 | dev_warn(&vdev->pdev->dev, |
291 | "Failed to setup Intel IGD regions\n"); | 291 | "Failed to setup Intel IGD regions\n"); |
292 | vfio_pci_disable(vdev); | 292 | goto disable_exit; |
293 | return ret; | 293 | } |
294 | } | ||
295 | |||
296 | if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && | ||
297 | IS_ENABLED(CONFIG_VFIO_PCI_NVLINK2)) { | ||
298 | ret = vfio_pci_nvdia_v100_nvlink2_init(vdev); | ||
299 | if (ret && ret != -ENODEV) { | ||
300 | dev_warn(&vdev->pdev->dev, | ||
301 | "Failed to setup NVIDIA NV2 RAM region\n"); | ||
302 | goto disable_exit; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | if (pdev->vendor == PCI_VENDOR_ID_IBM && | ||
307 | IS_ENABLED(CONFIG_VFIO_PCI_NVLINK2)) { | ||
308 | ret = vfio_pci_ibm_npu2_init(vdev); | ||
309 | if (ret && ret != -ENODEV) { | ||
310 | dev_warn(&vdev->pdev->dev, | ||
311 | "Failed to setup NVIDIA NV2 ATSD region\n"); | ||
312 | goto disable_exit; | ||
294 | } | 313 | } |
295 | } | 314 | } |
296 | 315 | ||
297 | vfio_pci_probe_mmaps(vdev); | 316 | vfio_pci_probe_mmaps(vdev); |
298 | 317 | ||
299 | return 0; | 318 | return 0; |
319 | |||
320 | disable_exit: | ||
321 | vfio_pci_disable(vdev); | ||
322 | return ret; | ||
300 | } | 323 | } |
301 | 324 | ||
302 | static void vfio_pci_disable(struct vfio_pci_device *vdev) | 325 | static void vfio_pci_disable(struct vfio_pci_device *vdev) |
@@ -750,6 +773,12 @@ static long vfio_pci_ioctl(void *device_data, | |||
750 | if (ret) | 773 | if (ret) |
751 | return ret; | 774 | return ret; |
752 | 775 | ||
776 | if (vdev->region[i].ops->add_capability) { | ||
777 | ret = vdev->region[i].ops->add_capability(vdev, | ||
778 | &vdev->region[i], &caps); | ||
779 | if (ret) | ||
780 | return ret; | ||
781 | } | ||
753 | } | 782 | } |
754 | } | 783 | } |
755 | 784 | ||
@@ -1117,6 +1146,15 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma) | |||
1117 | return -EINVAL; | 1146 | return -EINVAL; |
1118 | if ((vma->vm_flags & VM_SHARED) == 0) | 1147 | if ((vma->vm_flags & VM_SHARED) == 0) |
1119 | return -EINVAL; | 1148 | return -EINVAL; |
1149 | if (index >= VFIO_PCI_NUM_REGIONS) { | ||
1150 | int regnum = index - VFIO_PCI_NUM_REGIONS; | ||
1151 | struct vfio_pci_region *region = vdev->region + regnum; | ||
1152 | |||
1153 | if (region && region->ops && region->ops->mmap && | ||
1154 | (region->flags & VFIO_REGION_INFO_FLAG_MMAP)) | ||
1155 | return region->ops->mmap(vdev, region, vma); | ||
1156 | return -EINVAL; | ||
1157 | } | ||
1120 | if (index >= VFIO_PCI_ROM_REGION_INDEX) | 1158 | if (index >= VFIO_PCI_ROM_REGION_INDEX) |
1121 | return -EINVAL; | 1159 | return -EINVAL; |
1122 | if (!vdev->bar_mmap_supported[index]) | 1160 | if (!vdev->bar_mmap_supported[index]) |