Skip to content

Commit e8a3bc8

Browse files
committed
Merge branch 'next' of git://github.com/awilliam/linux-vfio.git
2 parents a95298e + 2b88119 commit e8a3bc8

File tree

16 files changed

+1298
-192
lines changed

16 files changed

+1298
-192
lines changed

drivers/cdx/cdx.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,38 @@ cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev)
211211
return NULL;
212212
}
213213

214+
int cdx_set_master(struct cdx_device *cdx_dev)
215+
{
216+
struct cdx_controller *cdx = cdx_dev->cdx;
217+
struct cdx_device_config dev_config;
218+
int ret = -EOPNOTSUPP;
219+
220+
dev_config.type = CDX_DEV_BUS_MASTER_CONF;
221+
dev_config.bus_master_enable = true;
222+
if (cdx->ops->dev_configure)
223+
ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
224+
cdx_dev->dev_num, &dev_config);
225+
226+
return ret;
227+
}
228+
EXPORT_SYMBOL_GPL(cdx_set_master);
229+
230+
int cdx_clear_master(struct cdx_device *cdx_dev)
231+
{
232+
struct cdx_controller *cdx = cdx_dev->cdx;
233+
struct cdx_device_config dev_config;
234+
int ret = -EOPNOTSUPP;
235+
236+
dev_config.type = CDX_DEV_BUS_MASTER_CONF;
237+
dev_config.bus_master_enable = false;
238+
if (cdx->ops->dev_configure)
239+
ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
240+
cdx_dev->dev_num, &dev_config);
241+
242+
return ret;
243+
}
244+
EXPORT_SYMBOL_GPL(cdx_clear_master);
245+
214246
/**
215247
* cdx_bus_match - device to driver matching callback
216248
* @dev: the cdx device to match against

drivers/cdx/controller/cdx_controller.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ static int cdx_configure_device(struct cdx_controller *cdx,
6666
case CDX_DEV_RESET_CONF:
6767
ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num);
6868
break;
69+
case CDX_DEV_BUS_MASTER_CONF:
70+
ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num,
71+
dev_config->bus_master_enable);
72+
break;
6973
default:
7074
ret = -EINVAL;
7175
}

drivers/cdx/controller/mcdi_functions.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,61 @@ int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num)
168168

169169
return ret;
170170
}
171+
172+
static int cdx_mcdi_ctrl_flag_get(struct cdx_mcdi *cdx, u8 bus_num,
173+
u8 dev_num, u32 *flags)
174+
{
175+
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_IN_LEN);
176+
MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN);
177+
size_t outlen;
178+
int ret;
179+
180+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_BUS, bus_num);
181+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_DEVICE, dev_num);
182+
ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_GET, inbuf,
183+
sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
184+
if (ret)
185+
return ret;
186+
187+
if (outlen != MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN)
188+
return -EIO;
189+
190+
*flags = MCDI_DWORD(outbuf, CDX_DEVICE_CONTROL_GET_OUT_FLAGS);
191+
192+
return 0;
193+
}
194+
195+
static int cdx_mcdi_ctrl_flag_set(struct cdx_mcdi *cdx, u8 bus_num,
196+
u8 dev_num, bool enable, int bit_pos)
197+
{
198+
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_SET_IN_LEN);
199+
u32 flags;
200+
int ret;
201+
202+
/*
203+
* Get flags and then set/reset bit at bit_pos according to
204+
* the input params.
205+
*/
206+
ret = cdx_mcdi_ctrl_flag_get(cdx, bus_num, dev_num, &flags);
207+
if (ret)
208+
return ret;
209+
210+
flags = flags & (u32)(~(BIT(bit_pos)));
211+
if (enable)
212+
flags |= (1 << bit_pos);
213+
214+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_BUS, bus_num);
215+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_DEVICE, dev_num);
216+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_FLAGS, flags);
217+
ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_SET, inbuf,
218+
sizeof(inbuf), NULL, 0, NULL);
219+
220+
return ret;
221+
}
222+
223+
int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,
224+
u8 dev_num, bool enable)
225+
{
226+
return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable,
227+
MC_CMD_CDX_DEVICE_CONTROL_SET_IN_BUS_MASTER_ENABLE_LBN);
228+
}

drivers/cdx/controller/mcdi_functions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,17 @@ int cdx_mcdi_bus_disable(struct cdx_mcdi *cdx, u8 bus_num);
7676
int cdx_mcdi_reset_device(struct cdx_mcdi *cdx,
7777
u8 bus_num, u8 dev_num);
7878

79+
/**
80+
* cdx_mcdi_bus_master_enable - Set/Reset bus mastering for cdx device
81+
* represented by bus_num:dev_num
82+
* @cdx: pointer to MCDI interface.
83+
* @bus_num: Bus number.
84+
* @dev_num: Device number.
85+
* @enable: Enable bus mastering if set, disable otherwise.
86+
*
87+
* Return: 0 on success, <0 on failure
88+
*/
89+
int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,
90+
u8 dev_num, bool enable);
91+
7992
#endif /* CDX_MCDI_FUNCTIONS_H */

drivers/gpu/drm/i915/gvt/kvmgt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,7 +1379,7 @@ static long intel_vgpu_ioctl(struct vfio_device *vfio_dev, unsigned int cmd,
13791379
intel_gvt_reset_vgpu(vgpu);
13801380
return 0;
13811381
} else if (cmd == VFIO_DEVICE_QUERY_GFX_PLANE) {
1382-
struct vfio_device_gfx_plane_info dmabuf;
1382+
struct vfio_device_gfx_plane_info dmabuf = {};
13831383
int ret = 0;
13841384

13851385
minsz = offsetofend(struct vfio_device_gfx_plane_info,

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)