diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 16:18:25 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 16:18:25 -0500 |
| commit | 34b1cf60abb06fa79d5f8e56f1def843dbf91888 (patch) | |
| tree | 2b6145709fa3c5900957cc0f625fad85f9378c7b | |
| parent | 27529c891b132f4fc65711334e885f466138ea2a (diff) | |
| parent | 46ed90f157f42d956ffed17c003f089a59b76e3e (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.c | 15 | ||||
| -rw-r--r-- | drivers/vfio/mdev/vfio_mdev.c | 6 | ||||
| -rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 75 | ||||
| -rw-r--r-- | drivers/vfio/vfio.c | 52 | ||||
| -rw-r--r-- | include/linux/vfio.h | 3 | ||||
| -rw-r--r-- | include/uapi/linux/vfio.h | 10 |
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 | ||
| 114 | int vfio_mdev_probe(struct device *dev) | 114 | static 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 | ||
| 121 | void vfio_mdev_remove(struct device *dev) | 121 | static 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 | ||
| 126 | struct mdev_driver vfio_mdev_driver = { | 126 | static 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 | ||
| 565 | static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev, | 568 | static 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 | ||
| 607 | int vfio_pci_register_dev_region(struct vfio_pci_device *vdev, | 579 | int 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)); |
