The result size returned by virtio_pci_admin_dev_parts_get() is 8 bytes
larger than the actual result data size. This occurs because the
result_sg_size field of the command is filled with the result length
from virtqueue_get_buf(), which includes both the data size and an
additional 8 bytes of status.
This oversized result size causes two issues:
1. The state transferred to the destination includes 8 bytes of extra
data at the end.
2. The allocated buffer in the kernel may be smaller than the returned
size, leading to failures when reading beyond the allocated size.
The commit fixes this by subtracting the status size from the result of
virtqueue_get_buf().
This fix has been tested through live migrations with virtio-net,
virtio-net-transitional, and virtio-blk devices.
Fixes: 704806ca400e ("virtio: Extend the admin command to include the result
size")
Signed-off-by: Israel Rukshin <[email protected]>
Reviewed-by: Parav Pandit <[email protected]>
Reviewed-by: Max Gurtovoy <[email protected]>
---
drivers/virtio/virtio_pci_modern.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_pci_modern.c
b/drivers/virtio/virtio_pci_modern.c
index 5eaade757860..7209390a5cbf 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -56,7 +56,8 @@ void vp_modern_avq_done(struct virtqueue *vq)
do {
virtqueue_disable_cb(vq);
while ((cmd = virtqueue_get_buf(vq, &len))) {
- cmd->result_sg_size = len;
+ cmd->result_sg_size =
+ len - sizeof(struct virtio_admin_cmd_status);
complete(&cmd->completion);
}
} while (!virtqueue_enable_cb(vq));
--
2.34.1