This patch makes vhost-vdpa bus driver can get/set virtqueue state from userspace VDUSE process. Signed-off-by: Xie Yongji <xieyongji@xxxxxxxxxxxxx> --- Documentation/driver-api/vduse.rst | 4 +++ drivers/vdpa/vdpa_user/vduse_dev.c | 54 ++++++++++++++++++++++++++++++++++++++ include/uapi/linux/vduse.h | 9 +++++++ 3 files changed, 67 insertions(+) diff --git a/Documentation/driver-api/vduse.rst b/Documentation/driver-api/vduse.rst index da9b3040f20a..623f7b040ccf 100644 --- a/Documentation/driver-api/vduse.rst +++ b/Documentation/driver-api/vduse.rst @@ -30,6 +30,10 @@ The following types of messages are provided by the VDUSE framework now: - VDUSE_GET_VQ_READY: Get ready status of virtqueue +- VDUSE_SET_VQ_STATE: Set the state (last_avail_idx) for virtqueue + +- VDUSE_GET_VQ_STATE: Get the state (last_avail_idx) for virtqueue + - VDUSE_SET_FEATURES: Set virtio features supported by the driver - VDUSE_GET_FEATURES: Get virtio features supported by the device diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index 4a869b9698ef..b974333ed4e9 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -291,6 +291,40 @@ static bool vduse_dev_get_vq_ready(struct vduse_dev *dev, return ready; } +static int vduse_dev_get_vq_state(struct vduse_dev *dev, + struct vduse_virtqueue *vq, + struct vdpa_vq_state *state) +{ + struct vduse_dev_msg *msg = vduse_dev_new_msg(dev, VDUSE_GET_VQ_STATE); + int ret; + + msg->req.size = sizeof(struct vduse_vq_state); + msg->req.vq_state.index = vq->index; + + ret = vduse_dev_msg_sync(dev, msg); + state->avail_index = msg->resp.vq_state.avail_idx; + vduse_dev_msg_put(msg); + + return ret; +} + +static int vduse_dev_set_vq_state(struct vduse_dev *dev, + struct vduse_virtqueue *vq, + const struct vdpa_vq_state *state) +{ + struct vduse_dev_msg *msg = vduse_dev_new_msg(dev, VDUSE_SET_VQ_STATE); + int ret; + + msg->req.size = sizeof(struct vduse_vq_state); + msg->req.vq_state.index = vq->index; + msg->req.vq_state.avail_idx = state->avail_index; + + ret = vduse_dev_msg_sync(dev, msg); + vduse_dev_msg_put(msg); + + return ret; +} + static ssize_t vduse_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; @@ -431,6 +465,24 @@ static bool vduse_vdpa_get_vq_ready(struct vdpa_device *vdpa, u16 idx) return vq->ready; } +static int vduse_vdpa_set_vq_state(struct vdpa_device *vdpa, u16 idx, + const struct vdpa_vq_state *state) +{ + struct vduse_dev *dev = vdpa_to_vduse(vdpa); + struct vduse_virtqueue *vq = &dev->vqs[idx]; + + return vduse_dev_set_vq_state(dev, vq, state); +} + +static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx, + struct vdpa_vq_state *state) +{ + struct vduse_dev *dev = vdpa_to_vduse(vdpa); + struct vduse_virtqueue *vq = &dev->vqs[idx]; + + return vduse_dev_get_vq_state(dev, vq, state); +} + static u32 vduse_vdpa_get_vq_align(struct vdpa_device *vdpa) { struct vduse_dev *dev = vdpa_to_vduse(vdpa); @@ -532,6 +584,8 @@ static const struct vdpa_config_ops vduse_vdpa_config_ops = { .set_vq_num = vduse_vdpa_set_vq_num, .set_vq_ready = vduse_vdpa_set_vq_ready, .get_vq_ready = vduse_vdpa_get_vq_ready, + .set_vq_state = vduse_vdpa_set_vq_state, + .get_vq_state = vduse_vdpa_get_vq_state, .get_vq_align = vduse_vdpa_get_vq_align, .get_features = vduse_vdpa_get_features, .set_features = vduse_vdpa_set_features, diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h index f8579abdaa3b..873305dfd93f 100644 --- a/include/uapi/linux/vduse.h +++ b/include/uapi/linux/vduse.h @@ -13,6 +13,8 @@ enum vduse_req_type { VDUSE_SET_VQ_ADDR, VDUSE_SET_VQ_READY, VDUSE_GET_VQ_READY, + VDUSE_SET_VQ_STATE, + VDUSE_GET_VQ_STATE, VDUSE_SET_FEATURES, VDUSE_GET_FEATURES, VDUSE_SET_STATUS, @@ -38,6 +40,11 @@ struct vduse_vq_ready { __u8 ready; }; +struct vduse_vq_state { + __u32 index; + __u16 avail_idx; +}; + struct vduse_dev_config_data { __u32 offset; __u32 len; @@ -53,6 +60,7 @@ struct vduse_dev_request { struct vduse_vq_num vq_num; /* virtqueue num */ struct vduse_vq_addr vq_addr; /* virtqueue address */ struct vduse_vq_ready vq_ready; /* virtqueue ready status */ + struct vduse_vq_state vq_state; /* virtqueue state */ struct vduse_dev_config_data config; /* virtio device config space */ __u64 features; /* virtio features */ __u8 status; /* device status */ @@ -64,6 +72,7 @@ struct vduse_dev_response { __s32 result; /* the result of request */ union { struct vduse_vq_ready vq_ready; /* virtqueue ready status */ + struct vduse_vq_state vq_state; /* virtqueue state */ struct vduse_dev_config_data config; /* virtio device config space */ __u64 features; /* virtio features */ __u8 status; /* device status */ -- 2.11.0