diff options
-rw-r--r-- | drivers/gpu/drm/i915/gvt/kvmgt.c | 15 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 14 | ||||
-rw-r--r-- | drivers/vfio/vfio.c | 52 | ||||
-rw-r--r-- | include/linux/vfio.h | 3 |
4 files changed, 24 insertions, 60 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/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index a98681dca1d3..de48acd29a84 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c | |||
@@ -585,6 +585,8 @@ static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev, | |||
585 | if (!sparse) | 585 | if (!sparse) |
586 | return -ENOMEM; | 586 | return -ENOMEM; |
587 | 587 | ||
588 | sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP; | ||
589 | sparse->header.version = 1; | ||
588 | sparse->nr_areas = nr_areas; | 590 | sparse->nr_areas = nr_areas; |
589 | 591 | ||
590 | if (vdev->msix_offset & PAGE_MASK) { | 592 | if (vdev->msix_offset & PAGE_MASK) { |
@@ -600,8 +602,7 @@ static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev, | |||
600 | i++; | 602 | i++; |
601 | } | 603 | } |
602 | 604 | ||
603 | ret = vfio_info_add_capability(caps, VFIO_REGION_INFO_CAP_SPARSE_MMAP, | 605 | ret = vfio_info_add_capability(caps, &sparse->header, size); |
604 | sparse); | ||
605 | kfree(sparse); | 606 | kfree(sparse); |
606 | 607 | ||
607 | return ret; | 608 | return ret; |
@@ -744,7 +745,9 @@ static long vfio_pci_ioctl(void *device_data, | |||
744 | break; | 745 | break; |
745 | default: | 746 | default: |
746 | { | 747 | { |
747 | struct vfio_region_info_cap_type cap_type; | 748 | struct vfio_region_info_cap_type cap_type = { |
749 | .header.id = VFIO_REGION_INFO_CAP_TYPE, | ||
750 | .header.version = 1 }; | ||
748 | 751 | ||
749 | if (info.index >= | 752 | if (info.index >= |
750 | VFIO_PCI_NUM_REGIONS + vdev->num_regions) | 753 | VFIO_PCI_NUM_REGIONS + vdev->num_regions) |
@@ -759,9 +762,8 @@ static long vfio_pci_ioctl(void *device_data, | |||
759 | cap_type.type = vdev->region[i].type; | 762 | cap_type.type = vdev->region[i].type; |
760 | cap_type.subtype = vdev->region[i].subtype; | 763 | cap_type.subtype = vdev->region[i].subtype; |
761 | 764 | ||
762 | ret = vfio_info_add_capability(&caps, | 765 | ret = vfio_info_add_capability(&caps, &cap_type.header, |
763 | VFIO_REGION_INFO_CAP_TYPE, | 766 | sizeof(cap_type)); |
764 | &cap_type); | ||
765 | if (ret) | 767 | if (ret) |
766 | return ret; | 768 | return ret; |
767 | 769 | ||
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 2bc3705a99bd..721f97f8dac1 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c | |||
@@ -1857,63 +1857,19 @@ void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset) | |||
1857 | } | 1857 | } |
1858 | EXPORT_SYMBOL(vfio_info_cap_shift); | 1858 | EXPORT_SYMBOL(vfio_info_cap_shift); |
1859 | 1859 | ||
1860 | static int sparse_mmap_cap(struct vfio_info_cap *caps, void *cap_type) | 1860 | int vfio_info_add_capability(struct vfio_info_cap *caps, |
1861 | struct vfio_info_cap_header *cap, size_t size) | ||
1861 | { | 1862 | { |
1862 | struct vfio_info_cap_header *header; | 1863 | struct vfio_info_cap_header *header; |
1863 | struct vfio_region_info_cap_sparse_mmap *sparse_cap, *sparse = cap_type; | ||
1864 | size_t size; | ||
1865 | 1864 | ||
1866 | size = sizeof(*sparse) + sparse->nr_areas * sizeof(*sparse->areas); | 1865 | header = vfio_info_cap_add(caps, size, cap->id, cap->version); |
1867 | header = vfio_info_cap_add(caps, size, | ||
1868 | VFIO_REGION_INFO_CAP_SPARSE_MMAP, 1); | ||
1869 | if (IS_ERR(header)) | 1866 | if (IS_ERR(header)) |
1870 | return PTR_ERR(header); | 1867 | return PTR_ERR(header); |
1871 | 1868 | ||
1872 | sparse_cap = container_of(header, | 1869 | memcpy(header + 1, cap + 1, size - sizeof(*header)); |
1873 | struct vfio_region_info_cap_sparse_mmap, header); | ||
1874 | sparse_cap->nr_areas = sparse->nr_areas; | ||
1875 | memcpy(sparse_cap->areas, sparse->areas, | ||
1876 | sparse->nr_areas * sizeof(*sparse->areas)); | ||
1877 | return 0; | ||
1878 | } | ||
1879 | |||
1880 | static int region_type_cap(struct vfio_info_cap *caps, void *cap_type) | ||
1881 | { | ||
1882 | struct vfio_info_cap_header *header; | ||
1883 | struct vfio_region_info_cap_type *type_cap, *cap = cap_type; | ||
1884 | 1870 | ||
1885 | header = vfio_info_cap_add(caps, sizeof(*cap), | ||
1886 | VFIO_REGION_INFO_CAP_TYPE, 1); | ||
1887 | if (IS_ERR(header)) | ||
1888 | return PTR_ERR(header); | ||
1889 | |||
1890 | type_cap = container_of(header, struct vfio_region_info_cap_type, | ||
1891 | header); | ||
1892 | type_cap->type = cap->type; | ||
1893 | type_cap->subtype = cap->subtype; | ||
1894 | return 0; | 1871 | return 0; |
1895 | } | 1872 | } |
1896 | |||
1897 | int vfio_info_add_capability(struct vfio_info_cap *caps, int cap_type_id, | ||
1898 | void *cap_type) | ||
1899 | { | ||
1900 | int ret = -EINVAL; | ||
1901 | |||
1902 | if (!cap_type) | ||
1903 | return 0; | ||
1904 | |||
1905 | switch (cap_type_id) { | ||
1906 | case VFIO_REGION_INFO_CAP_SPARSE_MMAP: | ||
1907 | ret = sparse_mmap_cap(caps, cap_type); | ||
1908 | break; | ||
1909 | |||
1910 | case VFIO_REGION_INFO_CAP_TYPE: | ||
1911 | ret = region_type_cap(caps, cap_type); | ||
1912 | break; | ||
1913 | } | ||
1914 | |||
1915 | return ret; | ||
1916 | } | ||
1917 | EXPORT_SYMBOL(vfio_info_add_capability); | 1873 | EXPORT_SYMBOL(vfio_info_add_capability); |
1918 | 1874 | ||
1919 | int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs, | 1875 | int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs, |
diff --git a/include/linux/vfio.h b/include/linux/vfio.h index a47b985341d1..66741ab087c1 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h | |||
@@ -145,7 +145,8 @@ extern struct vfio_info_cap_header *vfio_info_cap_add( | |||
145 | extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); | 145 | extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); |
146 | 146 | ||
147 | extern int vfio_info_add_capability(struct vfio_info_cap *caps, | 147 | extern int vfio_info_add_capability(struct vfio_info_cap *caps, |
148 | int cap_type_id, void *cap_type); | 148 | struct vfio_info_cap_header *cap, |
149 | size_t size); | ||
149 | 150 | ||
150 | extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, | 151 | extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, |
151 | int num_irqs, int max_irq_type, | 152 | int num_irqs, int max_irq_type, |