]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
virtio/vhost: don't consider non-MAP_SHARED regions public
authorDaniil Tatianin <d-tatianin@yandex-team.ru>
Thu, 13 Nov 2025 08:58:42 +0000 (11:58 +0300)
committerMichael S. Tsirkin <mst@redhat.com>
Thu, 5 Feb 2026 10:06:45 +0000 (05:06 -0500)
Just having a file descriptor is not enough to consider a memory region
public. If QEMU didn't map it as MAP_SHARED (in case of share=off), guest
writes to this region won't be visible to the vhost-user backend, thus
causing it to read all zeroes or garbage. Make sure we don't pass such
regions and include that to our definition of what a private region is.

Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
Fixes: 552b25229c ("vhost: Rework memslot filtering and fix "used_memslot" tracking")
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251113085842.323745-1-d-tatianin@yandex-team.ru>

hw/virtio/vhost.c

index 31e9704cdc6271becb073065ec38de6f893c85bd..c6a5928cb12fea6e1e5ae9b17edc2e25d96acc57 100644 (file)
@@ -592,11 +592,13 @@ static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section)
         /*
          * Some backends (like vhost-user) can only handle memory regions
          * that have an fd (can be mapped into a different process). Filter
-         * the ones without an fd out, if requested.
-         *
-         * TODO: we might have to limit to MAP_SHARED as well.
+         * the ones without an fd out, if requested. Also make sure that
+         * this region is mapped as shared so that the vhost backend can
+         * observe modifications to this region, otherwise we consider it
+         * private.
          */
-        if (memory_region_get_fd(section->mr) < 0 &&
+        if ((memory_region_get_fd(section->mr) < 0 ||
+            !qemu_ram_is_shared(section->mr->ram_block)) &&
             dev->vhost_ops->vhost_backend_no_private_memslots &&
             dev->vhost_ops->vhost_backend_no_private_memslots(dev)) {
             trace_vhost_reject_section(mr->name, 2);