From f9ece2c403bb632d7991964fb72293d387358818 Mon Sep 17 00:00:00 2001 From: Mattias Nissler Date: Tue, 23 Jan 2024 06:35:31 -0800 Subject: [PATCH] Fix DMA message size calculation When performing DMA via VFIO-user commands over the socket, vfu_dma_transfer breaks large requests into chunks according to the client's maximum data transfer size negotiated at connection setup time. This change fixes the calculation of the chunk size for the case where the last chunk is less than the maximum transfer size. Unfortunately, the existing test didn't catch this due to the request size being a multiple of that maximum data transfer size. Adjust the test to make the last chunk size a true remainder. Signed-off-by: Mattias Nissler --- lib/libvfio-user.c | 9 +++++---- test/py/test_sgl_read_write.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index 7f4d4ec6..dc13ea5e 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -2312,13 +2312,14 @@ vfu_dma_transfer(vfu_ctx_t *vfu_ctx, enum vfio_user_command cmd, if (cmd == VFIO_USER_DMA_WRITE) { memcpy(rbuf + sizeof(*dma_req), data + count, dma_req->count); - ret = vfu_ctx->tran->send_msg(vfu_ctx, msg_id++, VFIO_USER_DMA_WRITE, - rbuf, rlen, NULL, + ret = vfu_ctx->tran->send_msg(vfu_ctx, msg_id++, + VFIO_USER_DMA_WRITE, rbuf, + dma_req->count + sizeof(*dma_req), NULL, dma_reply, sizeof(*dma_reply)); } else { ret = vfu_ctx->tran->send_msg(vfu_ctx, msg_id++, VFIO_USER_DMA_READ, - dma_req, sizeof(*dma_req), NULL, - rbuf, rlen); + dma_req, sizeof(*dma_req), NULL, rbuf, + dma_req->count + sizeof(*dma_reply)); } if (ret < 0) { diff --git a/test/py/test_sgl_read_write.py b/test/py/test_sgl_read_write.py index 2f4e9929..2400080a 100644 --- a/test/py/test_sgl_read_write.py +++ b/test/py/test_sgl_read_write.py @@ -156,7 +156,7 @@ def test_dma_read_write(): def test_dma_read_write_large(): ret, sg = vfu_addr_to_sgl(ctx, dma_addr=MAP_ADDR + 0x1000, - length=2 * PAGE_SIZE, + length=2 * PAGE_SIZE + 42, max_nr_sgs=1, prot=mmap.PROT_READ | mmap.PROT_WRITE) assert ret == 1