Messages in this thread Patch in this message | | | From | Nipun Gupta <> | Subject | [PATCH v8 3/3] vfio-cdx: add bus mastering device feature support | Date | Fri, 15 Sep 2023 10:24:23 +0530 |
| |
Support Bus master enable and disable on VFIO-CDX devices using VFIO_DEVICE_FEATURE_BUS_MASTER flag over VFIO_DEVICE_FEATURE IOCTL.
Co-developed-by: Shubham Rohila <shubham.rohila@amd.com> Signed-off-by: Shubham Rohila <shubham.rohila@amd.com> Signed-off-by: Nipun Gupta <nipun.gupta@amd.com> ---
Changes v7->v8: - None
Changes v6->v7: - Add check for BME in open, thus resulting in correct response in feature probe. - Set vdev_regions to NULL in case of error in vfio device open.
Changes v5->v6: - Called CDX device reset at cdx_open_device()
Changes v4->v5: - Use device feature IOCTL instead of adding a new VFIO IOCTL for bus master feature.
Changes in v4: - This patch is newly added which uses cdx_set_master() and cdx_clear_master() APIs.
drivers/vfio/cdx/main.c | 57 +++++++++++++++++++++++++++++++++++++- drivers/vfio/cdx/private.h | 2 ++ 2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/cdx/main.c b/drivers/vfio/cdx/main.c index c376a69d2db2..53ed8e6c499f 100644 --- a/drivers/vfio/cdx/main.c +++ b/drivers/vfio/cdx/main.c @@ -14,7 +14,7 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev) container_of(core_vdev, struct vfio_cdx_device, vdev); struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev); int count = cdx_dev->res_count; - int i; + int i, ret; vdev->regions = kcalloc(count, sizeof(struct vfio_cdx_region), GFP_KERNEL_ACCOUNT); @@ -39,6 +39,17 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev) if (!(cdx_dev->res[i].flags & IORESOURCE_READONLY)) vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_WRITE; } + ret = cdx_dev_reset(core_vdev->dev); + if (ret) { + kfree(vdev->regions); + vdev->regions = NULL; + return ret; + } + ret = cdx_clear_master(cdx_dev); + if (ret) + vdev->flags &= ~BME_SUPPORT; + else + vdev->flags |= BME_SUPPORT; return 0; } @@ -52,6 +63,49 @@ static void vfio_cdx_close_device(struct vfio_device *core_vdev) cdx_dev_reset(core_vdev->dev); } +static int vfio_cdx_bm_ctrl(struct vfio_device *core_vdev, u32 flags, + void __user *arg, size_t argsz) +{ + size_t minsz = + offsetofend(struct vfio_device_feature_bus_master, op); + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev); + struct vfio_device_feature_bus_master ops; + int ret; + + if (!vdev->flags & BME_SUPPORT) + return -ENOTTY; + + ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_SET, + sizeof(ops)); + if (ret != 1) + return ret; + + if (copy_from_user(&ops, arg, minsz)) + return -EFAULT; + + switch (ops.op) { + case VFIO_DEVICE_FEATURE_CLEAR_MASTER: + return cdx_clear_master(cdx_dev); + case VFIO_DEVICE_FEATURE_SET_MASTER: + return cdx_set_master(cdx_dev); + default: + return -EINVAL; + } +} + +static int vfio_cdx_ioctl_feature(struct vfio_device *device, u32 flags, + void __user *arg, size_t argsz) +{ + switch (flags & VFIO_DEVICE_FEATURE_MASK) { + case VFIO_DEVICE_FEATURE_BUS_MASTER: + return vfio_cdx_bm_ctrl(device, flags, arg, argsz); + default: + return -ENOTTY; + } +} + static int vfio_cdx_ioctl_get_info(struct vfio_cdx_device *vdev, struct vfio_device_info __user *arg) { @@ -169,6 +223,7 @@ static const struct vfio_device_ops vfio_cdx_ops = { .open_device = vfio_cdx_open_device, .close_device = vfio_cdx_close_device, .ioctl = vfio_cdx_ioctl, + .device_feature = vfio_cdx_ioctl_feature, .mmap = vfio_cdx_mmap, .bind_iommufd = vfio_iommufd_physical_bind, .unbind_iommufd = vfio_iommufd_physical_unbind, diff --git a/drivers/vfio/cdx/private.h b/drivers/vfio/cdx/private.h index 8bdc117ea88e..8e9d25913728 100644 --- a/drivers/vfio/cdx/private.h +++ b/drivers/vfio/cdx/private.h @@ -23,6 +23,8 @@ struct vfio_cdx_region { struct vfio_cdx_device { struct vfio_device vdev; struct vfio_cdx_region *regions; + u32 flags; +#define BME_SUPPORT BIT(0) }; #endif /* VFIO_CDX_PRIVATE_H */ -- 2.17.1
| |