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:
parent
3459b5a966
commit
8bd15fa161
@ -139,6 +139,12 @@ virtqueue_enqueue_xmit(struct virtqueue *vq, struct virtio_req *req)
|
|||||||
uint32_t total_iovs = req->iovcnt + 2;
|
uint32_t total_iovs = req->iovcnt + 2;
|
||||||
struct iovec *iov = req->iov;
|
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;
|
head_idx = vq->vq_desc_head_idx;
|
||||||
idx = head_idx;
|
idx = head_idx;
|
||||||
dxp = &vq->vq_descx[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;
|
vq->vq_desc_head_idx = idx;
|
||||||
if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
|
if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END) {
|
||||||
vq->vq_desc_tail_idx = idx;
|
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->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - total_iovs);
|
||||||
vq_update_avail_ring(vq, head_idx);
|
vq_update_avail_ring(vq, head_idx);
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,12 @@ struct virtqueue {
|
|||||||
* VQ_RING_DESC_CHAIN_END.
|
* VQ_RING_DESC_CHAIN_END.
|
||||||
*/
|
*/
|
||||||
uint16_t vq_desc_head_idx;
|
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_desc_tail_idx;
|
||||||
uint16_t vq_queue_index; /**< PCI queue index */
|
uint16_t vq_queue_index; /**< PCI queue index */
|
||||||
uint16_t *notify_addr;
|
uint16_t *notify_addr;
|
||||||
|
Loading…
Reference in New Issue
Block a user