aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-01 16:18:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-01 16:18:25 -0500
commit34b1cf60abb06fa79d5f8e56f1def843dbf91888 (patch)
tree2b6145709fa3c5900957cc0f625fad85f9378c7b
parent27529c891b132f4fc65711334e885f466138ea2a (diff)
parent46ed90f157f42d956ffed17c003f089a59b76e3e (diff)
Merge tag 'vfio-v4.16-rc1' of git://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Mask INTx from user if pdev->irq is zero (Alexey Kardashevskiy) - Capability helper cleanup (Alex Williamson) - Allow mmaps overlapping MSI-X vector table with region capability exposing this feature (Alexey Kardashevskiy) - mdev static cleanups (Xiongwei Song) * tag 'vfio-v4.16-rc1' of git://github.com/awilliam/linux-vfio: vfio: mdev: make a couple of functions and structure vfio_mdev_driver static vfio-pci: Allow mapping MSIX BAR vfio: Simplify capability helper vfio-pci: Mask INTx if a device is not capabable of enabling it
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c15
-rw-r--r--drivers/vfio/mdev/vfio_mdev.c6
-rw-r--r--drivers/vfio/pci/vfio_pci.c75
-rw-r--r--drivers/vfio/vfio.c52
-rw-r--r--include/linux/vfio.h3
-rw-r--r--include/uapi/linux/vfio.h10
6 files changed, 45 insertions, 116 deletions
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 96060920a6fe..0a7d084da1a2 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1012,6 +1012,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
1012 if (!sparse) 1012 if (!sparse)
1013 return -ENOMEM; 1013 return -ENOMEM;
1014 1014
1015 sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
1016 sparse->header.version = 1;
1015 sparse->nr_areas = nr_areas; 1017 sparse->nr_areas = nr_areas;
1016 cap_type_id = VFIO_REGION_INFO_CAP_SPARSE_MMAP; 1018 cap_type_id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
1017 sparse->areas[0].offset = 1019 sparse->areas[0].offset =
@@ -1033,7 +1035,9 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
1033 break; 1035 break;
1034 default: 1036 default:
1035 { 1037 {
1036 struct vfio_region_info_cap_type cap_type; 1038 struct vfio_region_info_cap_type cap_type = {
1039 .header.id = VFIO_REGION_INFO_CAP_TYPE,
1040 .header.version = 1 };
1037 1041
1038 if (info.index >= VFIO_PCI_NUM_REGIONS + 1042 if (info.index >= VFIO_PCI_NUM_REGIONS +
1039 vgpu->vdev.num_regions) 1043 vgpu->vdev.num_regions)
@@ -1050,8 +1054,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
1050 cap_type.subtype = vgpu->vdev.region[i].subtype; 1054 cap_type.subtype = vgpu->vdev.region[i].subtype;
1051 1055
1052 ret = vfio_info_add_capability(&caps, 1056 ret = vfio_info_add_capability(&caps,
1053 VFIO_REGION_INFO_CAP_TYPE, 1057 &cap_type.header,
1054 &cap_type); 1058 sizeof(cap_type));
1055 if (ret) 1059 if (ret)
1056 return ret; 1060 return ret;
1057 } 1061 }
@@ -1061,8 +1065,9 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
1061 switch (cap_type_id) { 1065 switch (cap_type_id) {
1062 case VFIO_REGION_INFO_CAP_SPARSE_MMAP: 1066 case VFIO_REGION_INFO_CAP_SPARSE_MMAP:
1063 ret = vfio_info_add_capability(&caps, 1067 ret = vfio_info_add_capability(&caps,
1064 VFIO_REGION_INFO_CAP_SPARSE_MMAP, 1068 &sparse->header, sizeof(*sparse) +
1065 sparse); 1069 (sparse->nr_areas *
1070 sizeof(*sparse->areas)));
1066 kfree(sparse); 1071 kfree(sparse);
1067 if (ret) 1072 if (ret)
1068 return ret; 1073 return ret;
diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
index fa848a701b8b..d230620fe02d 100644
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ b/drivers/vfio/mdev/vfio_mdev.c
@@ -111,19 +111,19 @@ static const struct vfio_device_ops vfio_mdev_dev_ops = {
111 .mmap = vfio_mdev_mmap, 111 .mmap = vfio_mdev_mmap,
112}; 112};
113 113
114int vfio_mdev_probe(struct device *dev) 114static int vfio_mdev_probe(struct device *dev)
115{ 115{
116 struct mdev_device *mdev = to_mdev_device(dev); 116 struct mdev_device *mdev = to_mdev_device(dev);
117 117
118 return vfio_add_group_dev(dev, &vfio_mdev_dev_ops, mdev); 118 return vfio_add_group_dev(dev, &vfio_mdev_dev_ops, mdev);
119} 119}
120 120
121void vfio_mdev_remove(struct device *dev) 121static void vfio_mdev_remove(struct device *dev)
122{ 122{
123 vfio_del_group_dev(dev); 123 vfio_del_group_dev(dev);
124} 124}
125 125
126struct mdev_driver vfio_mdev_driver = { 126static struct mdev_driver vfio_mdev_driver = {
127 .name = "vfio_mdev", 127 .name = "vfio_mdev",
128 .probe = vfio_mdev_probe, 128 .probe = vfio_mdev_probe,
129 .remove = vfio_mdev_remove, 129 .remove = vfio_mdev_remove,
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index f041b1a6cf66..b0f759476900 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -207,6 +207,9 @@ static bool vfio_pci_nointx(struct pci_dev *pdev)
207 } 207 }
208 } 208 }
209 209
210 if (!pdev->irq)
211 return true;
212
210 return false; 213 return false;
211} 214}
212 215
@@ -562,46 +565,15 @@ static int vfio_pci_for_each_slot_or_bus(struct pci_dev *pdev,
562 return walk.ret; 565 return walk.ret;
563} 566}
564 567
565static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev, 568static int msix_mmappable_cap(struct vfio_pci_device *vdev,
566 struct vfio_info_cap *caps) 569 struct vfio_info_cap *caps)
567{ 570{
568 struct vfio_region_info_cap_sparse_mmap *sparse; 571 struct vfio_info_cap_header header = {
569 size_t end, size; 572 .id = VFIO_REGION_INFO_CAP_MSIX_MAPPABLE,
570 int nr_areas = 2, i = 0, ret; 573 .version = 1
571 574 };
572 end = pci_resource_len(vdev->pdev, vdev->msix_bar);
573
574 /* If MSI-X table is aligned to the start or end, only one area */
575 if (((vdev->msix_offset & PAGE_MASK) == 0) ||
576 (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) >= end))
577 nr_areas = 1;
578
579 size = sizeof(*sparse) + (nr_areas * sizeof(*sparse->areas));
580
581 sparse = kzalloc(size, GFP_KERNEL);
582 if (!sparse)
583 return -ENOMEM;
584
585 sparse->nr_areas = nr_areas;
586
587 if (vdev->msix_offset & PAGE_MASK) {
588 sparse->areas[i].offset = 0;
589 sparse->areas[i].size = vdev->msix_offset & PAGE_MASK;
590 i++;
591 }
592
593 if (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) < end) {
594 sparse->areas[i].offset = PAGE_ALIGN(vdev->msix_offset +
595 vdev->msix_size);
596 sparse->areas[i].size = end - sparse->areas[i].offset;
597 i++;
598 }
599
600 ret = vfio_info_add_capability(caps, VFIO_REGION_INFO_CAP_SPARSE_MMAP,
601 sparse);
602 kfree(sparse);
603 575
604 return ret; 576 return vfio_info_add_capability(caps, &header, sizeof(header));
605} 577}
606 578
607int vfio_pci_register_dev_region(struct vfio_pci_device *vdev, 579int vfio_pci_register_dev_region(struct vfio_pci_device *vdev,
@@ -692,7 +664,7 @@ static long vfio_pci_ioctl(void *device_data,
692 if (vdev->bar_mmap_supported[info.index]) { 664 if (vdev->bar_mmap_supported[info.index]) {
693 info.flags |= VFIO_REGION_INFO_FLAG_MMAP; 665 info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
694 if (info.index == vdev->msix_bar) { 666 if (info.index == vdev->msix_bar) {
695 ret = msix_sparse_mmap_cap(vdev, &caps); 667 ret = msix_mmappable_cap(vdev, &caps);
696 if (ret) 668 if (ret)
697 return ret; 669 return ret;
698 } 670 }
@@ -741,7 +713,9 @@ static long vfio_pci_ioctl(void *device_data,
741 break; 713 break;
742 default: 714 default:
743 { 715 {
744 struct vfio_region_info_cap_type cap_type; 716 struct vfio_region_info_cap_type cap_type = {
717 .header.id = VFIO_REGION_INFO_CAP_TYPE,
718 .header.version = 1 };
745 719
746 if (info.index >= 720 if (info.index >=
747 VFIO_PCI_NUM_REGIONS + vdev->num_regions) 721 VFIO_PCI_NUM_REGIONS + vdev->num_regions)
@@ -756,9 +730,8 @@ static long vfio_pci_ioctl(void *device_data,
756 cap_type.type = vdev->region[i].type; 730 cap_type.type = vdev->region[i].type;
757 cap_type.subtype = vdev->region[i].subtype; 731 cap_type.subtype = vdev->region[i].subtype;
758 732
759 ret = vfio_info_add_capability(&caps, 733 ret = vfio_info_add_capability(&caps, &cap_type.header,
760 VFIO_REGION_INFO_CAP_TYPE, 734 sizeof(cap_type));