All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] vhost/migration: Fix incorrect size used in inflight->addr in VMSD
@ 2026-07-28 15:39 Peter Xu
  2026-07-28 20:57 ` Fabiano Rosas
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Peter Xu @ 2026-07-28 15:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: peterx, Michael S. Tsirkin, Fabiano Rosas, Stefano Garzarella,
	김승중, Alexandr Moshkov

It was overlooked that VMSTATE_VBUFFER_UINT64() won't really work with an
uint64_t, as vmstate core only treats the size as 32bits, and maximum
INT32_MAX (see vmstate_size()).

Considering that we do not need real 64bits for the size, stick with the 2G
limit, converting the size field into 32bits.

Since we can't touch the wire protocol on migration from an old QEMU, we
can't directly modify the type of size to uint32_t.  Instead, we need to
introduce a temporary variable for this extremely rare issue __size_32bits
to be used only for VMSTATE_VBUFFER_UINT32().  Document it and name it
weird enough so people won't get confused on having two size variables.

Remove VMSTATE_VBUFFER_UINT64() altogether, because it was never going to
be used right.  It means QEMU will only support 2G max for VMS_VBUFFER.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3675
Reported-by: 김승중 <seungjung0711@gmail.com>
Cc: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Fabiano Rosas <farosas@suse.de>
Fixes: 3a80ff0721 ("vhost: add vmstate for inflight region with inner buffer")
Signed-off-by: Peter Xu <peterx@redhat.com>
---

PS1: I only did smoke test as I'm not fluent with vhost inflight feature.
Please kindly try it out if possible. In general, migrations from older
QEMU should work even after applied.  One can also treat this as partly-RFC
from that.

PS2: Michael, we have just discussed what we should define as CVE for
migration, and this one shouldn't fall into CVE category, please refer to:

https://lore.kernel.org/r/20260721131457.3062767-1-farosas@suse.de

So I didn't yet attach CVE tag.  Please correct if I'm wrong, thanks.
---
 include/hw/virtio/vhost.h   |  5 +++++
 include/migration/vmstate.h | 10 ----------
 hw/virtio/vhost.c           | 19 ++++++++++++++-----
 3 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 684bafcaad..1d1cc24c04 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -17,6 +17,11 @@ struct vhost_inflight {
     int fd;
     void *addr;
     uint64_t size;
+    /*
+     * This is a temporary variable only used during migration loading to
+     * satisfy VMSTATE_VBUFFER_UINT32() typing. Please use @size otherwise.
+     */
+    uint32_t __size_32bits;
     uint64_t offset;
     uint16_t queue_size;
 };
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 1b7f295417..a349b2d84a 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -782,16 +782,6 @@ extern const VMStateInfo vmstate_info_g_byte_array;
     .offset       = offsetof(_state, _field),                        \
 }
 
-#define VMSTATE_VBUFFER_UINT64(_field, _state, _version, _test, _field_size) { \
-    .name         = (stringify(_field)),                             \
-    .version_id   = (_version),                                      \
-    .field_exists = (_test),                                         \
-    .size_offset  = vmstate_offset_value(_state, _field_size, uint64_t),\
-    .info         = &vmstate_info_buffer,                            \
-    .flags        = VMS_VBUFFER | VMS_POINTER,                       \
-    .offset       = offsetof(_state, _field),                        \
-}
-
 #define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version,       \
                                      _test, _field_size) {           \
     .name         = (stringify(_field)),                             \
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index af41841b52..e7c570d0f5 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -2022,15 +2022,24 @@ void vhost_get_features_ex(struct vhost_dev *hdev,
 static bool vhost_inflight_buffer_pre_load(void *opaque, Error **errp)
 {
     struct vhost_inflight *inflight = opaque;
-
     int fd = -1;
-    void *addr = qemu_memfd_alloc("vhost-inflight", inflight->size,
-                                  F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
-                                  &fd, errp);
+    void *addr;
+
+    if (inflight->size > INT32_MAX) {
+        error_setg(errp, "inflight size '%"PRIu64"' exceeds "
+                   "migration limit '%"PRIu32"'", inflight->size, INT32_MAX);
+        return false;
+    }
+
+    addr = qemu_memfd_alloc("vhost-inflight", inflight->size,
+                            F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+                            &fd, errp);
     if (!addr) {
         return false;
     }
 
+    /* Only used in VMSTATE_VBUFFER_UINT32() */
+    inflight->__size_32bits = inflight->size;
     inflight->offset = 0;
     inflight->addr = addr;
     inflight->fd = fd;
@@ -2042,7 +2051,7 @@ const VMStateDescription vmstate_vhost_inflight_region_buffer = {
     .name = "vhost-inflight-region/buffer",
     .pre_load_errp = vhost_inflight_buffer_pre_load,
     .fields = (const VMStateField[]) {
-        VMSTATE_VBUFFER_UINT64(addr, struct vhost_inflight, 0, NULL, size),
+        VMSTATE_VBUFFER_UINT32(addr, struct vhost_inflight, 0, NULL, __size_32bits),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
2.54.0



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

end of thread, other threads:[~2026-07-29 19:27 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 15:39 [PATCH] vhost/migration: Fix incorrect size used in inflight->addr in VMSD Peter Xu
2026-07-28 20:57 ` Fabiano Rosas
2026-07-29 14:00   ` Peter Xu
2026-07-29 14:25     ` Michael S. Tsirkin
2026-07-29 14:27     ` Fabiano Rosas
2026-07-29 15:44       ` Peter Xu
2026-07-29 16:13         ` Fabiano Rosas
2026-07-29 17:40           ` Peter Xu
2026-07-29 17:48           ` Peter Xu
2026-07-29 18:57             ` Michael S. Tsirkin
2026-07-29 19:27               ` Peter Xu
2026-07-28 23:17 ` Michael S. Tsirkin
2026-07-29  7:25 ` Alexandr Moshkov
2026-07-29  8:49   ` Michael S. Tsirkin
2026-07-29 14:16     ` Peter Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.