Skip to content

Commit deefd50

Browse files
committed
Merge tag 'vfio-v6.7-rc1' of https://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Add support for "chunk mode" in the mlx5-vfio-pci variant driver, which allows both larger device image sizes for migration, beyond the previous 4GB limit, and also read-ahead support for improved migration performance (Yishai Hadas) - A new bus master control interface for the CDX bus driver where there is no in-band mechanism to toggle device DMA as there is through config space on PCI devices (Nipun Gupta) - Add explicit alignment directives to vfio data structures to reduce the chance of breaking 32-bit userspace. In most cases this is transparent and the remaining cases where data structures are padded work within the existing rules for extending data structures within vfio (Stefan Hajnoczi) - Resolve a bug in the cdx bus driver noted when compiled with clang where missing parenthesis result in the wrong operation (Nathan Chancellor) - Resolve errors reported by smatch for a function when dealing with invalid inputs (Alex Williamson) - Add migration support to the mtty vfio/mdev sample driver for testing and integration purposes, allowing CI of migration without specific hardware requirements. Also resolve many of the short- comings of this driver relative to implementation of the vfio interrupt ioctl along the way (Alex Williamson) * tag 'vfio-v6.7-rc1' of https://github.com/awilliam/linux-vfio: vfio/mtty: Enable migration support vfio/mtty: Overhaul mtty interrupt handling vfio: Fix smatch errors in vfio_combine_iova_ranges() vfio/cdx: Add parentheses between bitwise AND expression and logical NOT vfio/mlx5: Activate the chunk mode functionality vfio/mlx5: Add support for READING in chunk mode vfio/mlx5: Add support for SAVING in chunk mode vfio/mlx5: Pre-allocate chunks for the STOP_COPY phase vfio/mlx5: Rename some stuff to match chunk mode vfio/mlx5: Enable querying state size which is > 4GB vfio/mlx5: Refactor the SAVE callback to activate a work only upon an error vfio/mlx5: Wake up the reader post of disabling the SAVING migration file vfio: use __aligned_u64 in struct vfio_device_ioeventfd vfio: use __aligned_u64 in struct vfio_device_gfx_plane_info vfio: trivially use __aligned_u64 for ioctl structs vfio-cdx: add bus mastering device feature support vfio: add bus master feature to device feature ioctl cdx: add support for bus mastering
2 parents 009fbfc + 2b88119 commit deefd50

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
@@ -182,6 +182,38 @@ cdx_match_id(const struct cdx_device_id *ids, struct cdx_device *dev)
182182
return NULL;
183183
}
184184

185+
int cdx_set_master(struct cdx_device *cdx_dev)
186+
{
187+
struct cdx_controller *cdx = cdx_dev->cdx;
188+
struct cdx_device_config dev_config;
189+
int ret = -EOPNOTSUPP;
190+
191+
dev_config.type = CDX_DEV_BUS_MASTER_CONF;
192+
dev_config.bus_master_enable = true;
193+
if (cdx->ops->dev_configure)
194+
ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
195+
cdx_dev->dev_num, &dev_config);
196+
197+
return ret;
198+
}
199+
EXPORT_SYMBOL_GPL(cdx_set_master);
200+
201+
int cdx_clear_master(struct cdx_device *cdx_dev)
202+
{
203+
struct cdx_controller *cdx = cdx_dev->cdx;
204+
struct cdx_device_config dev_config;
205+
int ret = -EOPNOTSUPP;
206+
207+
dev_config.type = CDX_DEV_BUS_MASTER_CONF;
208+
dev_config.bus_master_enable = false;
209+
if (cdx->ops->dev_configure)
210+
ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num,
211+
cdx_dev->dev_num, &dev_config);
212+
213+
return ret;
214+
}
215+
EXPORT_SYMBOL_GPL(cdx_clear_master);
216+
185217
/**
186218
* cdx_bus_match - device to driver matching callback
187219
* @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
@@ -56,6 +56,10 @@ static int cdx_configure_device(struct cdx_controller *cdx,
5656
case CDX_DEV_RESET_CONF:
5757
ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num);
5858
break;
59+
case CDX_DEV_BUS_MASTER_CONF:
60+
ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num,
61+
dev_config->bus_master_enable);
62+
break;
5963
default:
6064
ret = -EINVAL;
6165
}

drivers/cdx/controller/mcdi_functions.c

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

138138
return ret;
139139
}
140+
141+
static int cdx_mcdi_ctrl_flag_get(struct cdx_mcdi *cdx, u8 bus_num,
142+
u8 dev_num, u32 *flags)
143+
{
144+
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_IN_LEN);
145+
MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN);
146+
size_t outlen;
147+
int ret;
148+
149+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_BUS, bus_num);
150+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_GET_IN_DEVICE, dev_num);
151+
ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_GET, inbuf,
152+
sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
153+
if (ret)
154+
return ret;
155+
156+
if (outlen != MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_LEN)
157+
return -EIO;
158+
159+
*flags = MCDI_DWORD(outbuf, CDX_DEVICE_CONTROL_GET_OUT_FLAGS);
160+
161+
return 0;
162+
}
163+
164+
static int cdx_mcdi_ctrl_flag_set(struct cdx_mcdi *cdx, u8 bus_num,
165+
u8 dev_num, bool enable, int bit_pos)
166+
{
167+
MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_CONTROL_SET_IN_LEN);
168+
u32 flags;
169+
int ret;
170+
171+
/*
172+
* Get flags and then set/reset bit at bit_pos according to
173+
* the input params.
174+
*/
175+
ret = cdx_mcdi_ctrl_flag_get(cdx, bus_num, dev_num, &flags);
176+
if (ret)
177+
return ret;
178+
179+
flags = flags & (u32)(~(BIT(bit_pos)));
180+
if (enable)
181+
flags |= (1 << bit_pos);
182+
183+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_BUS, bus_num);
184+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_DEVICE, dev_num);
185+
MCDI_SET_DWORD(inbuf, CDX_DEVICE_CONTROL_SET_IN_FLAGS, flags);
186+
ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_CONTROL_SET, inbuf,
187+
sizeof(inbuf), NULL, 0, NULL);
188+
189+
return ret;
190+
}
191+
192+
int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,
193+
u8 dev_num, bool enable)
194+
{
195+
return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable,
196+
MC_CMD_CDX_DEVICE_CONTROL_SET_IN_BUS_MASTER_ENABLE_LBN);
197+
}

drivers/cdx/controller/mcdi_functions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,17 @@ int cdx_mcdi_get_dev_config(struct cdx_mcdi *cdx,
5858
int cdx_mcdi_reset_device(struct cdx_mcdi *cdx,
5959
u8 bus_num, u8 dev_num);
6060

61+
/**
62+
* cdx_mcdi_bus_master_enable - Set/Reset bus mastering for cdx device
63+
* represented by bus_num:dev_num
64+
* @cdx: pointer to MCDI interface.
65+
* @bus_num: Bus number.
66+
* @dev_num: Device number.
67+
* @enable: Enable bus mastering if set, disable otherwise.
68+
*
69+
* Return: 0 on success, <0 on failure
70+
*/
71+
int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num,
72+
u8 dev_num, bool enable);
73+
6174
#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)