Skip to content

Commit 97bedb2

Browse files
committed
vhost: Add smp_rmb() in vhost_vq_avail_empty()
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-427.18.1.el9_4 commit-author Gavin Shan <gshan@redhat.com> commit 22e1992 A smp_rmb() has been missed in vhost_vq_avail_empty(), spotted by Will. Otherwise, it's not ensured the available ring entries pushed by guest can be observed by vhost in time, leading to stale available ring entries fetched by vhost in vhost_get_vq_desc(), as reported by Yihuang Yu on NVidia's grace-hopper (ARM64) platform. /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \ -accel kvm -machine virt,gic-version=host -cpu host \ -smp maxcpus=1,cpus=1,sockets=1,clusters=1,cores=1,threads=1 \ -m 4096M,slots=16,maxmem=64G \ -object memory-backend-ram,id=mem0,size=4096M \ : \ -netdev tap,id=vnet0,vhost=true \ -device virtio-net-pci,bus=pcie.8,netdev=vnet0,mac=52:54:00:f1:26:b0 : guest# netperf -H 10.26.1.81 -l 60 -C -c -t UDP_STREAM virtio_net virtio0: output.0:id 100 is not a head! Add the missed smp_rmb() in vhost_vq_avail_empty(). When tx_can_batch() returns true, it means there's still pending tx buffers. Since it might read indices, so it still can bypass the smp_rmb() in vhost_get_vq_desc(). Note that it should be safe until vq->avail_idx is changed by commit 275bf96 ("vhost: better detection of available buffers"). Fixes: 275bf96 ("vhost: better detection of available buffers") Cc: <stable@kernel.org> # v4.11+ Reported-by: Yihuang Yu <yihyu@redhat.com> Suggested-by: Will Deacon <will@kernel.org> Signed-off-by: Gavin Shan <gshan@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Message-Id: <20240328002149.1141302-2-gshan@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> (cherry picked from commit 22e1992) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 83f44e4 commit 97bedb2

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

drivers/vhost/vhost.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2572,9 +2572,19 @@ bool vhost_vq_avail_empty(struct vhost_dev *dev, struct vhost_virtqueue *vq)
25722572
r = vhost_get_avail_idx(vq, &avail_idx);
25732573
if (unlikely(r))
25742574
return false;
2575+
25752576
vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
2577+
if (vq->avail_idx != vq->last_avail_idx) {
2578+
/* Since we have updated avail_idx, the following
2579+
* call to vhost_get_vq_desc() will read available
2580+
* ring entries. Make sure that read happens after
2581+
* the avail_idx read.
2582+
*/
2583+
smp_rmb();
2584+
return false;
2585+
}
25762586

2577-
return vq->avail_idx == vq->last_avail_idx;
2587+
return true;
25782588
}
25792589
EXPORT_SYMBOL_GPL(vhost_vq_avail_empty);
25802590

0 commit comments

Comments
 (0)