Commit 5ff81ed4 authored by Gavin Shan's avatar Gavin Shan Committed by chenyi
Browse files

vhost: Add smp_rmb() in vhost_enable_notify()

mainline inclusion
from mainline-v6.9-rc4
commit df9ace7647d4123209395bb9967e998d5758c645
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAHR5K

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=df9ace7647d4123209395bb9967e998d5758c645



----------------------------------------------------

A smp_rmb() has been missed in vhost_enable_notify(), inspired 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_enable_notify(). When it 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 d3bb267b
("vhost: cache avail index in vhost_enable_notify()").

Fixes: d3bb267b ("vhost: cache avail index in vhost_enable_notify()")
Cc: <stable@kernel.org> # v5.18+
Reported-by: default avatarYihuang Yu <yihyu@redhat.com>
Suggested-by: default avatarWill Deacon <will@kernel.org>
Signed-off-by: default avatarGavin Shan <gshan@redhat.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Message-Id: <20240328002149.1141302-3-gshan@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Signed-off-by: default avatarchenyi <chenyi211@huawei.com>
parent 29a70426
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -2583,7 +2583,18 @@ bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
		return false;
	}

	return vhost16_to_cpu(vq, avail_idx) != vq->avail_idx;
	vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
	if (vq->avail_idx != vq->last_avail_idx) {
		/* Since we have updated avail_idx, the following
		 * call to vhost_get_vq_desc() will read available
		 * ring entries. Make sure that read happens after
		 * the avail_idx read.
		 */
		smp_rmb();
		return true;
	}

	return false;
}
EXPORT_SYMBOL_GPL(vhost_enable_notify);