diff --git a/lib/vhost/vduse.c b/lib/vhost/vduse.c index 897dee9f1b2..0b5d158feeb 100644 --- a/lib/vhost/vduse.c +++ b/lib/vhost/vduse.c @@ -86,9 +86,10 @@ vduse_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm __rte_unuse size = entry.last - entry.start + 1; mmap_addr = mmap(0, size + entry.offset, entry.perm, MAP_SHARED, fd, 0); - if (!mmap_addr) { + if (mmap_addr == MAP_FAILED) { VHOST_CONFIG_LOG(dev->ifname, ERR, - "Failed to mmap IOTLB entry for 0x%" PRIx64, iova); + "Failed to mmap IOTLB entry for 0x%" PRIx64 ": %s", + iova, strerror(errno)); ret = -1; goto close_fd; } diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h index e9e71c17071..ee61f7415ee 100644 --- a/lib/vhost/vhost.h +++ b/lib/vhost/vhost.h @@ -261,8 +261,9 @@ struct vhost_async { }; #define VHOST_RECONNECT_VERSION 0x0 -#define VHOST_MAX_VRING 0x100 #define VHOST_MAX_QUEUE_PAIRS 0x80 +/* Max vring count: 2 per queue pair plus 1 control queue */ +#define VHOST_MAX_VRING (VHOST_MAX_QUEUE_PAIRS * 2 + 1) struct __rte_cache_aligned vhost_reconnect_vring { uint16_t last_avail_idx; @@ -501,7 +502,7 @@ struct __rte_cache_aligned virtio_net { int extbuf; int linearbuf; - struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2]; + struct vhost_virtqueue *virtqueue[VHOST_MAX_VRING]; rte_rwlock_t iotlb_pending_lock; struct vhost_iotlb_entry *iotlb_pool; diff --git a/lib/vhost/virtio_net_ctrl.c b/lib/vhost/virtio_net_ctrl.c index 603a8db7288..8149885384a 100644 --- a/lib/vhost/virtio_net_ctrl.c +++ b/lib/vhost/virtio_net_ctrl.c @@ -28,7 +28,7 @@ virtio_net_ctrl_pop(struct virtio_net *dev, struct vhost_virtqueue *cvq, struct virtio_net_ctrl_elem *ctrl_elem) __rte_requires_shared_capability(&cvq->iotlb_lock) { - uint16_t avail_idx, desc_idx, n_descs = 0; + uint16_t avail_idx, desc_idx, n_descs = 0, nr_descs, cnt = 0; uint64_t desc_len, desc_addr, desc_iova, data_len = 0; uint8_t *ctrl_req; struct vring_desc *descs; @@ -59,12 +59,19 @@ virtio_net_ctrl_pop(struct virtio_net *dev, struct vhost_virtqueue *cvq, goto err; } + nr_descs = desc_len / sizeof(struct vring_desc); desc_idx = 0; } else { descs = cvq->desc; + nr_descs = cvq->size; } while (1) { + if (unlikely(desc_idx >= nr_descs || ++cnt > nr_descs)) { + VHOST_CONFIG_LOG(dev->ifname, ERR, "Invalid ctrl descriptor chain"); + goto err; + } + desc_len = descs[desc_idx].len; desc_iova = descs[desc_idx].addr; @@ -142,12 +149,23 @@ virtio_net_ctrl_pop(struct virtio_net *dev, struct vhost_virtqueue *cvq, goto free_err; } + nr_descs = desc_len / sizeof(struct vring_desc); desc_idx = 0; } else { descs = cvq->desc; + nr_descs = cvq->size; } - while (!(descs[desc_idx].flags & VRING_DESC_F_WRITE)) { + cnt = 0; + while (1) { + if (unlikely(desc_idx >= nr_descs || ++cnt > nr_descs)) { + VHOST_CONFIG_LOG(dev->ifname, ERR, "Invalid ctrl descriptor chain"); + goto free_err; + } + + if (descs[desc_idx].flags & VRING_DESC_F_WRITE) + break; + desc_len = descs[desc_idx].len; desc_iova = descs[desc_idx].addr;