qemu-e2k/hw/virtio
Stefan Hajnoczi 3009edff81 vhost-user: fix VHOST_USER_ADD/REM_MEM_REG truncation
QEMU currently truncates the mmap_offset field when sending
VHOST_USER_ADD_MEM_REG and VHOST_USER_REM_MEM_REG messages. The struct
layout looks like this:

  typedef struct VhostUserMemoryRegion {
      uint64_t guest_phys_addr;
      uint64_t memory_size;
      uint64_t userspace_addr;
      uint64_t mmap_offset;
  } VhostUserMemoryRegion;

  typedef struct VhostUserMemRegMsg {
      uint32_t padding;
      /* WARNING: there is a 32-bit hole here! */
      VhostUserMemoryRegion region;
  } VhostUserMemRegMsg;

The payload size is calculated as follows when sending the message in
hw/virtio/vhost-user.c:

  msg->hdr.size = sizeof(msg->payload.mem_reg.padding) +
      sizeof(VhostUserMemoryRegion);

This calculation produces an incorrect result of only 36 bytes.
sizeof(VhostUserMemRegMsg) is actually 40 bytes.

The consequence of this is that the final field, mmap_offset, is
truncated. This breaks x86_64 TCG guests on s390 hosts. Other guest/host
combinations may get lucky if either of the following holds:
1. The guest memory layout does not need mmap_offset != 0.
2. The host is little-endian and mmap_offset <= 0xffffffff so the
   truncation has no effect.

Fix this by extending the existing 32-bit padding field to 64-bit. Now
the padding reflects the actual compiler padding. This can be verified
using pahole(1).

Also document the layout properly in the vhost-user specification.  The
vhost-user spec did not document the exact layout. It would be
impossible to implement the spec without looking at the QEMU source
code.

Existing vhost-user frontends and device backends continue to work after
this fix has been applied. The only change in the wire protocol is that
QEMU now sets hdr.size to 40 instead of 36. If a vhost-user
implementation has a hardcoded size check for 36 bytes, then it will
fail with new QEMUs. Both QEMU and DPDK/SPDK don't check the exact
payload size, so they continue to work.

Fixes: f1aeb14b08 ("Transmit vhost-user memory regions individually")
Cc: Raphael Norwitz <raphael.norwitz@nutanix.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20201109174355.1069147-1-stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Fixes: f1aeb14b08 ("Transmit vhost-user memory regions individually")
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
2020-11-12 09:19:40 -05:00
..
Kconfig virtio-mem: Paravirtualized memory hot(un)plug 2020-07-03 07:57:04 -04:00
meson.build meson: convert hw/virtio 2020-08-21 06:30:26 -04:00
trace-events virtio-iommu: Set supported page size mask 2020-11-03 07:19:27 -05:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
vhost-backend.c hw/virtio/vhost-backend: Fix Coverity CID 1432871 2020-11-03 07:19:27 -05:00
vhost-scsi-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
vhost-stub.c vhost-user: simplify vhost_user_init/vhost_user_cleanup 2019-03-12 21:22:31 -04:00
vhost-user-blk-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
vhost-user-fs-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
vhost-user-fs.c qdev: Unrealize must not fail 2020-05-15 07:08:14 +02:00
vhost-user-input-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
vhost-user-scsi-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
vhost-user-vsock-pci.c vhost-user-vsock-pci: force virtio version 1 2020-09-29 02:15:24 -04:00
vhost-user-vsock.c virtio: add vhost-user-vsock base device 2020-06-12 10:17:06 -04:00
vhost-user.c vhost-user: fix VHOST_USER_ADD/REM_MEM_REG truncation 2020-11-12 09:19:40 -05:00
vhost-vdpa.c hw/virtio/vhost-vdpa: Fix Coverity CID 1432864 2020-10-30 04:29:13 -04:00
vhost-vsock-common.c vhost-vsock: add vhost-vsock-common abstraction 2020-06-12 10:17:06 -04:00
vhost-vsock-pci.c vhost-vsock-pci: force virtio version 1 2020-09-29 02:15:24 -04:00
vhost-vsock.c vhost-vsock: set vhostfd to non-blocking mode 2020-10-30 04:29:13 -04:00
vhost.c vhost-blk: set features before setting inflight feature 2020-11-03 16:39:05 -05:00
virtio-9p-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-balloon-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-balloon.c qapi: Restrict balloon-related commands to machine code 2020-09-29 15:41:35 +02:00
virtio-blk-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-bus.c virtio: notify virtqueue via host notifier when available 2019-11-06 06:35:00 -05:00
virtio-crypto-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-crypto.c virtio-crypto: don't modify elem->in/out_sg 2020-09-23 13:41:58 +01:00
virtio-input-host-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-input-pci.c Use OBJECT_DECLARE_SIMPLE_TYPE when possible 2020-09-18 14:12:32 -04:00
virtio-iommu-pci.c virtio-iommu-pci: force virtio version 1 2020-09-29 02:14:30 -04:00
virtio-iommu.c virtio-iommu: Set supported page size mask 2020-11-03 07:19:27 -05:00
virtio-mem-pci.c virito-mem: Implement get_min_alignment() 2020-11-03 07:19:26 -05:00
virtio-mem-pci.h Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-mem.c virtio-mem: Probe THP size to determine default block size 2020-11-03 07:19:26 -05:00
virtio-mmio.c qemu/atomic.h: rename atomic_ to qatomic_ 2020-09-23 16:07:44 +01:00
virtio-net-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-pci.c virtio: skip legacy support check on machine types less than 5.1 2020-09-29 02:15:24 -04:00
virtio-pci.h Use OBJECT_DECLARE_TYPE when possible 2020-09-18 14:12:32 -04:00
virtio-pmem-pci.c virtio-pmem-pci: force virtio version 1 2020-09-29 02:14:30 -04:00
virtio-pmem-pci.h Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-pmem.c hw: virtio-pmem: detach the element fromt the virtqueue when error occurs 2020-09-29 03:06:12 -04:00
virtio-rng-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-rng.c error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
virtio-scsi-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio-serial-pci.c Use DECLARE_*CHECKER* macros 2020-09-09 09:27:09 -04:00
virtio.c virtio: skip guest index check on device load 2020-10-30 06:48:53 -04:00