diff options
Diffstat (limited to 'drivers/vfio/vfio.c')
-rw-r--r-- | drivers/vfio/vfio.c | 52 |
1 files changed, 4 insertions, 48 deletions
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, |