Implement stop operation for vdpa_sim devices, so vhost-vdpa will offer
that backend feature and userspace can effectively stop the device.
This is a must before get virtqueue indexes (base) for live migration,
since the device could modify them after userland gets them. There are
individual ways to perform that action for some devices
(VHOST_NET_SET_BACKEND, VHOST_VSOCK_SET_RUNNING, ...) but there was no
way to perform it for any vhost device (and, in particular, vhost-vdpa).
Comments are welcome.
Eugenio Pérez (4):
vdpa: Add stop operation
vhost-vdpa: introduce STOP backend feature bit
vhost-vdpa: uAPI to stop the device
vdpa_sim: Implement stop vdpa op
drivers/vdpa/vdpa_sim/vdpa_sim.c | 21 +++++++++++++++++++
drivers/vdpa/vdpa_sim/vdpa_sim.h | 1 +
drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 3 +++
drivers/vhost/vdpa.c | 31 ++++++++++++++++++++++++++++
include/linux/vdpa.h | 6 ++++++
include/uapi/linux/vhost.h | 3 +++
include/uapi/linux/vhost_types.h | 2 ++
7 files changed, 67 insertions(+)
--
2.27.0
The ioctl adds support for stop the device from userspace.
Signed-off-by: Eugenio Pérez <[email protected]>
---
drivers/vhost/vdpa.c | 18 ++++++++++++++++++
include/uapi/linux/vhost.h | 3 +++
2 files changed, 21 insertions(+)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index a325bc259afb..da4a8c709bc1 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -478,6 +478,21 @@ static long vhost_vdpa_get_vqs_count(struct vhost_vdpa *v, u32 __user *argp)
return 0;
}
+static long vhost_vdpa_stop(struct vhost_vdpa *v, u32 __user *argp)
+{
+ struct vdpa_device *vdpa = v->vdpa;
+ const struct vdpa_config_ops *ops = vdpa->config;
+ int stop;
+
+ if (!ops->stop)
+ return -EOPNOTSUPP;
+
+ if (copy_to_user(argp, &stop, sizeof(stop)))
+ return -EFAULT;
+
+ return ops->stop(vdpa, stop);
+}
+
static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
void __user *argp)
{
@@ -649,6 +664,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
case VHOST_VDPA_GET_VQS_COUNT:
r = vhost_vdpa_get_vqs_count(v, argp);
break;
+ case VHOST_STOP:
+ r = vhost_vdpa_stop(v, argp);
+ break;
default:
r = vhost_dev_ioctl(&v->vdev, cmd, argp);
if (r == -ENOIOCTLCMD)
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index cab645d4a645..e7526968ab0c 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -171,4 +171,7 @@
#define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, \
struct vhost_vring_state)
+/* Stop or resume a device so it does not process virtqueue requests anymore */
+#define VHOST_STOP _IOW(VHOST_VIRTIO, 0x7D, int)
+
#endif
--
2.27.0