diff options
| -rw-r--r-- | virtio.c | 29 | ||||
| -rw-r--r-- | virtio.h | 4 | ||||
| -rw-r--r-- | vu_common.c | 14 |
3 files changed, 32 insertions, 15 deletions
@@ -428,12 +428,18 @@ static bool virtqueue_map_desc(const struct vu_dev *dev, * @vq: Virtqueue * @idx: First descriptor ring entry to map * @elem: Virtqueue element to store descriptor ring iov + * @in_sg: Incoming iovec array for device-writable descriptors + * @max_in_sg: Maximum number of entries in @in_sg + * @out_sg: Outgoing iovec array for device-readable descriptors + * @max_out_sg: Maximum number of entries in @out_sg * * Return: -1 if there is an error, 0 otherwise */ static int vu_queue_map_desc(const struct vu_dev *dev, struct vu_virtq *vq, unsigned int idx, - struct vu_virtq_element *elem) + struct vu_virtq_element *elem, + struct iovec *in_sg, size_t max_in_sg, + struct iovec *out_sg, size_t max_out_sg) { const struct vring_desc *desc = vq->vring.desc; struct vring_desc desc_buf[VIRTQUEUE_MAX_SIZE]; @@ -470,16 +476,16 @@ static int vu_queue_map_desc(const struct vu_dev *dev, /* Collect all the descriptors */ do { if (le16toh(desc[i].flags) & VRING_DESC_F_WRITE) { - if (!virtqueue_map_desc(dev, &in_num, elem->in_sg, - elem->in_num, + if (!virtqueue_map_desc(dev, &in_num, in_sg, + max_in_sg, le64toh(desc[i].addr), le32toh(desc[i].len))) return -1; } else { if (in_num) die("Incorrect order for descriptors"); - if (!virtqueue_map_desc(dev, &out_num, elem->out_sg, - elem->out_num, + if (!virtqueue_map_desc(dev, &out_num, out_sg, + max_out_sg, le64toh(desc[i].addr), le32toh(desc[i].len))) { return -1; @@ -496,7 +502,9 @@ static int vu_queue_map_desc(const struct vu_dev *dev, die("vhost-user: Failed to read descriptor list"); elem->index = idx; + elem->in_sg = in_sg; elem->in_num = in_num; + elem->out_sg = out_sg; elem->out_num = out_num; return 0; @@ -507,11 +515,17 @@ static int vu_queue_map_desc(const struct vu_dev *dev, * @dev: Vhost-user device * @vq: Virtqueue * @elem: Virtqueue element to fill with the entry information + * @in_sg: Incoming iovec array for device-writable descriptors + * @max_in_sg: Maximum number of entries in @in_sg + * @out_sg: Outgoing iovec array for device-readable descriptors + * @max_out_sg: Maximum number of entries in @out_sg * * Return: -1 if there is an error, 0 otherwise */ int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq, - struct vu_virtq_element *elem) + struct vu_virtq_element *elem, + struct iovec *in_sg, size_t max_in_sg, + struct iovec *out_sg, size_t max_out_sg) { unsigned int head; int ret; @@ -535,7 +549,8 @@ int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq, if (vu_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) vring_set_avail_event(vq, vq->last_avail_idx); - ret = vu_queue_map_desc(dev, vq, head, elem); + ret = vu_queue_map_desc(dev, vq, head, elem, in_sg, max_in_sg, + out_sg, max_out_sg); if (ret < 0) return ret; @@ -188,7 +188,9 @@ static inline bool vu_has_protocol_feature(const struct vu_dev *vdev, void vu_queue_notify(const struct vu_dev *dev, struct vu_virtq *vq); int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq, - struct vu_virtq_element *elem); + struct vu_virtq_element *elem, + struct iovec *in_sg, size_t max_in_sg, + struct iovec *out_sg, size_t max_out_sg); void vu_queue_detach_element(struct vu_virtq *vq); void vu_queue_unpop(struct vu_virtq *vq); bool vu_queue_rewind(struct vu_virtq *vq, unsigned int num); diff --git a/vu_common.c b/vu_common.c index 5f2ce18..4d809ac 100644 --- a/vu_common.c +++ b/vu_common.c @@ -91,7 +91,11 @@ int vu_collect(const struct vu_dev *vdev, struct vu_virtq *vq, struct iovec *iov; int ret; - ret = vu_queue_pop(vdev, vq, &elem[elem_cnt]); + ret = vu_queue_pop(vdev, vq, &elem[elem_cnt], + elem[elem_cnt].in_sg, + elem[elem_cnt].in_num, + elem[elem_cnt].out_sg, + elem[elem_cnt].out_num); if (ret < 0) break; @@ -178,12 +182,8 @@ static void vu_handle_tx(struct vu_dev *vdev, int index, int ret; struct iov_tail data; - elem[count].out_num = VU_MAX_TX_BUFFER_NB; - elem[count].out_sg = &out_sg[out_sg_count]; - elem[count].in_num = 0; - elem[count].in_sg = NULL; - - ret = vu_queue_pop(vdev, vq, &elem[count]); + ret = vu_queue_pop(vdev, vq, &elem[count], NULL, 0, + &out_sg[out_sg_count], VU_MAX_TX_BUFFER_NB); if (ret < 0) break; out_sg_count += elem[count].out_num; |
