From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643183; cv=none; d=zohomail.com; s=zohoarc; b=IrEJas/jDVd8SvGFi30Z4xYyFyv65PYERZcmg3eOPUTU1XMTClq+zj7VrmyyhKXrAz0ulTIxitsk6ndQB0JlAD/QBotvAefgfizQlDTIOCLaVfgovg3MUHhcHbRWKP5XR5GgNnJ0UiOl6eNwlrRKCjNCZ2YqSq3pHvfVdFMw99I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643183; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=LmdwgA85Tezs/7WxJCpjo7imqLr6jtNRy0nvMCvtd8o=; b=Yv2WW+vcHe5jTIVgUfWyIAnhia1vWNLi93Px/GMn3jAZq7ntDE48wJDCOnR1AH8u7c2kbF4FuzKOTiXOMFSa/p6qV1oy7GeZxnRnBalScj5cOGiEmKuW6aZeGONoN1fwn4p06xuZdWlzcOQmrYOZBvAXfkUmDoQvdW7MwVXjKTg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643183206217.56980352417327; Wed, 4 Mar 2026 08:53:03 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpSt-0000vV-AL; Wed, 04 Mar 2026 11:52:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpSq-0000f3-0e for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:52:48 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpSm-0002dc-MB for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:52:47 -0500 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-52-8TInRZ8tMqeghk8CmrRTVQ-1; Wed, 04 Mar 2026 11:52:42 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AED701800281; Wed, 4 Mar 2026 16:52:39 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 76A9D1800756; Wed, 4 Mar 2026 16:52:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643163; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LmdwgA85Tezs/7WxJCpjo7imqLr6jtNRy0nvMCvtd8o=; b=UmGCILw6OITJlW7D0tVunPGKpK1kvSn4tM3C01wiq+UIBAZZuMg9gdY3UBbhPAoILSgfIr 8oMN+FekBCm48FByuhkAoNfVBvYwPm4RfEfrUOaf7jhtSbDqrmGSmqFV6fta0PEAW/hzcQ 7JR0zXwts3TRaJ+BSgVICmyF3squva0= X-MC-Unique: 8TInRZ8tMqeghk8CmrRTVQ-1 X-Mimecast-MFC-AGG-ID: 8TInRZ8tMqeghk8CmrRTVQ_1772643160 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 1/7] vhost-user: Add VirtIO Shared Memory map request Date: Wed, 4 Mar 2026 17:52:17 +0100 Message-ID: <20260304165223.2166175-2-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 0 X-Spam_score: -0.0 X-Spam_bar: / X-Spam_report: (-0.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643184692154100 Content-Type: text/plain; charset="utf-8" Add SHMEM_MAP/UNMAP requests to vhost-user for dynamic management of VIRTIO Shared Memory mappings. This implementation introduces VirtioSharedMemoryMapping as a unified QOM object that manages both the mapping metadata and MemoryRegion lifecycle. This object provides reference-counted lifecycle management with automatic cleanup of file descriptors and memory regions through QOM finalization. This request allows backends to dynamically map file descriptors into a VIRTIO Shared Memory Region identified by their shmid. Maps are created using memory_region_init_ram_from_fd() with configurable read/write permissions, and the resulting MemoryRegions are added as subregions to the shmem container region. The mapped memory is then advertised to the guest VIRTIO drivers as a base address plus offset for reading and writting according to the requested mmap flags. The backend can unmap memory ranges within a given VIRTIO Shared Memory Region to free resources. Upon receiving this message, the frontend removes the MemoryRegion as a subregion and automatically unreferences the VirtioSharedMemoryMapping object, triggering cleanup if no other references exist. Error handling has been improved to ensure consistent behavior across handlers that manage their own vhost_user_send_resp() calls. Since these handlers clear the VHOST_USER_NEED_REPLY_MASK flag, explicit error checking ensures proper connection closure on failures, maintaining the expected error flow. Note the memory region commit for these operations needs to be delayed until after we reply to the backend to avoid deadlocks. Otherwise, the MemoryListener would send a VHOST_USER_SET_MEM_TABLE message before the reply. Reviewed-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Signed-off-by: Albert Esteve --- hw/virtio/vhost-user.c | 274 ++++++++++++++++++++++ hw/virtio/virtio.c | 201 ++++++++++++++++ include/hw/virtio/virtio.h | 134 +++++++++++ include/system/memory.h | 2 +- subprojects/libvhost-user/libvhost-user.c | 70 ++++++ subprojects/libvhost-user/libvhost-user.h | 54 +++++ system/memory.c | 14 ++ 7 files changed, 748 insertions(+), 1 deletion(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index bb8f8eab77..ff0d1d0ad9 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -104,6 +104,7 @@ typedef enum VhostUserRequest { VHOST_USER_GET_SHARED_OBJECT =3D 41, VHOST_USER_SET_DEVICE_STATE_FD =3D 42, VHOST_USER_CHECK_DEVICE_STATE =3D 43, + VHOST_USER_GET_SHMEM_CONFIG =3D 44, VHOST_USER_MAX } VhostUserRequest; =20 @@ -115,6 +116,8 @@ typedef enum VhostUserBackendRequest { VHOST_USER_BACKEND_SHARED_OBJECT_ADD =3D 6, VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE =3D 7, VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP =3D 8, + VHOST_USER_BACKEND_SHMEM_MAP =3D 9, + VHOST_USER_BACKEND_SHMEM_UNMAP =3D 10, VHOST_USER_BACKEND_MAX } VhostUserBackendRequest; =20 @@ -136,6 +139,12 @@ typedef struct VhostUserMemRegMsg { VhostUserMemoryRegion region; } VhostUserMemRegMsg; =20 +typedef struct VhostUserShMemConfig { + uint32_t nregions; + uint32_t padding; + uint64_t memory_sizes[VIRTIO_MAX_SHMEM_REGIONS]; +} VhostUserShMemConfig; + typedef struct VhostUserLog { uint64_t mmap_size; uint64_t mmap_offset; @@ -192,6 +201,23 @@ typedef struct VhostUserShared { unsigned char uuid[16]; } VhostUserShared; =20 +/* For the flags field of VhostUserMMap */ +#define VHOST_USER_FLAG_MAP_RW (1u << 0) + +typedef struct { + /* VIRTIO Shared Memory Region ID */ + uint8_t shmid; + uint8_t padding[7]; + /* File offset */ + uint64_t fd_offset; + /* Offset within the VIRTIO Shared Memory Region */ + uint64_t shm_offset; + /* Size of the mapping */ + uint64_t len; + /* Flags for the mmap operation, from VHOST_USER_FLAG_MAP_* */ + uint64_t flags; +} VhostUserMMap; + typedef struct { VhostUserRequest request; =20 @@ -224,6 +250,8 @@ typedef union { VhostUserInflight inflight; VhostUserShared object; VhostUserTransferDeviceState transfer_state; + VhostUserMMap mmap; + VhostUserShMemConfig shmem; } VhostUserPayload; =20 typedef struct VhostUserMsg { @@ -1771,6 +1799,196 @@ vhost_user_backend_handle_shared_object_lookup(stru= ct vhost_user *u, return 0; } =20 +/** + * vhost_user_backend_handle_shmem_map() - Handle SHMEM_MAP backend request + * @dev: vhost device + * @ioc: QIOChannel for communication + * @hdr: vhost-user message header + * @payload: message payload containing mapping details + * @fd: file descriptor for the shared memory region + * + * Handles VHOST_USER_BACKEND_SHMEM_MAP requests from the backend. Creates + * a VhostUserShmemObject to manage the shared memory mapping and adds it + * to the appropriate VirtIO shared memory region. The VhostUserShmemObject + * serves as an intermediate parent for the MemoryRegion, ensuring proper + * lifecycle management with reference counting. + * + * Returns: 0 on success, negative errno on failure + */ +static int +vhost_user_backend_handle_shmem_map(struct vhost_dev *dev, + QIOChannel *ioc, + VhostUserHeader *hdr, + VhostUserPayload *payload, + int fd) +{ + VirtioSharedMemory *shmem; + VhostUserMMap *vu_mmap =3D &payload->mmap; + VirtioSharedMemoryMapping *existing; + Error *local_err =3D NULL; + int ret =3D 0; + + if (fd < 0) { + error_report("Bad fd for map"); + ret =3D -EBADF; + goto send_reply; + } + + if (QSIMPLEQ_EMPTY(&dev->vdev->shmem_list)) { + error_report("Device has no VIRTIO Shared Memory Regions. " + "Requested ID: %d", vu_mmap->shmid); + ret =3D -EFAULT; + goto send_reply; + } + + shmem =3D virtio_find_shmem_region(dev->vdev, vu_mmap->shmid); + if (!shmem) { + error_report("VIRTIO Shared Memory Region at " + "ID %d not found or uninitialized", vu_mmap->shmid); + ret =3D -EFAULT; + goto send_reply; + } + + if ((vu_mmap->shm_offset + vu_mmap->len) < vu_mmap->len || + (vu_mmap->shm_offset + vu_mmap->len) > memory_region_size(&shmem->= mr)) { + error_report("Bad offset/len for mmap %" PRIx64 "+%" PRIx64, + vu_mmap->shm_offset, vu_mmap->len); + ret =3D -EFAULT; + goto send_reply; + } + + QTAILQ_FOREACH(existing, &shmem->mmaps, link) { + if (ranges_overlap(existing->offset, existing->len, + vu_mmap->shm_offset, vu_mmap->len)) { + error_report("VIRTIO Shared Memory mapping overlap"); + ret =3D -EFAULT; + goto send_reply; + } + } + + memory_region_transaction_begin(); + + /* Create VirtioSharedMemoryMapping object */ + VirtioSharedMemoryMapping *mapping =3D virtio_shared_memory_mapping_ne= w( + vu_mmap->shmid, fd, vu_mmap->fd_offset, vu_mmap->shm_offset, + vu_mmap->len, vu_mmap->flags & VHOST_USER_FLAG_MAP_RW); + + if (!mapping) { + ret =3D -EFAULT; + goto send_reply_commit; + } + + /* Add the mapping to the shared memory region */ + if (virtio_add_shmem_map(shmem, mapping) !=3D 0) { + error_report("Failed to add shared memory mapping"); + object_unref(OBJECT(mapping)); + ret =3D -EFAULT; + goto send_reply_commit; + } + +send_reply_commit: + /* Send reply and commit after transaction started */ + if (hdr->flags & VHOST_USER_NEED_REPLY_MASK) { + payload->u64 =3D !!ret; + hdr->size =3D sizeof(payload->u64); + if (!vhost_user_send_resp(ioc, hdr, payload, &local_err)) { + error_report_err(local_err); + memory_region_transaction_commit(); + return -EFAULT; + } + } + memory_region_transaction_commit(); + return 0; + +send_reply: + if (hdr->flags & VHOST_USER_NEED_REPLY_MASK) { + payload->u64 =3D !!ret; + hdr->size =3D sizeof(payload->u64); + if (!vhost_user_send_resp(ioc, hdr, payload, &local_err)) { + error_report_err(local_err); + return -EFAULT; + } + } + return 0; +} + +/** + * vhost_user_backend_handle_shmem_unmap() - Handle SHMEM_UNMAP backend re= quest + * @dev: vhost device + * @ioc: QIOChannel for communication + * @hdr: vhost-user message header + * @payload: message payload containing unmapping details + * + * Handles VHOST_USER_BACKEND_SHMEM_UNMAP requests from the backend. Remov= es + * the specified memory mapping from the VirtIO shared memory region. This + * automatically unreferences the associated VhostUserShmemObject, which m= ay + * trigger its finalization and cleanup (munmap, close fd) if no other + * references exist. + * + * Returns: 0 on success, negative errno on failure + */ +static int +vhost_user_backend_handle_shmem_unmap(struct vhost_dev *dev, + QIOChannel *ioc, + VhostUserHeader *hdr, + VhostUserPayload *payload) +{ + VirtioSharedMemory *shmem =3D NULL; + VirtioSharedMemoryMapping *mmap =3D NULL; + VhostUserMMap *vu_mmap =3D &payload->mmap; + Error *local_err =3D NULL; + int ret =3D 0; + + if (QSIMPLEQ_EMPTY(&dev->vdev->shmem_list)) { + error_report("Device has no VIRTIO Shared Memory Regions. " + "Requested ID: %d", vu_mmap->shmid); + ret =3D -EFAULT; + goto send_reply; + } + + shmem =3D virtio_find_shmem_region(dev->vdev, vu_mmap->shmid); + if (!shmem) { + error_report("VIRTIO Shared Memory Region at " + "ID %d not found or uninitialized", vu_mmap->shmid); + ret =3D -EFAULT; + goto send_reply; + } + + if ((vu_mmap->shm_offset + vu_mmap->len) < vu_mmap->len || + (vu_mmap->shm_offset + vu_mmap->len) > memory_region_size(&shmem->= mr)) { + error_report("Bad offset/len for unmmap %" PRIx64 "+%" PRIx64, + vu_mmap->shm_offset, vu_mmap->len); + ret =3D -EFAULT; + goto send_reply; + } + + mmap =3D virtio_find_shmem_map(shmem, vu_mmap->shm_offset, vu_mmap->le= n); + if (!mmap) { + error_report("Shared memory mapping not found at offset %" PRIx64 + " with length %" PRIx64, + vu_mmap->shm_offset, vu_mmap->len); + ret =3D -EFAULT; + goto send_reply; + } + +send_reply: + if (hdr->flags & VHOST_USER_NEED_REPLY_MASK) { + payload->u64 =3D !!ret; + hdr->size =3D sizeof(payload->u64); + if (!vhost_user_send_resp(ioc, hdr, payload, &local_err)) { + error_report_err(local_err); + return -EFAULT; + } + } + + if (!ret && shmem && mmap) { + /* Free the MemoryRegion only after reply */ + virtio_del_shmem_map(shmem, vu_mmap->shm_offset, vu_mmap->len); + } + + return 0; +} + static void close_backend_channel(struct vhost_user *u) { g_source_destroy(u->backend_src); @@ -1844,6 +2062,21 @@ static gboolean backend_read(QIOChannel *ioc, GIOCon= dition condition, ret =3D vhost_user_backend_handle_shared_object_lookup(dev->opaque, &payload.obje= ct); break; + case VHOST_USER_BACKEND_SHMEM_MAP: + /* Handler manages its own response, check error and close connect= ion */ + reply_ack =3D false; + if (vhost_user_backend_handle_shmem_map(dev, ioc, &hdr, &payload, + fd ? fd[0] : -1) < 0) { + goto err; + } + break; + case VHOST_USER_BACKEND_SHMEM_UNMAP: + /* Handler manages its own response, check error and close connect= ion */ + reply_ack =3D false; + if (vhost_user_backend_handle_shmem_unmap(dev, ioc, &hdr, &payload= ) < 0) { + goto err; + } + break; default: error_report("Received unexpected msg type: %d.", hdr.request); ret =3D -EINVAL; @@ -3028,6 +3261,46 @@ static int vhost_user_check_device_state(struct vhos= t_dev *dev, Error **errp) return 0; } =20 +static int vhost_user_get_shmem_config(struct vhost_dev *dev, + int *nregions, + uint64_t *memory_sizes, + Error **errp) +{ + int ret; + VhostUserMsg msg =3D { + .hdr.request =3D VHOST_USER_GET_SHMEM_CONFIG, + .hdr.flags =3D VHOST_USER_VERSION, + }; + + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_SHMEM)) { + *nregions =3D 0; + return 0; + } + + ret =3D vhost_user_write(dev, &msg, NULL, 0); + if (ret < 0) { + return ret; + } + + ret =3D vhost_user_read(dev, &msg); + if (ret < 0) { + return ret; + } + + if (msg.payload.shmem.nregions > VIRTIO_MAX_SHMEM_REGIONS) { + error_setg(errp, "Received too many shared memory regions: %d", + msg.payload.shmem.nregions); + return -EINVAL; + } + + *nregions =3D msg.payload.shmem.nregions; + memcpy(memory_sizes, + &msg.payload.shmem.memory_sizes, + sizeof(uint64_t) * VIRTIO_MAX_SHMEM_REGIONS); + return 0; +} + const VhostOps user_ops =3D { .backend_type =3D VHOST_BACKEND_TYPE_USER, .vhost_backend_init =3D vhost_user_backend_init, @@ -3066,4 +3339,5 @@ const VhostOps user_ops =3D { .vhost_supports_device_state =3D vhost_user_supports_device_state, .vhost_set_device_state_fd =3D vhost_user_set_device_state_fd, .vhost_check_device_state =3D vhost_user_check_device_state, + .vhost_get_shmem_config =3D vhost_user_get_shmem_config, }; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index e9d5532952..96ecb6f1e1 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3113,6 +3113,173 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f) return ret; } =20 +VirtioSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev, uint8_t sh= mid, uint64_t size) +{ + VirtioSharedMemory *elem; + g_autofree char *name =3D NULL; + + elem =3D g_new0(VirtioSharedMemory, 1); + elem->shmid =3D shmid; + + /* Initialize embedded MemoryRegion as container for shmem mappings */ + name =3D g_strdup_printf("virtio-shmem-%d", shmid); + memory_region_init(&elem->mr, OBJECT(vdev), name, size); + QTAILQ_INIT(&elem->mmaps); + QSIMPLEQ_INSERT_TAIL(&vdev->shmem_list, elem, entry); + return elem; +} + +VirtioSharedMemory *virtio_find_shmem_region(VirtIODevice *vdev, uint8_t s= hmid) +{ + VirtioSharedMemory *shmem, *next; + QSIMPLEQ_FOREACH_SAFE(shmem, &vdev->shmem_list, entry, next) { + if (shmem->shmid =3D=3D shmid) { + return shmem; + } + } + return NULL; +} + +static void virtio_shared_memory_mapping_instance_init(Object *obj) +{ + VirtioSharedMemoryMapping *mapping =3D VIRTIO_SHARED_MEMORY_MAPPING(ob= j); + + mapping->shmid =3D 0; + mapping->offset =3D 0; + mapping->len =3D 0; + mapping->mr =3D NULL; +} + +static void virtio_shared_memory_mapping_instance_finalize(Object *obj) +{ + VirtioSharedMemoryMapping *mapping =3D VIRTIO_SHARED_MEMORY_MAPPING(ob= j); + + /* Clean up MemoryRegion if it exists */ + if (mapping->mr) { + /* Unparent the MemoryRegion to trigger cleanup */ + object_unparent(OBJECT(mapping->mr)); + mapping->mr =3D NULL; + } +} + +VirtioSharedMemoryMapping *virtio_shared_memory_mapping_new(uint8_t shmid, + int fd, + uint64_t fd_of= fset, + uint64_t shm_o= ffset, + uint64_t len, + bool allow_wri= te) +{ + VirtioSharedMemoryMapping *mapping; + MemoryRegion *mr; + g_autoptr(GString) mr_name =3D g_string_new(NULL); + uint32_t ram_flags; + Error *local_err =3D NULL; + + if (len =3D=3D 0) { + error_report("Shared memory mapping size cannot be zero"); + return NULL; + } + + fd =3D dup(fd); + if (fd < 0) { + error_report("Failed to duplicate fd: %s", strerror(errno)); + return NULL; + } + + /* Determine RAM flags */ + ram_flags =3D RAM_SHARED; + if (!allow_write) { + ram_flags |=3D RAM_READONLY_FD; + } + + /* Create the VirtioSharedMemoryMapping */ + mapping =3D VIRTIO_SHARED_MEMORY_MAPPING( + object_new(TYPE_VIRTIO_SHARED_MEMORY_MAPPING)); + + /* Set up object properties */ + mapping->shmid =3D shmid; + mapping->offset =3D shm_offset; + mapping->len =3D len; + + /* Create MemoryRegion as a child of this object */ + mr =3D g_new0(MemoryRegion, 1); + g_string_printf(mr_name, "virtio-shmem-%d-%" PRIx64, shmid, shm_offset= ); + + /* Initialize MemoryRegion with file descriptor */ + if (!memory_region_init_ram_from_fd(mr, OBJECT(mapping), mr_name->str, + len, ram_flags, fd, fd_offset, + &local_err)) { + error_report_err(local_err); + g_free(mr); + close(fd); + object_unref(OBJECT(mapping)); + return NULL; + } + + mapping->mr =3D mr; + return mapping; +} + +int virtio_add_shmem_map(VirtioSharedMemory *shmem, + VirtioSharedMemoryMapping *mapping) +{ + if (!mapping) { + error_report("VirtioSharedMemoryMapping cannot be NULL"); + return -1; + } + if (!mapping->mr) { + error_report("VirtioSharedMemoryMapping has no MemoryRegion"); + return -1; + } + + /* Validate boundaries against the VIRTIO shared memory region */ + if (mapping->offset + mapping->len > memory_region_size(&shmem->mr)) { + error_report("Memory exceeds the shared memory boundaries"); + return -1; + } + + /* Add as subregion to the VIRTIO shared memory */ + memory_region_add_subregion(&shmem->mr, mapping->offset, mapping->mr); + + /* Add to the mapped regions list */ + QTAILQ_INSERT_TAIL(&shmem->mmaps, mapping, link); + + return 0; +} + +VirtioSharedMemoryMapping *virtio_find_shmem_map(VirtioSharedMemory *shmem, + hwaddr offset, uint64_t size) +{ + VirtioSharedMemoryMapping *mapping; + QTAILQ_FOREACH(mapping, &shmem->mmaps, link) { + if (mapping->offset =3D=3D offset && mapping->len =3D=3D size) { + return mapping; + } + } + return NULL; +} + +void virtio_del_shmem_map(VirtioSharedMemory *shmem, hwaddr offset, + uint64_t size) +{ + VirtioSharedMemoryMapping *mapping =3D virtio_find_shmem_map(shmem, of= fset, size); + if (mapping =3D=3D NULL) { + return; + } + + /* + * Remove from memory region first + */ + memory_region_del_subregion(&shmem->mr, mapping->mr); + + /* + * Remove from list and unref the mapping which will trigger automatic= cleanup + * when the reference count reaches zero. + */ + QTAILQ_REMOVE(&shmem->mmaps, mapping, link); + object_unref(OBJECT(mapping)); +} + /* A wrapper for use as a VMState .put function */ static int virtio_device_put(QEMUFile *f, void *opaque, size_t size, const VMStateField *field, JSONWriter *vmdes= c) @@ -3238,6 +3405,7 @@ int virtio_set_features_ex(VirtIODevice *vdev, const = uint64_t *features) void virtio_reset(VirtIODevice *vdev) { VirtioDeviceClass *k =3D VIRTIO_DEVICE_GET_CLASS(vdev); + VirtioSharedMemory *shmem; uint64_t features[VIRTIO_FEATURES_NU64S]; int i; =20 @@ -3277,6 +3445,15 @@ void virtio_reset(VirtIODevice *vdev) for (i =3D 0; i < VIRTIO_QUEUE_MAX; i++) { __virtio_queue_reset(vdev, i); } + + /* Mappings are removed to prevent stale fds from remaining open. */ + QSIMPLEQ_FOREACH(shmem, &vdev->shmem_list, entry) { + while (!QTAILQ_EMPTY(&shmem->mmaps)) { + VirtioSharedMemoryMapping *mapping =3D QTAILQ_FIRST(&shmem->mm= aps); + virtio_del_shmem_map(shmem, mapping->offset, + memory_region_size(mapping->mr)); + } + } } =20 static void virtio_device_check_notification_compatibility(VirtIODevice *v= dev, @@ -3600,6 +3777,7 @@ void virtio_init(VirtIODevice *vdev, uint16_t device_= id, size_t config_size) NULL, virtio_vmstate_change, vdev); vdev->device_endian =3D virtio_default_endian(); vdev->use_guest_notifier_mask =3D true; + QSIMPLEQ_INIT(&vdev->shmem_list); } =20 /* @@ -4111,11 +4289,25 @@ static void virtio_device_free_virtqueues(VirtIODev= ice *vdev) static void virtio_device_instance_finalize(Object *obj) { VirtIODevice *vdev =3D VIRTIO_DEVICE(obj); + VirtioSharedMemory *shmem; =20 virtio_device_free_virtqueues(vdev); =20 g_free(vdev->config); g_free(vdev->vector_queues); + while (!QSIMPLEQ_EMPTY(&vdev->shmem_list)) { + shmem =3D QSIMPLEQ_FIRST(&vdev->shmem_list); + while (!QTAILQ_EMPTY(&shmem->mmaps)) { + VirtioSharedMemoryMapping *mapping =3D QTAILQ_FIRST(&shmem->mm= aps); + virtio_del_shmem_map(shmem, mapping->offset, + memory_region_size(mapping->mr)); + } + + /* Clean up the embedded MemoryRegion */ + object_unparent(OBJECT(&shmem->mr)); + QSIMPLEQ_REMOVE_HEAD(&vdev->shmem_list, entry); + g_free(shmem); + } } =20 static const Property virtio_properties[] =3D { @@ -4481,9 +4673,18 @@ static const TypeInfo virtio_device_info =3D { .class_size =3D sizeof(VirtioDeviceClass), }; =20 +static const TypeInfo virtio_shared_memory_mapping_info =3D { + .name =3D TYPE_VIRTIO_SHARED_MEMORY_MAPPING, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(VirtioSharedMemoryMapping), + .instance_init =3D virtio_shared_memory_mapping_instance_init, + .instance_finalize =3D virtio_shared_memory_mapping_instance_finalize, +}; + static void virtio_register_types(void) { type_register_static(&virtio_device_info); + type_register_static(&virtio_shared_memory_mapping_info); } =20 type_init(virtio_register_types) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 9dd93cf965..2dcf58639d 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -99,6 +99,44 @@ enum virtio_device_endian { VIRTIO_DEVICE_ENDIAN_BIG, }; =20 +#define TYPE_VIRTIO_SHARED_MEMORY_MAPPING "virtio-shared-memory-mapping" +OBJECT_DECLARE_SIMPLE_TYPE(VirtioSharedMemoryMapping, VIRTIO_SHARED_MEMORY= _MAPPING) + +/** + * VirtioSharedMemoryMapping: + * @parent: Parent QOM object + * @shmid: VIRTIO Shared Memory Region ID + * @offset: Offset within the VIRTIO Shared Memory Region + * @len: Size of the mapping + * @mr: MemoryRegion associated with this shared memory mapping + * @link: List entry for the shared memory region's mapping list + * + * A QOM object that represents an individual file descriptor-based shared + * memory mapping within a VIRTIO Shared Memory Region. It manages the + * MemoryRegion lifecycle and file descriptor cleanup through QOM reference + * counting. When the object is unreferenced and its reference count drops + * to zero, it automatically cleans up the MemoryRegion and closes the file + * descriptor. + */ +struct VirtioSharedMemoryMapping { + Object parent; + + uint8_t shmid; + hwaddr offset; + uint64_t len; + MemoryRegion *mr; + QTAILQ_ENTRY(VirtioSharedMemoryMapping) link; +}; + +struct VirtioSharedMemory { + uint8_t shmid; + MemoryRegion mr; + QTAILQ_HEAD(, VirtioSharedMemoryMapping) mmaps; + QSIMPLEQ_ENTRY(VirtioSharedMemory) entry; +}; + +typedef struct VirtioSharedMemory VirtioSharedMemory; + /** * struct VirtIODevice - common VirtIO structure * @name: name of the device @@ -168,6 +206,8 @@ struct VirtIODevice */ EventNotifier config_notifier; bool device_iotlb_enabled; + /* Shared memory region for mappings. */ + QSIMPLEQ_HEAD(, VirtioSharedMemory) shmem_list; }; =20 struct VirtioDeviceClass { @@ -298,6 +338,100 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); =20 int virtio_save(VirtIODevice *vdev, QEMUFile *f); =20 +/** + * virtio_new_shmem_region() - Create a new shared memory region + * @vdev: VirtIODevice + * @shmid: Shared memory ID + * @size: Size of the shared memory region + * + * Creates a new VirtioSharedMemory region for the given device and ID. + * The returned VirtioSharedMemory is owned by the VirtIODevice and will + * be automatically freed when the device is destroyed. The caller + * should not free the returned pointer. + * + * Returns: Pointer to the new VirtioSharedMemory region, or NULL on failu= re + */ +VirtioSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev, uint8_t sh= mid, uint64_t size); + +/** + * virtio_find_shmem_region() - Find an existing shared memory region + * @vdev: VirtIODevice + * @shmid: Shared memory ID to find + * + * Finds an existing VirtioSharedMemory region by ID. The returned pointer + * is owned by the VirtIODevice and should not be freed by the caller. + * + * Returns: Pointer to the VirtioSharedMemory region, or NULL if not found + */ +VirtioSharedMemory *virtio_find_shmem_region(VirtIODevice *vdev, uint8_t s= hmid); + +/** + * virtio_shared_memory_mapping_new() - Create a new VirtioSharedMemoryMap= ping + * @shmid: VIRTIO Shared Memory Region ID + * @fd: File descriptor for the shared memory + * @fd_offset: Offset within the file descriptor + * @shm_offset: Offset within the VIRTIO Shared Memory Region + * @len: Size of the mapping + * @allow_write: Whether to allow write access to the mapping + * + * Creates a new VirtioSharedMemoryMapping that manages a shared memory ma= pping. + * The object will create a MemoryRegion using memory_region_init_ram_from= _fd() + * as a child object. When the object is finalized, it will automatically + * clean up the MemoryRegion and close the file descriptor. + * + * Return: A new VirtioSharedMemoryMapping on success, NULL on error. + */ +VirtioSharedMemoryMapping *virtio_shared_memory_mapping_new(uint8_t shmid, + int fd, + uint64_t fd_of= fset, + uint64_t shm_o= ffset, + uint64_t len, + bool allow_wri= te); + +/** + * virtio_add_shmem_map() - Add a memory mapping to a shared region + * @shmem: VirtioSharedMemory region + * @mapping: VirtioSharedMemoryMapping to add (transfers ownership) + * + * Adds a memory mapping to the shared memory region. The VirtioSharedMemo= ryMapping + * ownership is transferred to the shared memory region and will be automa= tically + * cleaned up through QOM reference counting when virtio_del_shmem_map() is + * called or when the shared memory region is destroyed. + * + * Returns: 0 on success, negative errno on failure + */ +int virtio_add_shmem_map(VirtioSharedMemory *shmem, + VirtioSharedMemoryMapping *mapping); + +/** + * virtio_find_shmem_map() - Find a memory mapping in a shared region + * @shmem: VirtioSharedMemory region + * @offset: Offset within the shared memory region + * @size: Size of the mapping to find + * + * Finds an existing memory mapping that covers the specified range. + * The returned VirtioSharedMemoryMapping is owned by the VirtioSharedMemo= ry + * region and should not be freed by the caller. + * + * Returns: Pointer to the VirtioSharedMemoryMapping, or NULL if not found + */ +VirtioSharedMemoryMapping *virtio_find_shmem_map(VirtioSharedMemory *shmem, + hwaddr offset, uint64_t size); + +/** + * virtio_del_shmem_map() - Remove a memory mapping from a shared region + * @shmem: VirtioSharedMemory region + * @offset: Offset of the mapping to remove + * @size: Size of the mapping to remove + * + * Removes a memory mapping from the shared memory region. This will + * automatically unref the associated VhostUserShmemObject, which may + * trigger its finalization and cleanup if no other references exist. + * The mapping's MemoryRegion will be properly unmapped and cleaned up. + */ +void virtio_del_shmem_map(VirtioSharedMemory *shmem, hwaddr offset, + uint64_t size); + extern const VMStateInfo virtio_vmstate_info; =20 #define VMSTATE_VIRTIO_DEVICE \ diff --git a/include/system/memory.h b/include/system/memory.h index 0562af3136..4526c5ac99 100644 --- a/include/system/memory.h +++ b/include/system/memory.h @@ -1489,6 +1489,7 @@ bool memory_region_init_ram_from_file(MemoryRegion *m= r, const char *path, ram_addr_t offset, Error **errp); +#endif =20 /** * memory_region_init_ram_from_fd: Initialize RAM memory region with a @@ -1518,7 +1519,6 @@ bool memory_region_init_ram_from_fd(MemoryRegion *mr, int fd, ram_addr_t offset, Error **errp); -#endif =20 /** * memory_region_init_ram_ptr: Initialize RAM memory region from a diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvho= st-user/libvhost-user.c index 9c630c2170..034cbfdc3c 100644 --- a/subprojects/libvhost-user/libvhost-user.c +++ b/subprojects/libvhost-user/libvhost-user.c @@ -1592,6 +1592,76 @@ vu_rm_shared_object(VuDev *dev, unsigned char uuid[U= UID_LEN]) return vu_send_message(dev, &msg); } =20 +bool +vu_shmem_map(VuDev *dev, uint8_t shmid, uint64_t fd_offset, + uint64_t shm_offset, uint64_t len, uint64_t flags, int fd) +{ + VhostUserMsg vmsg =3D { + .request =3D VHOST_USER_BACKEND_SHMEM_MAP, + .size =3D sizeof(vmsg.payload.mmap), + .flags =3D VHOST_USER_VERSION, + .payload.mmap =3D { + .shmid =3D shmid, + .fd_offset =3D fd_offset, + .shm_offset =3D shm_offset, + .len =3D len, + .flags =3D flags, + }, + .fd_num =3D 1, + .fds[0] =3D fd, + }; + + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_SHMEM)) { + return false; + } + + if (vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_REPLY_ACK)) { + vmsg.flags |=3D VHOST_USER_NEED_REPLY_MASK; + } + + pthread_mutex_lock(&dev->backend_mutex); + if (!vu_message_write(dev, dev->backend_fd, &vmsg)) { + pthread_mutex_unlock(&dev->backend_mutex); + return false; + } + + /* Also unlocks the backend_mutex */ + return vu_process_message_reply(dev, &vmsg); +} + +bool +vu_shmem_unmap(VuDev *dev, uint8_t shmid, uint64_t shm_offset, uint64_t le= n) +{ + VhostUserMsg vmsg =3D { + .request =3D VHOST_USER_BACKEND_SHMEM_UNMAP, + .size =3D sizeof(vmsg.payload.mmap), + .flags =3D VHOST_USER_VERSION, + .payload.mmap =3D { + .shmid =3D shmid, + .fd_offset =3D 0, + .shm_offset =3D shm_offset, + .len =3D len, + }, + }; + + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_SHMEM)) { + return false; + } + + if (vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_REPLY_ACK)) { + vmsg.flags |=3D VHOST_USER_NEED_REPLY_MASK; + } + + pthread_mutex_lock(&dev->backend_mutex); + if (!vu_message_write(dev, dev->backend_fd, &vmsg)) { + pthread_mutex_unlock(&dev->backend_mutex); + return false; + } + + /* Also unlocks the backend_mutex */ + return vu_process_message_reply(dev, &vmsg); +} + static bool vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg) { diff --git a/subprojects/libvhost-user/libvhost-user.h b/subprojects/libvho= st-user/libvhost-user.h index 2ffc58c11b..6a2d0f9fae 100644 --- a/subprojects/libvhost-user/libvhost-user.h +++ b/subprojects/libvhost-user/libvhost-user.h @@ -69,6 +69,8 @@ enum VhostUserProtocolFeature { /* Feature 16 is reserved for VHOST_USER_PROTOCOL_F_STATUS. */ /* Feature 17 reserved for VHOST_USER_PROTOCOL_F_XEN_MMAP. */ VHOST_USER_PROTOCOL_F_SHARED_OBJECT =3D 18, + /* Feature 19 is reserved for VHOST_USER_PROTOCOL_F_DEVICE_STATE */ + VHOST_USER_PROTOCOL_F_SHMEM =3D 20, VHOST_USER_PROTOCOL_F_MAX }; =20 @@ -127,6 +129,8 @@ typedef enum VhostUserBackendRequest { VHOST_USER_BACKEND_SHARED_OBJECT_ADD =3D 6, VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE =3D 7, VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP =3D 8, + VHOST_USER_BACKEND_SHMEM_MAP =3D 9, + VHOST_USER_BACKEND_SHMEM_UNMAP =3D 10, VHOST_USER_BACKEND_MAX } VhostUserBackendRequest; =20 @@ -186,6 +190,23 @@ typedef struct VhostUserShared { unsigned char uuid[UUID_LEN]; } VhostUserShared; =20 +/* For the flags field of VhostUserMMap */ +#define VHOST_USER_FLAG_MAP_RW (1u << 0) + +typedef struct { + /* VIRTIO Shared Memory Region ID */ + uint8_t shmid; + uint8_t padding[7]; + /* File offset */ + uint64_t fd_offset; + /* Offset within the VIRTIO Shared Memory Region */ + uint64_t shm_offset; + /* Size of the mapping */ + uint64_t len; + /* Flags for the mmap operation, from VHOST_USER_FLAG_MAP_* */ + uint64_t flags; +} VhostUserMMap; + #define VU_PACKED __attribute__((packed)) =20 typedef struct VhostUserMsg { @@ -210,6 +231,7 @@ typedef struct VhostUserMsg { VhostUserVringArea area; VhostUserInflight inflight; VhostUserShared object; + VhostUserMMap mmap; } payload; =20 int fds[VHOST_MEMORY_BASELINE_NREGIONS]; @@ -593,6 +615,38 @@ bool vu_add_shared_object(VuDev *dev, unsigned char uu= id[UUID_LEN]); */ bool vu_rm_shared_object(VuDev *dev, unsigned char uuid[UUID_LEN]); =20 +/** + * vu_shmem_map: + * @dev: a VuDev context + * @shmid: VIRTIO Shared Memory Region ID + * @fd_offset: File offset + * @shm_offset: Offset within the VIRTIO Shared Memory Region + * @len: Size of the mapping + * @flags: Flags for the mmap operation + * @fd: A file descriptor + * + * Advertises a new mapping to be made in a given VIRTIO Shared Memory Reg= ion. + * + * Returns: TRUE on success, FALSE on failure. + */ +bool vu_shmem_map(VuDev *dev, uint8_t shmid, uint64_t fd_offset, + uint64_t shm_offset, uint64_t len, uint64_t flags, int f= d); + +/** + * vu_shmem_unmap: + * @dev: a VuDev context + * @shmid: VIRTIO Shared Memory Region ID + * @fd_offset: File offset + * @len: Size of the mapping + * + * The front-end un-mmaps a given range in the VIRTIO Shared Memory Region + * with the requested `shmid`. + * + * Returns: TRUE on success, FALSE on failure. + */ +bool vu_shmem_unmap(VuDev *dev, uint8_t shmid, uint64_t shm_offset, + uint64_t len); + /** * vu_queue_set_notification: * @dev: a VuDev context diff --git a/system/memory.c b/system/memory.c index c51d0798a8..5fe18d6757 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1691,6 +1691,20 @@ bool memory_region_init_ram_from_fd(MemoryRegion *mr, } return true; } +#else +bool memory_region_init_ram_from_fd(MemoryRegion *mr, + Object *owner, + const char *name, + uint64_t size, + uint32_t ram_flags, + int fd, + ram_addr_t offset, + Error **errp) +{ + error_setg(errp, + "memory_region_init_ram_from_fd is not supported on this pl= atform"); + return false; +} #endif =20 void memory_region_init_ram_ptr(MemoryRegion *mr, --=20 2.52.0 From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643205; cv=none; d=zohomail.com; s=zohoarc; b=cJ0pcX7xcMWgrvKshIBkHkdp3Mnm3sta+uAXbabW28s9MPA01FW5bBUiIIPWHEgXjPFK0skXTAvBkRI6F/3RGfjru7kM7nfU2vcek82RewIAO8e7UGE0+HRrJKFufIu9pu6agBDkj2Hhw4mWmXLSmV5N3wAduxrFfjSr0ZOAc4Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643205; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=n1YOyGi2s28s7hb7l7rmjW1KUb63pKzOC/D9dpeJAUE=; b=HrH23BrTyhThM8bLkvCQNMln6BfiHMFPScToz+hCT8JOjDclDjaib4V5eIj9IXSun4cjX8Cm1nYwuD+XQzvxEgQCGkHM7OUs5h2ONleHqe7laaGnww+Wi/SxjrRGFZ2769P8ynqylhVwN1udLnufLoeSn5fo9Z8C+4a2kiCMRqM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643205681455.6716826731805; Wed, 4 Mar 2026 08:53:25 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpSy-0001Cp-6z; Wed, 04 Mar 2026 11:52:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpSv-00011E-DY for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:52:53 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpSu-0002eE-3D for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:52:53 -0500 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-621-SaAxE2c0NXeH7KQy1dhqDA-1; Wed, 04 Mar 2026 11:52:47 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6F7D61800371; Wed, 4 Mar 2026 16:52:46 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 892B3180035F; Wed, 4 Mar 2026 16:52:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643171; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n1YOyGi2s28s7hb7l7rmjW1KUb63pKzOC/D9dpeJAUE=; b=ed37T3ogPSkvCeIzyOQrJjbMYpDr0wJ1iI6GNbOW//mxw8HsnBZ//C/ylhAoHfo5MVCE4A lU9iIsfWE9ZniXPcFEFXAshjE1I8/9lBLy+ezo2qIvo87aKHf77z98FVlMfFGu9JQo2X5T 0MfBzmf1avw0NCB3TJnvQ3UQJPKdKD0= X-MC-Unique: SaAxE2c0NXeH7KQy1dhqDA-1 X-Mimecast-MFC-AGG-ID: SaAxE2c0NXeH7KQy1dhqDA_1772643166 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 2/7] vhost_user.rst: Align VhostUserMsg excerpt members Date: Wed, 4 Mar 2026 17:52:18 +0100 Message-ID: <20260304165223.2166175-3-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 0 X-Spam_score: -0.0 X-Spam_bar: / X-Spam_report: (-0.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643206873154100 Content-Type: text/plain; charset="utf-8" Add missing members to the VhostUserMsg excerpt in the vhost-user spec documentation. Reviewed-by: Stefano Garzarella Reviewed-by: David Hildenbrand Reviewed-by: Stefan Hajnoczi Signed-off-by: Albert Esteve --- docs/interop/vhost-user.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 137c9f3669..4c1538cf88 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -366,11 +366,15 @@ In QEMU the vhost-user message is implemented with th= e following struct: struct vhost_vring_state state; struct vhost_vring_addr addr; VhostUserMemory memory; + VhostUserMemRegMsg mem_reg; VhostUserLog log; struct vhost_iotlb_msg iotlb; VhostUserConfig config; + VhostUserCryptoSession session; VhostUserVringArea area; VhostUserInflight inflight; + VhostUserShared object; + VhostUserTransferDeviceState transfer_state; }; } QEMU_PACKED VhostUserMsg; =20 --=20 2.52.0 From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643196; cv=none; d=zohomail.com; s=zohoarc; b=QjpQBHGbpne3vNUmX0pcrWaYwYyDj1hgvl0oICg+tlL4RawT1Nw62JclGq2nhB9WqJuBhRdTq3DF9fME43SJaXQS40fBEjiO+y2MThhVztwh+QSA+3y0uf04qHmw76zRuUNfVVfMOeU004Nl3oWYInLzLypbkUO3qDi8quq60OQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643196; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=hon6YFACQydjiVC2MLBH4P+JHfOzlsYj8EtkcwJKskg=; b=EzPQ73omADetmWZ9QBmwqamf+LrTK9kEnLUVRB2a/PPklZlbf6EyJiOnHuENft5YJF++I7Vnfp7AjRS7Os24vuEj7MC4u0JVEuCmoYeedVKIQFaBxBfxap2Nu7laXspB2fz6y9tZS6ti93XQo3N4cDeOIfm1WFSFi3tmqctVlWY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643196663412.58463334599367; Wed, 4 Mar 2026 08:53:16 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpT5-0001cr-Ce; Wed, 04 Mar 2026 11:53:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpT2-0001Pp-EP for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:01 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpT0-0002f6-W0 for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:00 -0500 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-414-_fb43jOkPLGvfB81hvDKPg-1; Wed, 04 Mar 2026 11:52:55 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 759501956059; Wed, 4 Mar 2026 16:52:53 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EDE251800361; Wed, 4 Mar 2026 16:52:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643178; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hon6YFACQydjiVC2MLBH4P+JHfOzlsYj8EtkcwJKskg=; b=aWhJQMRZ+N3RHvO7YKnbgQ0GLbA66laszmJy5kD0oVB064XL/VhFhtNlIYcQhl/jIlL4E/ iGy3/EFUAIlxflSE8xfY/fnkNhhXHypvnFJ7rGJJbf8sGJJ7v+gzEDr3u1YBIdHD+O5qpw bhB53Int8610lnYGO/V09l21zM8EKus= X-MC-Unique: _fb43jOkPLGvfB81hvDKPg-1 X-Mimecast-MFC-AGG-ID: _fb43jOkPLGvfB81hvDKPg_1772643173 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 3/7] vhost_user.rst: Add SHMEM_MAP/_UNMAP to spec Date: Wed, 4 Mar 2026 17:52:19 +0100 Message-ID: <20260304165223.2166175-4-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 33 X-Spam_score: 3.3 X-Spam_bar: +++ X-Spam_report: (3.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643198776154100 Content-Type: text/plain; charset="utf-8" Add SHMEM_MAP/_UNMAP request to the vhost-user spec documentation. Reviewed-by: Stefano Garzarella Reviewed-by: Alyssa Ross Reviewed-by: Stefan Hajnoczi Reviewed-by: Manos Pitsidianakis Signed-off-by: Albert Esteve --- docs/interop/vhost-user.rst | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 4c1538cf88..08a5e43988 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -350,6 +350,27 @@ Device state transfer parameters In the future, additional phases might be added e.g. to allow iterative migration while the device is running. =20 +MMAP request +^^^^^^^^^^^^ + ++-------+---------+-----------+------------+-----+-------+ +| shmid | padding | fd_offset | shm_offset | len | flags | ++-------+---------+-----------+------------+-----+-------+ + +:shmid: a 8-bit shared memory region identifier + +:fd_offset: a 64-bit offset of this area from the start + of the supplied file descriptor + +:shm_offset: a 64-bit offset from the start of the + pointed shared memory region + +:len: a 64-bit size of the memory to map + +:flags: a 64-bit value: + - 0: Pages are mapped read-only + - 1: Pages are mapped read-write + C structure ----------- =20 @@ -375,6 +396,7 @@ In QEMU the vhost-user message is implemented with the = following struct: VhostUserInflight inflight; VhostUserShared object; VhostUserTransferDeviceState transfer_state; + VhostUserMMap mmap; }; } QEMU_PACKED VhostUserMsg; =20 @@ -1067,6 +1089,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_SHARED_OBJECT 18 #define VHOST_USER_PROTOCOL_F_DEVICE_STATE 19 #define VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT 20 + #define VHOST_USER_PROTOCOL_F_SHMEM_MAP 21 =20 Front-end message types ----------------------- @@ -1888,6 +1911,44 @@ is sent by the front-end. when the operation is successful, or non-zero otherwise. Note that if the operation fails, no fd is sent to the backend. =20 +``VHOST_USER_BACKEND_SHMEM_MAP`` + :id: 9 + :equivalent ioctl: N/A + :request payload: fd and ``struct VhostUserMMap`` + :reply payload: N/A + + When the ``VHOST_USER_PROTOCOL_F_SHMEM`` protocol feature has been + successfully negotiated, this message can be submitted by the backends to + advertise a new mapping to be made in a given VIRTIO Shared Memory Regio= n. + Upon receiving the message, the front-end will mmap the given fd into the + VIRTIO Shared Memory Region with the requested ``shmid``. + If ``VHOST_USER_PROTOCOL_F_REPLY_ACK`` is negotiated, and + back-end set the ``VHOST_USER_NEED_REPLY`` flag, the front-end + must respond with zero when operation is successfully completed, + or non-zero otherwise. + + Mapping over an already existing map is not allowed and requests shall f= ail. + Therefore, the memory range in the request must correspond with a valid, + free region of the VIRTIO Shared Memory Region. Also, note that mappings + consume resources and that the request can fail when there are no resour= ces + available. Lastly, mappings are automatically unmapped by the front-end + across device reset operation. + +``VHOST_USER_BACKEND_SHMEM_UNMAP`` + :id: 10 + :equivalent ioctl: N/A + :request payload: ``struct VhostUserMMap`` + :reply payload: N/A + + When the ``VHOST_USER_PROTOCOL_F_SHMEM`` protocol feature has been + successfully negotiated, this message can be submitted by the backends so + that the front-end un-mmaps a given range (``shm_offset``, ``len``) in t= he + VIRTIO Shared Memory Region with the requested ``shmid``. Note that the + given range shall correspond to the entirety of a valid mapped region. + If ``VHOST_USER_PROTOCOL_F_REPLY_ACK`` is negotiated, and the back-end + sets the ``VHOST_USER_NEED_REPLY`` flag, the front-end must respond with + zero when operation is successfully completed, or non-zero otherwise. + .. _reply_ack: =20 VHOST_USER_PROTOCOL_F_REPLY_ACK --=20 2.52.0 From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643192; cv=none; d=zohomail.com; s=zohoarc; b=Pv/sVj0NIbK/9G+al/EwFXnrXGmBHN06LT0bfEnD8rUGWI9d1CdgJ8m9pRpzIXMCuxm8XMrH2eEBq0Mjtm314qYHloKDTqtjOdQ8YWOOz1n+ELrVCDxMuVmWODRv1ZIyyGRM6j4piKYs2CEN7NEtKWzGGHAeANguYbjTZ/j/A0s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643192; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=rfV0gEUJC+rSPvPi445xgxocRWiYcV/AAmpU7HARrQc=; b=erMMoAs4Ret0oev7Hc9RP9l3vg0twrWGWTggGa+wkQ1txZiWgzRyTdPco07zPal6qVX+RhVMWBWINCf28IVBC3hM2axFYvWpycVuAO2mPqF5226jJHWotxwJkE2WhhTsHTMu4J76K2hkLDhImoDhD6GbptK7TAsABuj4m0cAV+M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643192887150.61590220340156; Wed, 4 Mar 2026 08:53:12 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpTB-00021N-33; Wed, 04 Mar 2026 11:53:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpT8-0001wz-UV for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpT7-0002fo-EV for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:06 -0500 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-28-DGSIqf_hMvWVGhD-nYTXIw-1; Wed, 04 Mar 2026 11:53:01 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B32DC195605B; Wed, 4 Mar 2026 16:52:59 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 10DBD180035F; Wed, 4 Mar 2026 16:52:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643184; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rfV0gEUJC+rSPvPi445xgxocRWiYcV/AAmpU7HARrQc=; b=L4S52V4DCQ+Y+qcBQ+nyWFnzeDWKFJ0kEHoWqn+Bl81HLaOE9EhWvGV1WkghyleAk4AmSL sAQhk8iGsC83CkI1jchnjS+bfWdTMT4GELKcnWTnNxaDc4agiqFsxHO/z/J5VfxfXEf1SG dhobK7i+0SevKK9plX0PGusicNNQ3Qk= X-MC-Unique: DGSIqf_hMvWVGhD-nYTXIw-1 X-Mimecast-MFC-AGG-ID: DGSIqf_hMvWVGhD-nYTXIw_1772643180 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 4/7] vhost_user: Add frontend get_shmem_config command Date: Wed, 4 Mar 2026 17:52:20 +0100 Message-ID: <20260304165223.2166175-5-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 33 X-Spam_score: 3.3 X-Spam_bar: +++ X-Spam_report: (3.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643195088154100 Content-Type: text/plain; charset="utf-8" The frontend can use this command to retrieve VirtIO Shared Memory Regions configuration from the backend. The response contains the number of shared memory regions, their size, and shmid. This is useful when the frontend is unaware of specific backend type and configuration, for example, in the `vhost-user-device` case. Reviewed-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Signed-off-by: Albert Esteve --- include/hw/virtio/vhost-backend.h | 10 ++++++++++ include/hw/virtio/vhost-user.h | 1 + include/hw/virtio/virtio.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-ba= ckend.h index ff94fa1734..ce58b4d2d6 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -163,6 +163,15 @@ typedef int (*vhost_set_device_state_fd_op)(struct vho= st_dev *dev, int *reply_fd, Error **errp); typedef int (*vhost_check_device_state_op)(struct vhost_dev *dev, Error **= errp); +/* + * Max regions is VIRTIO_MAX_SHMEM_REGIONS, so that is the maximum + * number of memory_sizes that will be accepted. + */ +typedef int (*vhost_get_shmem_config_op)(struct vhost_dev *dev, + int *nregions, + uint64_t *memory_sizes, + Error **errp); + =20 typedef struct VhostOps { VhostBackendType backend_type; @@ -220,6 +229,7 @@ typedef struct VhostOps { vhost_supports_device_state_op vhost_supports_device_state; vhost_set_device_state_fd_op vhost_set_device_state_fd; vhost_check_device_state_op vhost_check_device_state; + vhost_get_shmem_config_op vhost_get_shmem_config; } VhostOps; =20 int vhost_backend_update_device_iotlb(struct vhost_dev *dev, diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h index 53fe996686..0d8c7f1006 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -33,6 +33,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_SHARED_OBJECT =3D 18, VHOST_USER_PROTOCOL_F_DEVICE_STATE =3D 19, VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT =3D 20, + VHOST_USER_PROTOCOL_F_SHMEM =3D 21, VHOST_USER_PROTOCOL_F_MAX }; =20 diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 2dcf58639d..3d1b1b5e6d 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -82,6 +82,8 @@ typedef struct VirtQueueElement =20 #define VIRTIO_NO_VECTOR 0xffff =20 +#define VIRTIO_MAX_SHMEM_REGIONS 256 + /* special index value used internally for config irqs */ #define VIRTIO_CONFIG_IRQ_IDX -1 =20 --=20 2.52.0 From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643219; cv=none; d=zohomail.com; s=zohoarc; b=SIIfwvR/mimGNpH14SfJkByArh9ZSaNyyqnijzb4enUA+2xk+WdiN9LsU4jbRcWve+uwibEa4LZXRlchrYYw+ifc/PCNGciYLIo1tYSZECjGYPTUEYvDSXUYiMD85ELckX5OxeNRhuB60rr+wr2hLFCWjWi4uxVPOg2RPbCPBXc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643219; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=POIGA0TdhwgOcV5gif+U97gr41z8jC9z2Bscrr2zLow=; b=Hdq3ZSOBPUhFfcXBXsTlo8moOxNAD8bGMKJh4pZ2Gsj7xBEYoeC5R0pW0LleyCTw8HxZ7SmkgQzItzyyReTIXit/zAiJt7mNlyp2qa1pL71h8Cz5rlFDt+WUJKs+F5a8AYA73GUtcG5znsNFju3UntK8aI1d6tWn2rluad0Dx7o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643219826724.4668984436537; Wed, 4 Mar 2026 08:53:39 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpTJ-0002Jh-6F; Wed, 04 Mar 2026 11:53:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpTG-0002CO-94 for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:14 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpTE-0002gN-Sj for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:14 -0500 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-619-hXcbmq_mPi6iGmU8Uff1ZQ-1; Wed, 04 Mar 2026 11:53:07 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D5F031956059; Wed, 4 Mar 2026 16:53:05 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4D8B918005AE; Wed, 4 Mar 2026 16:52:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643190; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=POIGA0TdhwgOcV5gif+U97gr41z8jC9z2Bscrr2zLow=; b=euamUJaGZPIlQ+wE0KAYVsjS3l5J+TKskg0znR9t455ugcv9qwb8O07JC9UrWly1FFtZkj P6lCgByMH2uEUmaImrrND81JUYT3KCl8dqDDZrFKFXahewVmye9b4SfhpUJj8QEqXLTVJO xQ5Yel8/SXxgEFbTx+4PJu5JEaaKAQw= X-MC-Unique: hXcbmq_mPi6iGmU8Uff1ZQ-1 X-Mimecast-MFC-AGG-ID: hXcbmq_mPi6iGmU8Uff1ZQ_1772643186 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 5/7] vhost_user.rst: Add GET_SHMEM_CONFIG message Date: Wed, 4 Mar 2026 17:52:21 +0100 Message-ID: <20260304165223.2166175-6-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 33 X-Spam_score: 3.3 X-Spam_bar: +++ X-Spam_report: (3.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643221071154100 Content-Type: text/plain; charset="utf-8" Add GET_SHMEM_CONFIG vhost-user frontend message to the spec documentation. Reviewed-by: Stefano Garzarella Reviewed-by: Alyssa Ross Reviewed-by: Stefan Hajnoczi Signed-off-by: Albert Esteve --- docs/interop/vhost-user.rst | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 08a5e43988..4ee663d10b 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -371,6 +371,22 @@ MMAP request - 0: Pages are mapped read-only - 1: Pages are mapped read-write =20 +VIRTIO Shared Memory Region configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++-------------+---------+------------+----+--------------+ +| num regions | padding | mem size 0 | .. | mem size 255 | ++-------------+---------+------------+----+--------------+ + +:num regions: a 32-bit number of regions + +:padding: 32-bit + +:mem size: an array of 256 64-bit fields representing the size of each + VIRTIO Shared Memory Region. ``num regions`` specifies the + number of valid regions (non-zero size). The array index + corresponds to the shared memory ID (shmid). + C structure ----------- =20 @@ -397,6 +413,7 @@ In QEMU the vhost-user message is implemented with the = following struct: VhostUserShared object; VhostUserTransferDeviceState transfer_state; VhostUserMMap mmap; + VhostUserShMemConfig shmem; }; } QEMU_PACKED VhostUserMsg; =20 @@ -1777,6 +1794,28 @@ Front-end message types Using this function requires prior negotiation of the ``VHOST_USER_PROTOCOL_F_DEVICE_STATE`` feature. =20 +``VHOST_USER_GET_SHMEM_CONFIG`` + :id: 44 + :equivalent ioctl: N/A + :request payload: N/A + :reply payload: ``struct VhostUserShMemConfig`` + + When the ``VHOST_USER_PROTOCOL_F_SHMEM`` protocol feature has been + successfully negotiated, this message can be submitted by the front-end + to gather the VIRTIO Shared Memory Region configuration. The back-end wi= ll + respond with the number of VIRTIO Shared Memory Regions it requires, and + each shared memory region size in an array. The shared memory IDs are + represented by the array index. The information returned shall comply + with the following rules: + + * The shared information will remain valid and unchanged for the entire + lifetime of the connection. + + * The Shared Memory Region size must be a multiple of the page size + supported by mmap(2). + + * The size may be 0 if the region is unused. + Back-end message types ---------------------- =20 --=20 2.52.0 From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643213; cv=none; d=zohomail.com; s=zohoarc; b=QcdWAWLoTf3SOHA1i8DGCGTtZhxssJSuN1E6l0AQkZ3WRQXOowZO8yA2VCyT37ILwUcRdnwkAwv6qdJY99WSrtCTltkG+yBn16Jq2ZlYofkmX6GBnxjs/zdQZeBv3ltK4FKL7qnZ5u6g3dNvRMdWhogiSSXN97Qp8TB0oJTO/dA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643213; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=OJXjw/MZLO0jdXTJ3OCRwcBA0iCCwHaUHbmHZnw9RyQ=; b=VWOe0wCiyRY6QIG0xfNml1T0sqUUcC+SKio/XMQMam+uZXfxqG1AutoyxvVZyKntcniWv4Nd9EHieLBIysSwJWdENp045a8ptMix03qXGwI8Jg2YIEFpITKKckFNloGOhCX3ClXNsDytp/v08MCJnX+ydZXoVlbBGi1Xnqoo3a8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643213012981.2426346459836; Wed, 4 Mar 2026 08:53:33 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpTN-0002TK-Ka; Wed, 04 Mar 2026 11:53:21 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpTL-0002OZ-0E for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:19 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpTJ-0002hB-LT for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:18 -0500 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-591-QCBRsJgdPOqBg6qHOJj1Hw-1; Wed, 04 Mar 2026 11:53:13 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5263B18002CD; Wed, 4 Mar 2026 16:53:12 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5C95B180035F; Wed, 4 Mar 2026 16:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643197; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OJXjw/MZLO0jdXTJ3OCRwcBA0iCCwHaUHbmHZnw9RyQ=; b=JMzDrsUhadF3PE7l6kFoqrwyV9z76xSJXbigNgHKCps4nTnq36Wl22WgW4t72dh0GXf09O 40eX6c3PSMFBMGS+UreuYPaNoZVaEmT6ELrR8pqslKzOV6H0F89E9vXWnDlIDGFMAH4aRF wkd9CuYcRA0HznQUGoFNPv8c5j5NyzU= X-MC-Unique: QCBRsJgdPOqBg6qHOJj1Hw-1 X-Mimecast-MFC-AGG-ID: QCBRsJgdPOqBg6qHOJj1Hw_1772643192 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 6/7] qmp: add shmem feature map Date: Wed, 4 Mar 2026 17:52:22 +0100 Message-ID: <20260304165223.2166175-7-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 0 X-Spam_score: -0.0 X-Spam_bar: / X-Spam_report: (-0.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643214899154100 Content-Type: text/plain; charset="utf-8" Add new vhost-user protocol VHOST_USER_PROTOCOL_F_SHMEM feature to feature map. Reviewed-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Signed-off-by: Albert Esteve --- hw/virtio/virtio-qmp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c index 968299fda0..e3d0a10a59 100644 --- a/hw/virtio/virtio-qmp.c +++ b/hw/virtio/virtio-qmp.c @@ -127,6 +127,9 @@ static const qmp_virtio_feature_map_t vhost_user_protoc= ol_map[] =3D { FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_DEVICE_STATE, \ "VHOST_USER_PROTOCOL_F_DEVICE_STATE: Backend device state tran= sfer " "supported"), + FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SHMEM, \ + "VHOST_USER_PROTOCOL_F_SHMEM: Backend shared memory mappin= g " + "supported"), { -1, "" } }; =20 --=20 2.52.0 From nobody Thu Apr 2 14:13:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772643218; cv=none; d=zohomail.com; s=zohoarc; b=Yw+xe0hUzjhgqycww2afrvQYQr3/h06C943+0RJazFKSU6ycdSjJBvq2T2QQAOZk4XM8s5UlKX0TxOTsR6LRBmtlcOVS4/uXYryUpu7idjSlLVdo7Vl7K0ini3ySQxKfHmx6sp/wc/N94ytofA0XE+aUy9nHSIofBIXUVJKXgss= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772643218; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/2K0d0yMI2FB9ttaLek/P9Lpa6KPNcXaq5k+29l39xE=; b=muDBG2xzf38R1ljYUiXpsDcMtw5tLyuHOkA9esti7QHtu00K1I/WEIc5CRoh1aBD5XmWIqzIXNVn/jLFaiEuujxVHDGlfiIh6mDY4Vn7sBo4WMhtdxdqByncgbj0M/kyKUFXMmTi/fgvSakSXhtEzSv8ESM+IiemlcM+rgDCjp8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772643218063594.720889992501; Wed, 4 Mar 2026 08:53:38 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vxpTZ-0003Ex-Ae; Wed, 04 Mar 2026 11:53:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpTS-00032s-SY for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:27 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vxpTR-0002kg-7d for qemu-devel@nongnu.org; Wed, 04 Mar 2026 11:53:26 -0500 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-453-_DGIH1RvP7uFLp9MmyfThg-1; Wed, 04 Mar 2026 11:53:20 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B0AA51956053; Wed, 4 Mar 2026 16:53:18 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.26]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D8D2F18005AE; Wed, 4 Mar 2026 16:53:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772643204; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/2K0d0yMI2FB9ttaLek/P9Lpa6KPNcXaq5k+29l39xE=; b=EuAY10shiCo1G2skKhOVPBqn29kXPIZ9EXQ5onCCqVfBRH80rFgEblDcWyb81rdnM240aB 7k/6IibCWuk3gs46EzDTx6FM98qnfkRQcKlzubPOX2D9lp7IZZPyDbokbutsJqmRMUrctO 2mr90Ed5VqI6C97ngT+WUbCoaLMVALU= X-MC-Unique: _DGIH1RvP7uFLp9MmyfThg-1 X-Mimecast-MFC-AGG-ID: _DGIH1RvP7uFLp9MmyfThg_1772643198 From: Albert Esteve To: qemu-devel@nongnu.org Cc: mst@redhat.com, Stefano Garzarella , manos.pitsidianakis@linaro.org, slp@redhat.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , stefanha@redhat.com, stevensd@chromium.org, Laurent Vivier , jasowang@redhat.com, Peter Xu , hi@alyssa.is, Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Fabiano Rosas , dbassey@redhat.com, Paolo Bonzini Subject: [PATCH v14 7/7] vhost-user-device: Add shared memory BAR Date: Wed, 4 Mar 2026 17:52:23 +0100 Message-ID: <20260304165223.2166175-8-aesteve@redhat.com> In-Reply-To: <20260304165223.2166175-1-aesteve@redhat.com> References: <20260304165223.2166175-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=aesteve@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 33 X-Spam_score: 3.3 X-Spam_bar: +++ X-Spam_report: (3.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.703, RCVD_IN_VALIDITY_SAFE_BLOCKED=1.386, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772643221132154100 Content-Type: text/plain; charset="utf-8" Add shared memory BAR support to vhost-user-device-pci to enable direct file mapping for VIRTIO Shared Memory Regions. The implementation creates a consolidated shared memory BAR that contains all VIRTIO Shared Memory Regions as subregions. Each region is configured with its proper shmid, size, and offset within the BAR. The number and size of regions are retrieved via VHOST_USER_GET_SHMEM_CONFIG message sent by vhost-user-base during realization after virtio_init(). Specifically, it uses BAR 4 to avoid conflicts, as it is currently unused. The shared memory BAR is only created when the backend supports VHOST_USER_PROTOCOL_F_SHMEM and has configured shared memory regions. This maintains backward compatibility with backends that do not support shared memory functionality. Reviewed-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Signed-off-by: Albert Esteve --- hw/virtio/vhost-user-base.c | 46 ++++++++++++++++++++++++-- hw/virtio/vhost-user-test-device-pci.c | 42 +++++++++++++++++++++-- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c index 01ab9ca56b..de42ea46e5 100644 --- a/hw/virtio/vhost-user-base.c +++ b/hw/virtio/vhost-user-base.c @@ -16,6 +16,7 @@ #include "hw/virtio/virtio-bus.h" #include "hw/virtio/vhost-user-base.h" #include "qemu/error-report.h" +#include "migration/blocker.h" =20 static void vub_start(VirtIODevice *vdev) { @@ -276,7 +277,8 @@ static void vub_device_realize(DeviceState *dev, Error = **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); VHostUserBase *vub =3D VHOST_USER_BASE(dev); - int ret; + uint64_t memory_sizes[VIRTIO_MAX_SHMEM_REGIONS]; + int i, ret, nregions, regions_processed =3D 0; =20 if (!vub->chardev.chr) { error_setg(errp, "vhost-user-base: missing chardev"); @@ -319,7 +321,7 @@ static void vub_device_realize(DeviceState *dev, Error = **errp) =20 /* Allocate queues */ vub->vqs =3D g_ptr_array_sized_new(vub->num_vqs); - for (int i =3D 0; i < vub->num_vqs; i++) { + for (i =3D 0; i < vub->num_vqs; i++) { g_ptr_array_add(vub->vqs, virtio_add_queue(vdev, vub->vq_size, vub_handle_output)); @@ -333,11 +335,49 @@ static void vub_device_realize(DeviceState *dev, Erro= r **errp) VHOST_BACKEND_TYPE_USER, 0, errp); =20 if (ret < 0) { - do_vhost_user_cleanup(vdev, vub); + goto err; + } + + ret =3D vub->vhost_dev.vhost_ops->vhost_get_shmem_config(&vub->vhost_d= ev, + &nregions, + memory_sizes, + errp); + + if (ret < 0) { + goto err; + } + + for (i =3D 0; i < VIRTIO_MAX_SHMEM_REGIONS && regions_processed < nreg= ions; i++) { + if (memory_sizes[i]) { + regions_processed++; + if (vub->vhost_dev.migration_blocker =3D=3D NULL) { + error_setg(&vub->vhost_dev.migration_blocker, + "Migration disabled: devices with VIRTIO Shared Mem= ory " + "Regions do not support migration yet."); + ret =3D migrate_add_blocker_normal( + &vub->vhost_dev.migration_blocker, + errp); + + if (ret < 0) { + goto err; + } + } + + if (memory_sizes[i] % qemu_real_host_page_size() !=3D 0) { + error_setg(errp, "Shared memory %d size must be a multiple= of " + "the host page size", i); + goto err; + } + + virtio_new_shmem_region(vdev, i, memory_sizes[i]); + } } =20 qemu_chr_fe_set_handlers(&vub->chardev, NULL, NULL, vub_event, NULL, dev, NULL, true); + return; +err: + do_vhost_user_cleanup(vdev, vub); } =20 static void vub_device_unrealize(DeviceState *dev) diff --git a/hw/virtio/vhost-user-test-device-pci.c b/hw/virtio/vhost-user-= test-device-pci.c index 7f6d751690..2106557ed8 100644 --- a/hw/virtio/vhost-user-test-device-pci.c +++ b/hw/virtio/vhost-user-test-device-pci.c @@ -12,10 +12,13 @@ #include "hw/virtio/vhost-user-base.h" #include "hw/virtio/virtio-pci.h" =20 +#define VIRTIO_DEVICE_PCI_SHMEM_BAR 4 + struct VHostUserDevicePCI { VirtIOPCIProxy parent_obj; =20 VHostUserBase vub; + MemoryRegion shmembar; }; =20 #define TYPE_VHOST_USER_TEST_DEVICE_PCI "vhost-user-test-device-pci-base" @@ -25,10 +28,45 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserDevicePCI, VHOST_US= ER_TEST_DEVICE_PCI) static void vhost_user_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error = **errp) { VHostUserDevicePCI *dev =3D VHOST_USER_TEST_DEVICE_PCI(vpci_dev); - DeviceState *vdev =3D DEVICE(&dev->vub); + DeviceState *dev_state =3D DEVICE(&dev->vub); + VirtIODevice *vdev =3D VIRTIO_DEVICE(dev_state); + VirtioSharedMemory *shmem; + uint64_t offset =3D 0, shmem_size =3D 0; =20 + /* Keep modern 64-bit BARs (2 slots) away from the shared memory BAR. = */ + vpci_dev->modern_mem_bar_idx =3D 2; vpci_dev->nvectors =3D 1; - qdev_realize(vdev, BUS(&vpci_dev->bus), errp); + if (!qdev_realize(dev_state, BUS(&vpci_dev->bus), errp)) { + return; + } + + QSIMPLEQ_FOREACH(shmem, &vdev->shmem_list, entry) { + if (memory_region_size(&shmem->mr) > UINT64_MAX - shmem_size) { + error_setg(errp, "Total shared memory required overflow"); + return; + } + shmem_size =3D shmem_size + memory_region_size(&shmem->mr); + } + if (shmem_size) { + if (vpci_dev->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY) { + error_setg(errp, "modern-pio-notify is not supported due to PC= I BAR layout limitations"); + return; + } + memory_region_init(&dev->shmembar, OBJECT(vpci_dev), + "vhost-device-pci-shmembar", shmem_size); + QSIMPLEQ_FOREACH(shmem, &vdev->shmem_list, entry) { + memory_region_add_subregion(&dev->shmembar, offset, &shmem->mr= ); + virtio_pci_add_shm_cap(vpci_dev, VIRTIO_DEVICE_PCI_SHMEM_BAR, + offset, memory_region_size(&shmem->mr), + shmem->shmid); + offset =3D offset + memory_region_size(&shmem->mr); + } + pci_register_bar(&vpci_dev->pci_dev, VIRTIO_DEVICE_PCI_SHMEM_BAR, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &dev->shmembar); + } } =20 static void vhost_user_device_pci_class_init(ObjectClass *klass, --=20 2.52.0