Add an ioctl to allow VDUSE instances to set the VDUSE features supported by the userland VDUSE instance.
Signed-off-by: Eugenio Pérez <[email protected]> --- v4: New in v4. --- drivers/vdpa/vdpa_user/vduse_dev.c | 24 ++++++++++++++++++++++++ include/uapi/linux/vduse.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index e1930e38df7a..4d561b9fbf5e 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -160,6 +160,7 @@ struct vduse_dev_msg { struct vduse_control { u64 api_version; + u64 vduse_features; }; static DEFINE_MUTEX(vduse_lock); @@ -2349,7 +2350,29 @@ static long vduse_ioctl(struct file *file, unsigned int cmd, case VDUSE_GET_FEATURES: ret = put_user(vduse_features, (u64 __user *)argp); break; + case VDUSE_SET_FEATURES: { + u64 features; + ret = -EFAULT; + if (get_user(features, (u64 __user *)argp)) { + dev_dbg(vduse_ctrl_dev, "Could not get vduse features"); + break; + } + + ret = -EINVAL; + if (features & ~vduse_features) { + dev_dbg(vduse_ctrl_dev, + "Invalid features in %llx, expected %llx", + features, vduse_features); + break; + } + + ret = 0; + control->vduse_features = features; + dev_dbg(vduse_ctrl_dev, "Set features %llx", features); + + break; + } default: ret = -EINVAL; break; @@ -2376,6 +2399,7 @@ static int vduse_open(struct inode *inode, struct file *file) return -ENOMEM; control->api_version = VDUSE_API_VERSION_NOT_ASKED; + control->vduse_features = 0; file->private_data = control; return 0; diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h index 89aa3b448c0a..f14c965bb7f6 100644 --- a/include/uapi/linux/vduse.h +++ b/include/uapi/linux/vduse.h @@ -66,6 +66,9 @@ struct vduse_dev_config { /* Get the VDUSE supported features */ #define VDUSE_GET_FEATURES _IOR(VDUSE_BASE, 0x04, __u64) +/* Set the VDUSE features */ +#define VDUSE_SET_FEATURES _IOW(VDUSE_BASE, 0x05, __u64) + /* The ioctls for VDUSE device (/dev/vduse/$NAME) */ /** -- 2.55.0

