diff options
author | Christian Ehrhardt <christian.ehrhardt@canonical.com> | 2019-04-15 14:36:48 +0200 |
---|---|---|
committer | Christian Ehrhardt <christian.ehrhardt@canonical.com> | 2019-04-15 14:39:46 +0200 |
commit | e2bea7436061ca2e7e14bfcfdc5870f2555c3965 (patch) | |
tree | 46c62ce8f227674d6880430f9623edb4e77b9f9a /lib/librte_vhost/virtio_net.c | |
parent | a4f0fa29488e582ab8b5ef9db475b3d26ded690c (diff) |
New upstream version 18.11.1
Change-Id: Ic52e74a9ed6f3ae06acea4a27357bd7153efc2a3
Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Diffstat (limited to 'lib/librte_vhost/virtio_net.c')
-rw-r--r-- | lib/librte_vhost/virtio_net.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 5e1a1a72..15d682c3 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -335,13 +335,22 @@ fill_vec_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq, uint16_t vec_id = *vec_idx; uint32_t len = 0; uint64_t dlen; + uint32_t nr_descs = vq->size; + uint32_t cnt = 0; struct vring_desc *descs = vq->desc; struct vring_desc *idesc = NULL; + if (unlikely(idx >= vq->size)) + return -1; + *desc_chain_head = idx; if (vq->desc[idx].flags & VRING_DESC_F_INDIRECT) { dlen = vq->desc[idx].len; + nr_descs = dlen / sizeof(struct vring_desc); + if (unlikely(nr_descs > vq->size)) + return -1; + descs = (struct vring_desc *)(uintptr_t) vhost_iova_to_vva(dev, vq, vq->desc[idx].addr, &dlen, @@ -366,7 +375,7 @@ fill_vec_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq, } while (1) { - if (unlikely(idx >= vq->size)) { + if (unlikely(idx >= nr_descs || cnt++ >= nr_descs)) { free_ind_table(idesc); return -1; } @@ -520,6 +529,12 @@ fill_vec_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq, if (unlikely(!desc_is_avail(&descs[avail_idx], wrap_counter))) return -1; + /* + * The ordering between desc flags and desc + * content reads need to be enforced. + */ + rte_smp_rmb(); + *desc_count = 0; *len = 0; @@ -527,6 +542,9 @@ fill_vec_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq, if (unlikely(vec_id >= BUF_VECTOR_MAX)) return -1; + if (unlikely(*desc_count >= vq->size)) + return -1; + *desc_count += 1; *buf_id = descs[avail_idx].id; @@ -791,6 +809,12 @@ virtio_dev_rx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, rte_prefetch0(&vq->avail->ring[vq->last_avail_idx & (vq->size - 1)]); avail_head = *((volatile uint16_t *)&vq->avail->idx); + /* + * The ordering between avail index and + * desc reads needs to be enforced. + */ + rte_smp_rmb(); + for (pkt_idx = 0; pkt_idx < count; pkt_idx++) { uint32_t pkt_len = pkts[pkt_idx]->pkt_len + dev->vhost_hlen; uint16_t nr_vec = 0; @@ -1373,6 +1397,12 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, if (free_entries == 0) return 0; + /* + * The ordering between avail index and + * desc reads needs to be enforced. + */ + rte_smp_rmb(); + VHOST_LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__); count = RTE_MIN(count, MAX_PKT_BURST); |