From: Cheng Jiang Date: Thu, 15 Jul 2021 09:50:30 +0000 (+0000) Subject: vhost: fix index overflow for packed ring in async vhost X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=8d2c1260aff404767f7fa61508b864de81e95ce0;p=dpdk.git vhost: fix index overflow for packed ring in async vhost We introduced some new indexes in packed ring of async vhost. They will eventually overflow and lead to errors if the ring size is not a power of 2. This patch is to check and keep these indexes within a reasonable range. Fixes: 873e8dad6f49 ("vhost: support packed ring in async datapath") Cc: stable@dpdk.org Signed-off-by: Cheng Jiang Reviewed-by: Chenbo Xia --- diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c index aa30d147b6..7dba3344fd 100644 --- a/lib/vhost/virtio_net.c +++ b/lib/vhost/virtio_net.c @@ -1943,7 +1943,7 @@ virtio_dev_rx_async_submit_packed(struct virtio_net *dev, slot_idx = (vq->async_pkts_idx + num_async_pkts) % vq->size; if (it_pool[it_idx].count) { - uint16_t from, to; + uint16_t from; async_descs_idx += num_descs; async_fill_desc(&tdes[pkt_burst_idx++], @@ -1962,11 +1962,13 @@ virtio_dev_rx_async_submit_packed(struct virtio_net *dev, * descriptors. */ from = vq->shadow_used_idx - num_buffers; - to = vq->async_buffer_idx_packed % vq->size; store_dma_desc_info_packed(vq->shadow_used_packed, - vq->async_buffers_packed, vq->size, from, to, num_buffers); + vq->async_buffers_packed, vq->size, from, + vq->async_buffer_idx_packed, num_buffers); vq->async_buffer_idx_packed += num_buffers; + if (vq->async_buffer_idx_packed >= vq->size) + vq->async_buffer_idx_packed -= vq->size; vq->shadow_used_idx -= num_buffers; } else { comp_pkts[num_done_pkts++] = pkts[pkt_idx]; @@ -2019,6 +2021,8 @@ virtio_dev_rx_async_submit_packed(struct virtio_net *dev, dma_error_handler_packed(vq, async_descs, async_descs_idx, slot_idx, pkt_err, &pkt_idx, &num_async_pkts, &num_done_pkts); vq->async_pkts_idx += num_async_pkts; + if (vq->async_pkts_idx >= vq->size) + vq->async_pkts_idx -= vq->size; *comp_count = num_done_pkts; if (likely(vq->shadow_used_idx)) { @@ -2067,7 +2071,7 @@ write_back_completed_descs_packed(struct vhost_virtqueue *vq, uint16_t from, to; do { - from = vq->last_async_buffer_idx_packed % vq->size; + from = vq->last_async_buffer_idx_packed; to = (from + nr_left) % vq->size; if (to > from) { vhost_update_used_packed(vq, vq->async_buffers_packed + from, to - from); @@ -2076,7 +2080,7 @@ write_back_completed_descs_packed(struct vhost_virtqueue *vq, } else { vhost_update_used_packed(vq, vq->async_buffers_packed + from, vq->size - from); - vq->last_async_buffer_idx_packed += vq->size - from; + vq->last_async_buffer_idx_packed = 0; nr_left -= vq->size - from; } } while (nr_left > 0); @@ -2159,10 +2163,13 @@ uint16_t rte_vhost_poll_enqueue_completed(int vid, uint16_t queue_id, vhost_vring_call_split(dev, vq); } } else { - if (vq_is_packed(dev)) + if (vq_is_packed(dev)) { vq->last_async_buffer_idx_packed += n_buffers; - else + if (vq->last_async_buffer_idx_packed >= vq->size) + vq->last_async_buffer_idx_packed -= vq->size; + } else { vq->last_async_desc_idx_split += n_descs; + } } done: