vfio: Introduce common function to add capabilities
Vendor driver using mediated device framework should use vfio_info_add_capability() to add capabilities. Introduced this function to reduce code duplication in vendor drivers. vfio_info_cap_shift() manipulated a data buffer to add an offset to each element in a chain. This data buffer is documented in a uapi header. Changing vfio_info_cap_shift symbol to be available to all drivers. Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com> Signed-off-by: Neo Jia <cjia@nvidia.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
Родитель
c086de818d
Коммит
b3c0a866f1
|
@ -1797,8 +1797,66 @@ void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset)
|
||||||
for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next - offset)
|
for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next - offset)
|
||||||
tmp->next += offset;
|
tmp->next += offset;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vfio_info_cap_shift);
|
EXPORT_SYMBOL(vfio_info_cap_shift);
|
||||||
|
|
||||||
|
static int sparse_mmap_cap(struct vfio_info_cap *caps, void *cap_type)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pin a set of guest PFNs and return their associated host PFNs for local
|
* Pin a set of guest PFNs and return their associated host PFNs for local
|
||||||
|
|
|
@ -126,6 +126,9 @@ extern struct vfio_info_cap_header *vfio_info_cap_add(
|
||||||
struct vfio_info_cap *caps, size_t size, u16 id, u16 version);
|
struct vfio_info_cap *caps, size_t size, u16 id, u16 version);
|
||||||
extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset);
|
extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset);
|
||||||
|
|
||||||
|
extern int vfio_info_add_capability(struct vfio_info_cap *caps,
|
||||||
|
int cap_type_id, void *cap_type);
|
||||||
|
|
||||||
struct pci_dev;
|
struct pci_dev;
|
||||||
#ifdef CONFIG_EEH
|
#ifdef CONFIG_EEH
|
||||||
extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
|
extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче