Skip to content

Commit 8a97ab9

Browse files
nipung87Alex Williamson
authored andcommitted
vfio-cdx: add bus mastering device feature support
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> Link: https://lore.kernel.org/r/20230915045423.31630-3-nipun.gupta@amd.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent f59a7b6 commit 8a97ab9

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

drivers/vfio/cdx/main.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev)
1414
container_of(core_vdev, struct vfio_cdx_device, vdev);
1515
struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev);
1616
int count = cdx_dev->res_count;
17-
int i;
17+
int i, ret;
1818

1919
vdev->regions = kcalloc(count, sizeof(struct vfio_cdx_region),
2020
GFP_KERNEL_ACCOUNT);
@@ -39,6 +39,17 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev)
3939
if (!(cdx_dev->res[i].flags & IORESOURCE_READONLY))
4040
vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_WRITE;
4141
}
42+
ret = cdx_dev_reset(core_vdev->dev);
43+
if (ret) {
44+
kfree(vdev->regions);
45+
vdev->regions = NULL;
46+
return ret;
47+
}
48+
ret = cdx_clear_master(cdx_dev);
49+
if (ret)
50+
vdev->flags &= ~BME_SUPPORT;
51+
else
52+
vdev->flags |= BME_SUPPORT;
4253

4354
return 0;
4455
}
@@ -52,6 +63,49 @@ static void vfio_cdx_close_device(struct vfio_device *core_vdev)
5263
cdx_dev_reset(core_vdev->dev);
5364
}
5465

66+
static int vfio_cdx_bm_ctrl(struct vfio_device *core_vdev, u32 flags,
67+
void __user *arg, size_t argsz)
68+
{
69+
size_t minsz =
70+
offsetofend(struct vfio_device_feature_bus_master, op);
71+
struct vfio_cdx_device *vdev =
72+
container_of(core_vdev, struct vfio_cdx_device, vdev);
73+
struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev);
74+
struct vfio_device_feature_bus_master ops;
75+
int ret;
76+
77+
if (!vdev->flags & BME_SUPPORT)
78+
return -ENOTTY;
79+
80+
ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_SET,
81+
sizeof(ops));
82+
if (ret != 1)
83+
return ret;
84+
85+
if (copy_from_user(&ops, arg, minsz))
86+
return -EFAULT;
87+
88+
switch (ops.op) {
89+
case VFIO_DEVICE_FEATURE_CLEAR_MASTER:
90+
return cdx_clear_master(cdx_dev);
91+
case VFIO_DEVICE_FEATURE_SET_MASTER:
92+
return cdx_set_master(cdx_dev);
93+
default:
94+
return -EINVAL;
95+
}
96+
}
97+
98+
static int vfio_cdx_ioctl_feature(struct vfio_device *device, u32 flags,
99+
void __user *arg, size_t argsz)
100+
{
101+
switch (flags & VFIO_DEVICE_FEATURE_MASK) {
102+
case VFIO_DEVICE_FEATURE_BUS_MASTER:
103+
return vfio_cdx_bm_ctrl(device, flags, arg, argsz);
104+
default:
105+
return -ENOTTY;
106+
}
107+
}
108+
55109
static int vfio_cdx_ioctl_get_info(struct vfio_cdx_device *vdev,
56110
struct vfio_device_info __user *arg)
57111
{
@@ -169,6 +223,7 @@ static const struct vfio_device_ops vfio_cdx_ops = {
169223
.open_device = vfio_cdx_open_device,
170224
.close_device = vfio_cdx_close_device,
171225
.ioctl = vfio_cdx_ioctl,
226+
.device_feature = vfio_cdx_ioctl_feature,
172227
.mmap = vfio_cdx_mmap,
173228
.bind_iommufd = vfio_iommufd_physical_bind,
174229
.unbind_iommufd = vfio_iommufd_physical_unbind,

drivers/vfio/cdx/private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ struct vfio_cdx_region {
2323
struct vfio_cdx_device {
2424
struct vfio_device vdev;
2525
struct vfio_cdx_region *regions;
26+
u32 flags;
27+
#define BME_SUPPORT BIT(0)
2628
};
2729

2830
#endif /* VFIO_CDX_PRIVATE_H */

0 commit comments

Comments
 (0)