Merge tag 'vfio-v4.21-rc1' of git://github.com/awilliam/linux-vfio
[sfrench/cifs-2.6.git] / drivers / vfio / pci / vfio_pci.c
index ea0670c60c802e4bdef14a3596e5f1c45bc9aed9..ff60bd1ea58799dbf1c94fd5d715602be4ac98e7 100644 (file)
@@ -287,14 +287,37 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
                if (ret) {
                        dev_warn(&vdev->pdev->dev,
                                 "Failed to setup Intel IGD regions\n");
-                       vfio_pci_disable(vdev);
-                       return ret;
+                       goto disable_exit;
+               }
+       }
+
+       if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
+           IS_ENABLED(CONFIG_VFIO_PCI_NVLINK2)) {
+               ret = vfio_pci_nvdia_v100_nvlink2_init(vdev);
+               if (ret && ret != -ENODEV) {
+                       dev_warn(&vdev->pdev->dev,
+                                "Failed to setup NVIDIA NV2 RAM region\n");
+                       goto disable_exit;
+               }
+       }
+
+       if (pdev->vendor == PCI_VENDOR_ID_IBM &&
+           IS_ENABLED(CONFIG_VFIO_PCI_NVLINK2)) {
+               ret = vfio_pci_ibm_npu2_init(vdev);
+               if (ret && ret != -ENODEV) {
+                       dev_warn(&vdev->pdev->dev,
+                                       "Failed to setup NVIDIA NV2 ATSD region\n");
+                       goto disable_exit;
                }
        }
 
        vfio_pci_probe_mmaps(vdev);
 
        return 0;
+
+disable_exit:
+       vfio_pci_disable(vdev);
+       return ret;
 }
 
 static void vfio_pci_disable(struct vfio_pci_device *vdev)
@@ -748,6 +771,12 @@ static long vfio_pci_ioctl(void *device_data,
                        if (ret)
                                return ret;
 
+                       if (vdev->region[i].ops->add_capability) {
+                               ret = vdev->region[i].ops->add_capability(vdev,
+                                               &vdev->region[i], &caps);
+                               if (ret)
+                                       return ret;
+                       }
                }
                }
 
@@ -1115,6 +1144,15 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
                return -EINVAL;
        if ((vma->vm_flags & VM_SHARED) == 0)
                return -EINVAL;
+       if (index >= VFIO_PCI_NUM_REGIONS) {
+               int regnum = index - VFIO_PCI_NUM_REGIONS;
+               struct vfio_pci_region *region = vdev->region + regnum;
+
+               if (region && region->ops && region->ops->mmap &&
+                   (region->flags & VFIO_REGION_INFO_FLAG_MMAP))
+                       return region->ops->mmap(vdev, region, vma);
+               return -EINVAL;
+       }
        if (index >= VFIO_PCI_ROM_REGION_INDEX)
                return -EINVAL;
        if (!vdev->bar_mmap_supported[index])