|
@@ -1857,63 +1857,19 @@ void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset)
|
|
|
}
|
|
|
EXPORT_SYMBOL(vfio_info_cap_shift);
|
|
|
|
|
|
-static int sparse_mmap_cap(struct vfio_info_cap *caps, void *cap_type)
|
|
|
+int vfio_info_add_capability(struct vfio_info_cap *caps,
|
|
|
+ struct vfio_info_cap_header *cap, size_t size)
|
|
|
{
|
|
|
struct vfio_info_cap_header *header;
|
|
|
- struct vfio_region_info_cap_sparse_mmap *sparse_cap, *sparse = cap_type;
|
|
|
- size_t size;
|
|
|
|
|
|
- size = sizeof(*sparse) + sparse->nr_areas * sizeof(*sparse->areas);
|
|
|
- header = vfio_info_cap_add(caps, size,
|
|
|
- VFIO_REGION_INFO_CAP_SPARSE_MMAP, 1);
|
|
|
+ header = vfio_info_cap_add(caps, size, cap->id, cap->version);
|
|
|
if (IS_ERR(header))
|
|
|
return PTR_ERR(header);
|
|
|
|
|
|
- sparse_cap = container_of(header,
|
|
|
- struct vfio_region_info_cap_sparse_mmap, header);
|
|
|
- sparse_cap->nr_areas = sparse->nr_areas;
|
|
|
- memcpy(sparse_cap->areas, sparse->areas,
|
|
|
- sparse->nr_areas * sizeof(*sparse->areas));
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int region_type_cap(struct vfio_info_cap *caps, void *cap_type)
|
|
|
-{
|
|
|
- struct vfio_info_cap_header *header;
|
|
|
- struct vfio_region_info_cap_type *type_cap, *cap = cap_type;
|
|
|
+ memcpy(header + 1, cap + 1, size - sizeof(*header));
|
|
|
|
|
|
- header = vfio_info_cap_add(caps, sizeof(*cap),
|
|
|
- VFIO_REGION_INFO_CAP_TYPE, 1);
|
|
|
- if (IS_ERR(header))
|
|
|
- return PTR_ERR(header);
|
|
|
-
|
|
|
- type_cap = container_of(header, struct vfio_region_info_cap_type,
|
|
|
- header);
|
|
|
- type_cap->type = cap->type;
|
|
|
- type_cap->subtype = cap->subtype;
|
|
|
return 0;
|
|
|
}
|
|
|
-
|
|
|
-int vfio_info_add_capability(struct vfio_info_cap *caps, int cap_type_id,
|
|
|
- void *cap_type)
|
|
|
-{
|
|
|
- int ret = -EINVAL;
|
|
|
-
|
|
|
- if (!cap_type)
|
|
|
- return 0;
|
|
|
-
|
|
|
- switch (cap_type_id) {
|
|
|
- case VFIO_REGION_INFO_CAP_SPARSE_MMAP:
|
|
|
- ret = sparse_mmap_cap(caps, cap_type);
|
|
|
- break;
|
|
|
-
|
|
|
- case VFIO_REGION_INFO_CAP_TYPE:
|
|
|
- ret = region_type_cap(caps, cap_type);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
EXPORT_SYMBOL(vfio_info_add_capability);
|
|
|
|
|
|
int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, int num_irqs,
|