summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c15
-rw-r--r--drivers/vfio/pci/vfio_pci.c14
-rw-r--r--drivers/vfio/vfio.c52
-rw-r--r--include/linux/vfio.h3
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}
1858EXPORT_SYMBOL(vfio_info_cap_shift); 1858EXPORT_SYMBOL(vfio_info_cap_shift);
1859 1859
1860static int sparse_mmap_cap(struct vfio_info_cap *caps, void *cap_type) 1860int 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
1880static 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
1897int 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}
1917EXPORT_SYMBOL(vfio_info_add_capability); 1873EXPORT_SYMBOL(vfio_info_add_capability);
1918 1874
1919int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs, 1875int 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(
145extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); 145extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset);
146 146
147extern int vfio_info_add_capability(struct vfio_info_cap *caps, 147extern 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
150extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, 151extern 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,