rte_virtio: check against descriptor table overflow

Don't allow enqueueing a request when not
enough free descriptors are available.

While here, also clarify some other
vq_desc_tail_idx code.

Change-Id: Ibcec2e31b2f609f2fd71f2426ce1a91728ed82f6
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/378154
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-09-12 20:24:09 +02:00 committed by Jim Harris
parent 3459b5a966
commit 8bd15fa161
2 changed files with 16 additions and 2 deletions

View File

@ -139,6 +139,12 @@ virtqueue_enqueue_xmit(struct virtqueue *vq, struct virtio_req *req)
uint32_t total_iovs = req->iovcnt + 2;
struct iovec *iov = req->iov;
if (total_iovs > vq->vq_free_cnt) {
PMD_DRV_LOG(ERR, "not enough free descriptors. requested %"PRIu32", got %"PRIu32"\n",
total_iovs, vq->vq_free_cnt);
return;
}
head_idx = vq->vq_desc_head_idx;
idx = head_idx;
dxp = &vq->vq_descx[idx];
@ -175,8 +181,10 @@ virtqueue_enqueue_xmit(struct virtqueue *vq, struct virtio_req *req)
}
vq->vq_desc_head_idx = idx;
if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
vq->vq_desc_tail_idx = idx;
if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END) {
assert(vq->vq_free_cnt == 0);
vq->vq_desc_tail_idx = VQ_RING_DESC_CHAIN_END;
}
vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - total_iovs);
vq_update_avail_ring(vq, head_idx);
}

View File

@ -97,6 +97,12 @@ struct virtqueue {
* VQ_RING_DESC_CHAIN_END.
*/
uint16_t vq_desc_head_idx;
/**
* Tail of the free chain in desc table. If
* there are no free descriptors, this will be set to
* VQ_RING_DESC_CHAIN_END.
*/
uint16_t vq_desc_tail_idx;
uint16_t vq_queue_index; /**< PCI queue index */
uint16_t *notify_addr;