public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] virtio_ring: fix avail_wrap_counter in virtqueue_add_packed
@ 2023-08-08  5:10 Yuan Yao
  2023-08-08  5:43 ` Jason Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Yuan Yao @ 2023-08-08  5:10 UTC (permalink / raw)
  To: LKML
  Cc: Keiichi Watanabe, Daniel Verkamp, Takaya Saeki, Junichi Uekawa,
	Yuan Yao, David S. Miller, Jason Wang, Michael S. Tsirkin,
	Tiwei Bie, Xuan Zhuo, virtualization

In current packed virtqueue implementation, the avail_wrap_counter won't
flip, in the case when the driver supplies a descriptor chain with a
length equals to the queue size; total_sg == vq->packed.vring.num.

Let’s assume the following situation:
vq->packed.vring.num=4
vq->packed.next_avail_idx: 1
vq->packed.avail_wrap_counter: 0

Then the driver adds a descriptor chain containing 4 descriptors.

We expect the following result with avail_wrap_counter flipped:
vq->packed.next_avail_idx: 1
vq->packed.avail_wrap_counter: 1

But, the current implementation gives the following result:
vq->packed.next_avail_idx: 1
vq->packed.avail_wrap_counter: 0

To reproduce the bug, you can set a packed queue size as small as
possible, so that the driver is more likely to provide a descriptor
chain with a length equal to the packed queue size. For example, in
qemu run following commands:
sudo qemu-system-x86_64 \
-enable-kvm \
-nographic \
-kernel "path/to/kernel_image" \
-m 1G \
-drive file="path/to/rootfs",if=none,id=disk \
-device virtio-blk,drive=disk \
-drive file="path/to/disk_image",if=none,id=rwdisk \
-device virtio-blk,drive=rwdisk,packed=on,queue-size=4,\
indirect_desc=off \
-append "console=ttyS0 root=/dev/vda rw init=/bin/bash"

Inside the VM, create a directory and mount the rwdisk device on it. The
rwdisk will hang and mount operation will not complete.

This commit fixes the wrap counter error by flipping the
packed.avail_wrap_counter, when start of descriptor chain equals to the
end of descriptor chain (head == i).

Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support")
Signed-off-by: Yuan Yao <yuanyaogoog@chromium.org>
---

 drivers/virtio/virtio_ring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index c5310eaf8b46..da1150d127c2 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1461,7 +1461,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
 		}
 	}
 
-	if (i < head)
+	if (i <= head)
 		vq->packed.avail_wrap_counter ^= 1;
 
 	/* We're using some buffers from the free list. */
-- 
2.41.0.640.ga95def55d0-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread
* [PATCH] virtio_ring: fix avail_wrap_counter in virtqueue_add_packed
@ 2023-08-08  8:32 Yuan Yao
       [not found] ` <CAOJyEHb_KjPawwH+U30iJCDjB-VqH_FR-4qAsUk9T6Sn8FZMBQ@mail.gmail.com>
  0 siblings, 1 reply; 9+ messages in thread
From: Yuan Yao @ 2023-08-08  8:32 UTC (permalink / raw)
  To: LKML
  Cc: Junichi Uekawa, Daniel Verkamp, Takaya Saeki, Keiichi Watanabe,
	Yuan Yao, Jason Wang, David S. Miller, Michael S. Tsirkin,
	Tiwei Bie, Xuan Zhuo, virtualization

In current packed virtqueue implementation, the avail_wrap_counter won't
flip, in the case when the driver supplies a descriptor chain with a
length equals to the queue size; total_sg == vq->packed.vring.num.

Let’s assume the following situation:
vq->packed.vring.num=4
vq->packed.next_avail_idx: 1
vq->packed.avail_wrap_counter: 0

Then the driver adds a descriptor chain containing 4 descriptors.

We expect the following result with avail_wrap_counter flipped:
vq->packed.next_avail_idx: 1
vq->packed.avail_wrap_counter: 1

But, the current implementation gives the following result:
vq->packed.next_avail_idx: 1
vq->packed.avail_wrap_counter: 0

To reproduce the bug, you can set a packed queue size as small as
possible, so that the driver is more likely to provide a descriptor
chain with a length equal to the packed queue size. For example, in
qemu run following commands:
sudo qemu-system-x86_64 \
-enable-kvm \
-nographic \
-kernel "path/to/kernel_image" \
-m 1G \
-drive file="path/to/rootfs",if=none,id=disk \
-device virtio-blk,drive=disk \
-drive file="path/to/disk_image",if=none,id=rwdisk \
-device virtio-blk,drive=rwdisk,packed=on,queue-size=4,\
indirect_desc=off \
-append "console=ttyS0 root=/dev/vda rw init=/bin/bash"

Inside the VM, create a directory and mount the rwdisk device on it. The
rwdisk will hang and mount operation will not complete.

This commit fixes the wrap counter error by flipping the
packed.avail_wrap_counter, when start of descriptor chain equals to the
end of descriptor chain (head == i).

Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support")
Signed-off-by: Yuan Yao <yuanyaogoog@chromium.org>
Acked-by: Jason Wang <jasowang@redhat.com>
---

 drivers/virtio/virtio_ring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index c5310eaf8b46..da1150d127c2 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1461,7 +1461,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
 		}
 	}
 
-	if (i < head)
+	if (i <= head)
 		vq->packed.avail_wrap_counter ^= 1;
 
 	/* We're using some buffers from the free list. */
-- 
2.41.0.640.ga95def55d0-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-08-28  4:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-08  5:10 [PATCH] virtio_ring: fix avail_wrap_counter in virtqueue_add_packed Yuan Yao
2023-08-08  5:43 ` Jason Wang
2023-08-08  5:59   ` Michael S. Tsirkin
2023-08-08  6:05     ` Jason Wang
     [not found]   ` <CAOJyEHaXqmHStJnHrT0H4QsTJBxjBxVe+33EuWm9H3wApPKtxQ@mail.gmail.com>
2023-08-08  6:05     ` Jason Wang
     [not found]       ` <CAOJyEHaR1Y3VsKNpLqxf-ewAEf8JJDChjmnFM_0mv=hOg+X-vA@mail.gmail.com>
2023-08-08  9:13         ` Michael S. Tsirkin
     [not found]           ` <CAOJyEHYgvw7za0ksKNPu9TF1+8MwVFbctMbukgbAoQnf9da+hA@mail.gmail.com>
     [not found]             ` <CAOJyEHZs=59nZ=XTYu-mZWTz18OT7f6TknCxWksYeQZbPy2oUQ@mail.gmail.com>
2023-08-28  4:43               ` Michael S. Tsirkin
  -- strict thread matches above, loose matches on Subject: below --
2023-08-08  8:32 Yuan Yao
     [not found] ` <CAOJyEHb_KjPawwH+U30iJCDjB-VqH_FR-4qAsUk9T6Sn8FZMBQ@mail.gmail.com>
2023-08-10 19:19   ` Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox