Re: [PATCH] vfio: Simplify capability helper

From: Zhenyu Wang
Date: Wed Dec 13 2017 - 02:07:48 EST


On 2017.12.13 12:13:34 +1100, Alexey Kardashevskiy wrote:
> On 13/12/17 06:59, Alex Williamson wrote:
> > The vfio_info_add_capability() helper requires the caller to pass a
> > capability ID, which it then uses to fill in header fields, assuming
> > hard coded versions. This makes for an awkward and rigid interface.
> > The only thing we want this helper to do is allocate sufficient
> > space in the caps buffer and chain this capability into the list.
> > Reduce it to that simple task.
> >
> > Signed-off-by: Alex Williamson <alex.williamson@xxxxxxxxxx>
>
>
> Makes more sense now, thanks. I'll repost mine on top of this.
>
>
> Reviewed-by: Alexey Kardashevskiy <aik@xxxxxxxxx>
>
>

Looks good for KVMGT part.

Acked-by: Zhenyu Wang <zhenyuw@xxxxxxxxxxxxxxx>

> Below one observation, unrelated to this patch.
>
> > ---
> > drivers/gpu/drm/i915/gvt/kvmgt.c | 15 +++++++----
> > drivers/vfio/pci/vfio_pci.c | 14 ++++++----
> > drivers/vfio/vfio.c | 52 +++-----------------------------------
> > 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,
> > if (!sparse)
> > return -ENOMEM;
> >
> > + sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
> > + sparse->header.version = 1;
> > sparse->nr_areas = nr_areas;
> > cap_type_id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
>
>
> @cap_type_id is initialized in just one of many cases of switch
> (info.index) and after the entire switch, there is switch (cap_type_id). I
> wonder why compiler missed "potentially uninitialized variable here,
> although there is no bug - @cap_type_id is in sync with @spapse. It would
> make it cleaner imho just to have vfio_info_add_capability() next to the
> header initialization.
>

yeah, we could clean that up, thanks for pointing out.

>
>
> > sparse->areas[0].offset =
> > @@ -1033,7 +1035,9 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
> > break;
> > default:
> > {
> > - struct vfio_region_info_cap_type cap_type;
> > + struct vfio_region_info_cap_type cap_type = {
> > + .header.id = VFIO_REGION_INFO_CAP_TYPE,
> > + .header.version = 1 };
> >
> > if (info.index >= VFIO_PCI_NUM_REGIONS +
> > vgpu->vdev.num_regions)
> > @@ -1050,8 +1054,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
> > cap_type.subtype = vgpu->vdev.region[i].subtype;
> >
> > ret = vfio_info_add_capability(&caps,
> > - VFIO_REGION_INFO_CAP_TYPE,
> > - &cap_type);
> > + &cap_type.header,
> > + sizeof(cap_type));
> > if (ret)
> > return ret;
> > }
> > @@ -1061,8 +1065,9 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
> > switch (cap_type_id) {
> > case VFIO_REGION_INFO_CAP_SPARSE_MMAP:
> > ret = vfio_info_add_capability(&caps,
> > - VFIO_REGION_INFO_CAP_SPARSE_MMAP,
> > - sparse);
> > + &sparse->header, sizeof(*sparse) +
> > + (sparse->nr_areas *
> > + sizeof(*sparse->areas)));
> > kfree(sparse);
> > if (ret)
> > return ret;
> > diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
> > index f041b1a6cf66..a73e40983880 100644
> > --- a/drivers/vfio/pci/vfio_pci.c
> > +++ b/drivers/vfio/pci/vfio_pci.c
> > @@ -582,6 +582,8 @@ static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev,
> > if (!sparse)
> > return -ENOMEM;
> >
> > + sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
> > + sparse->header.version = 1;
> > sparse->nr_areas = nr_areas;
> >
> > if (vdev->msix_offset & PAGE_MASK) {
> > @@ -597,8 +599,7 @@ static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev,
> > i++;
> > }
> >
> > - ret = vfio_info_add_capability(caps, VFIO_REGION_INFO_CAP_SPARSE_MMAP,
> > - sparse);
> > + ret = vfio_info_add_capability(caps, &sparse->header, size);
> > kfree(sparse);
> >
> > return ret;
> > @@ -741,7 +742,9 @@ static long vfio_pci_ioctl(void *device_data,
> > break;
> > default:
> > {
> > - struct vfio_region_info_cap_type cap_type;
> > + struct vfio_region_info_cap_type cap_type = {
> > + .header.id = VFIO_REGION_INFO_CAP_TYPE,
> > + .header.version = 1 };
> >
> > if (info.index >=
> > VFIO_PCI_NUM_REGIONS + vdev->num_regions)
> > @@ -756,9 +759,8 @@ static long vfio_pci_ioctl(void *device_data,
> > cap_type.type = vdev->region[i].type;
> > cap_type.subtype = vdev->region[i].subtype;
> >
> > - ret = vfio_info_add_capability(&caps,
> > - VFIO_REGION_INFO_CAP_TYPE,
> > - &cap_type);
> > + ret = vfio_info_add_capability(&caps, &cap_type.header,
> > + sizeof(cap_type));
> > if (ret)
> > return ret;
> >
> > 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)
> > }
> > 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,
> > 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(
> > 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 vfio_info_cap_header *cap,
> > + size_t size);
> >
> > extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr,
> > int num_irqs, int max_irq_type,
> >
>
>
> --
> Alexey

--
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827

Attachment: signature.asc
Description: PGP signature