From nobody Sat Nov 15 05:30:42 2025 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=1755160799; cv=none; d=zohomail.com; s=zohoarc; b=RJx/Z+F3Jlv/aFYX4q6V9R30iefP+zUl60oeRqQ9TwdaSQ/1xjzxfg5vkH+8wZB/RbkyxtqOXSUOWCsZszmdtjwl+PTypZ5v61nECMw7HyHjYUM93qJufBKlSlQ9zgLGuV1UqbHipkf9RAwR/+3fmLBp+3kma40hx2n6OMln5TM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160799; 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=trklvPSAEOGArGb9zhpOZiaAnvdUV/AusLF82IqInQQ=; b=aagxTojS/S6X52SyuOfX/XTke/d6DTMdsl82Qv7xsffyxvPnpoiysDzpLgLyDOX8YnrZp4bC5C6W0nufHiTTFvDa13wrdKO8A0QbRuFgiHAx2U3bbRnylqlxzEG7DCdqd0MAK05d7fjYtzYCate1EDrZz7pTQ29Vsya0VH+01GE= 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 1755160799398453.4124358737098; Thu, 14 Aug 2025 01:39:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTTg-0007JP-Jl; Thu, 14 Aug 2025 04:38:28 -0400 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 1umTTd-0007JC-S3 for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:25 -0400 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 1umTTZ-00060o-BE for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:25 -0400 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-187-_z1M_DHGOLKaXgfAcEm_UA-1; Thu, 14 Aug 2025 04:38:15 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 2CC011800340; Thu, 14 Aug 2025 08:38:14 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 13946180044F; Thu, 14 Aug 2025 08:38:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160699; 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=trklvPSAEOGArGb9zhpOZiaAnvdUV/AusLF82IqInQQ=; b=EPVKrkY+XEuqDU7ZOX0Jih4gav6W6mu5Lj9Usua3GNPrVONdUdY85gH9qtgHyX4XQMyd/s UsY9MZQZqRRtq7i77VwQ1Qjdj3PlRHI8JVS4CdAbvC5PP2zUffIPO2Q+ePeiUg3zMA/ipc RQwFlPcBVSpEeLJ3QcFlpCZqAk49yxo= X-MC-Unique: _z1M_DHGOLKaXgfAcEm_UA-1 X-Mimecast-MFC-AGG-ID: _z1M_DHGOLKaXgfAcEm_UA_1755160694 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 1/8] vhost-user: Add VirtIO Shared Memory map request Date: Thu, 14 Aug 2025 10:37:42 +0200 Message-ID: <20250814083749.1317197-2-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160801235124100 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 VhostUserShmemObject as an intermediate QOM parent for MemoryRegions created for SHMEM_MAP requests. This object provides reference-counted lifecycle management with automatic cleanup. This request allows backends to dynamically map file descriptors into a VIRTIO Shared Memory Regions identified by their shmid. Maps are created using mmap() 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 associated VhostUserShmemObject, 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 respond to the backend to avoid deadlocks. Signed-off-by: Albert Esteve --- hw/virtio/meson.build | 1 + hw/virtio/vhost-user-shmem.c | 166 +++++++++++++++++ hw/virtio/vhost-user.c | 207 +++++++++++++++++++++- hw/virtio/virtio.c | 111 ++++++++++++ include/hw/virtio/vhost-user-shmem.h | 106 +++++++++++ include/hw/virtio/virtio.h | 93 ++++++++++ subprojects/libvhost-user/libvhost-user.c | 70 ++++++++ subprojects/libvhost-user/libvhost-user.h | 54 ++++++ 8 files changed, 806 insertions(+), 2 deletions(-) create mode 100644 hw/virtio/vhost-user-shmem.c create mode 100644 include/hw/virtio/vhost-user-shmem.h diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build index 3ea7b3cec8..5efcf70b75 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build @@ -20,6 +20,7 @@ if have_vhost # fixme - this really should be generic specific_virtio_ss.add(files('vhost-user.c')) system_virtio_ss.add(files('vhost-user-base.c')) + system_virtio_ss.add(files('vhost-user-shmem.c')) =20 # MMIO Stubs system_virtio_ss.add(files('vhost-user-device.c')) diff --git a/hw/virtio/vhost-user-shmem.c b/hw/virtio/vhost-user-shmem.c new file mode 100644 index 0000000000..ef231f5077 --- /dev/null +++ b/hw/virtio/vhost-user-shmem.c @@ -0,0 +1,166 @@ +/* + * VHost-user Shared Memory Object + * + * Copyright Red Hat, Inc. 2024 + * + * Authors: + * Albert Esteve + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/vhost-user-shmem.h" +#include "system/memory.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "trace.h" +#include + +/** + * VhostUserShmemObject + * + * An intermediate QOM object that manages individual shared memory mappin= gs + * created by VHOST_USER_BACKEND_SHMEM_MAP requests. It acts as a parent f= or + * MemoryRegion objects, providing proper lifecycle management with refere= nce + * counting. When the object is unreferenced and its reference count drops + * to zero, it automatically cleans up the MemoryRegion and unmaps the mem= ory. + */ + +static void vhost_user_shmem_object_finalize(Object *obj); +static void vhost_user_shmem_object_instance_init(Object *obj); + +static const TypeInfo vhost_user_shmem_object_info =3D { + .name =3D TYPE_VHOST_USER_SHMEM_OBJECT, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(VhostUserShmemObject), + .instance_init =3D vhost_user_shmem_object_instance_init, + .instance_finalize =3D vhost_user_shmem_object_finalize, +}; + +static void vhost_user_shmem_object_instance_init(Object *obj) +{ + VhostUserShmemObject *shmem_obj =3D VHOST_USER_SHMEM_OBJECT(obj); + + shmem_obj->shmid =3D 0; + shmem_obj->fd =3D -1; + shmem_obj->fd_offset =3D 0; + shmem_obj->shm_offset =3D 0; + shmem_obj->len =3D 0; + shmem_obj->flags =3D 0; + shmem_obj->mapped_addr =3D NULL; + shmem_obj->mr =3D NULL; +} + +static void vhost_user_shmem_object_finalize(Object *obj) +{ + VhostUserShmemObject *shmem_obj =3D VHOST_USER_SHMEM_OBJECT(obj); + + /* Clean up MemoryRegion if it exists */ + if (shmem_obj->mr) { + /* Unparent the MemoryRegion to trigger cleanup */ + object_unparent(OBJECT(shmem_obj->mr)); + shmem_obj->mr =3D NULL; + } + + /* Clean up memory mapping */ + if (shmem_obj->mapped_addr && shmem_obj->mapped_addr !=3D MAP_FAILED) { + if (munmap(shmem_obj->mapped_addr, shmem_obj->len) < 0) { + warn_report("vhost-user-shmem: failed to unmap memory region"); + } + shmem_obj->mapped_addr =3D NULL; + } + + /* Close file descriptor */ + if (shmem_obj->fd >=3D 0) { + close(shmem_obj->fd); + shmem_obj->fd =3D -1; + } +} + +VhostUserShmemObject *vhost_user_shmem_object_new(uint8_t shmid, + int fd, + uint64_t fd_offset, + uint64_t shm_offset, + uint64_t len, + uint16_t flags) +{ + VhostUserShmemObject *shmem_obj; + void *mapped_addr; + MemoryRegion *mr; + g_autoptr(GString) mr_name =3D g_string_new(NULL); + int prot_flags; + + if (fd < 0) { + error_report("Invalid file descriptor: %d", fd); + return NULL; + } + + if (len =3D=3D 0) { + error_report("Shared memory mapping size cannot be zero"); + return NULL; + } + + /* Determine memory protection flags */ + prot_flags =3D PROT_READ; + if (flags & VHOST_USER_FLAG_MAP_RW) { + prot_flags |=3D PROT_WRITE; + } + + /* Map the shared memory region */ + mapped_addr =3D mmap(NULL, len, prot_flags, MAP_SHARED, fd, fd_offset); + if (mapped_addr =3D=3D MAP_FAILED) { + error_report("Failed to map shared memory region: %s", strerror(er= rno)); + return NULL; + } + + /* Create the VhostUserShmemObject */ + shmem_obj =3D VHOST_USER_SHMEM_OBJECT( + object_new(TYPE_VHOST_USER_SHMEM_OBJECT)); + + /* Set up object properties */ + shmem_obj->shmid =3D shmid; + shmem_obj->fd =3D fd; + shmem_obj->fd_offset =3D fd_offset; + shmem_obj->shm_offset =3D shm_offset; + shmem_obj->len =3D len; + shmem_obj->flags =3D flags; + shmem_obj->mapped_addr =3D mapped_addr; + + /* Create MemoryRegion as a child of this object */ + mr =3D g_new0(MemoryRegion, 1); + g_string_printf(mr_name, "vhost-user-shmem-%d-%" PRIx64, shmid, shm_of= fset); + + /* Initialize MemoryRegion with the mapped memory */ + memory_region_init_ram_device_ptr(mr, OBJECT(shmem_obj), mr_name->str, + len, mapped_addr); + + shmem_obj->mr =3D mr; + return shmem_obj; +} + +MemoryRegion *vhost_user_shmem_object_get_mr(VhostUserShmemObject *shmem_o= bj) +{ + g_assert(shmem_obj); + return shmem_obj->mr; +} + +int vhost_user_shmem_object_get_fd(VhostUserShmemObject *shmem_obj) +{ + g_assert(shmem_obj); + return shmem_obj->fd; +} + +void *vhost_user_shmem_object_get_mapped_addr(VhostUserShmemObject *shmem_= obj) +{ + g_assert(shmem_obj); + return shmem_obj->mapped_addr; +} + +static void vhost_user_shmem_register_types(void) +{ + type_register_static(&vhost_user_shmem_object_info); +} + +type_init(vhost_user_shmem_register_types) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 1e1d6b0d6e..eb3ad728b0 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -11,6 +11,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "hw/virtio/virtio-dmabuf.h" +#include "hw/virtio/vhost-user-shmem.h" #include "hw/virtio/vhost.h" #include "hw/virtio/virtio-crypto.h" #include "hw/virtio/vhost-user.h" @@ -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 @@ -192,6 +195,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_* */ + uint16_t flags; +} VhostUserMMap; + typedef struct { VhostUserRequest request; =20 @@ -224,6 +244,7 @@ typedef union { VhostUserInflight inflight; VhostUserShared object; VhostUserTransferDeviceState transfer_state; + VhostUserMMap mmap; } VhostUserPayload; =20 typedef struct VhostUserMsg { @@ -1768,6 +1789,172 @@ 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; + Error *local_err =3D NULL; + g_autoptr(GString) shm_name =3D g_string_new(NULL); + + if (fd < 0) { + error_report("Bad fd for map"); + return -EBADF; + } + + if (QSIMPLEQ_EMPTY(&dev->vdev->shmem_list)) { + error_report("Device has no VIRTIO Shared Memory Regions. " + "Requested ID: %d", vu_mmap->shmid); + return -EFAULT; + } + + 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 unitialized", vu_mmap->shmid); + return -EFAULT; + } + + if ((vu_mmap->shm_offset + vu_mmap->len) < vu_mmap->len || + (vu_mmap->shm_offset + vu_mmap->len) > shmem->mr.size) { + error_report("Bad offset/len for mmap %" PRIx64 "+%" PRIx64, + vu_mmap->shm_offset, vu_mmap->len); + return -EFAULT; + } + + g_string_printf(shm_name, "virtio-shm%i-%lu", + vu_mmap->shmid, vu_mmap->shm_offset); + + memory_region_transaction_begin(); + + /* Create VhostUserShmemObject as intermediate parent for MemoryRegion= */ + VhostUserShmemObject *shmem_obj =3D vhost_user_shmem_object_new( + vu_mmap->shmid, fd, vu_mmap->fd_offset, vu_mmap->shm_offset, + vu_mmap->len, vu_mmap->flags); + + if (!shmem_obj) { + memory_region_transaction_commit(); + return -EFAULT; + } + + /* Add the mapping using our VhostUserShmemObject as the parent */ + if (virtio_add_shmem_map(shmem, shmem_obj) !=3D 0) { + error_report("Failed to add shared memory mapping"); + object_unref(OBJECT(shmem_obj)); + memory_region_transaction_commit(); + return -EFAULT; + } + + if (hdr->flags & VHOST_USER_NEED_REPLY_MASK) { + payload->u64 =3D 0; + hdr->size =3D sizeof(payload->u64); + vhost_user_send_resp(ioc, hdr, payload, &local_err); + if (local_err) { + error_report_err(local_err); + memory_region_transaction_commit(); + return -EFAULT; + } + } + + memory_region_transaction_commit(); + + 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; + VirtioSharedMemoryMapping *mmap =3D NULL; + VhostUserMMap *vu_mmap =3D &payload->mmap; + Error *local_err =3D NULL; + + if (QSIMPLEQ_EMPTY(&dev->vdev->shmem_list)) { + error_report("Device has no VIRTIO Shared Memory Regions. " + "Requested ID: %d", vu_mmap->shmid); + return -EFAULT; + } + + 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 unitialized", vu_mmap->shmid); + return -EFAULT; + } + + if ((vu_mmap->shm_offset + vu_mmap->len) < vu_mmap->len || + (vu_mmap->shm_offset + vu_mmap->len) > shmem->mr.size) { + error_report("Bad offset/len for unmmap %" PRIx64 "+%" PRIx64, + vu_mmap->shm_offset, vu_mmap->len); + return -EFAULT; + } + + 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); + return -EFAULT; + } + + memory_region_transaction_begin(); + memory_region_del_subregion(&shmem->mr, mmap->mem); + if (hdr->flags & VHOST_USER_NEED_REPLY_MASK) { + payload->u64 =3D 0; + hdr->size =3D sizeof(payload->u64); + vhost_user_send_resp(ioc, hdr, payload, &local_err); + if (local_err) { + error_report_err(local_err); + memory_region_transaction_commit(); + return -EFAULT; + } + } + memory_region_transaction_commit(); + + /* Free the MemoryRegion only after vhost_commit */ + 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); @@ -1833,8 +2020,24 @@ static gboolean backend_read(QIOChannel *ioc, GIOCon= dition condition, &payload.obje= ct); break; case VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP: - ret =3D vhost_user_backend_handle_shared_object_lookup(dev->opaque= , ioc, - &hdr, &payloa= d); + /* Handler manages its own response, check error and close connect= ion */ + if (vhost_user_backend_handle_shared_object_lookup(dev->opaque, io= c, + &hdr, &payload)= < 0) { + goto err; + } + break; + case VHOST_USER_BACKEND_SHMEM_MAP: + /* Handler manages its own response, check error and close connect= ion */ + 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 */ + 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); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 9a81ad912e..28cefda255 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-commands-virtio.h" +#include "hw/virtio/vhost-user-shmem.h" #include "trace.h" #include "qemu/defer-call.h" #include "qemu/error-report.h" @@ -3045,6 +3046,102 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f) return vmstate_save_state(f, &vmstate_virtio, vdev, NULL); } =20 +VirtioSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev, uint8_t sh= mid) +{ + 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, UINT64_MAX); + QTAILQ_INIT(&elem->mmaps); + QSIMPLEQ_INSERT_TAIL(&vdev->shmem_list, elem, entry); + return QSIMPLEQ_LAST(&vdev->shmem_list, VirtioSharedMemory, entry); +} + +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; +} + +int virtio_add_shmem_map(VirtioSharedMemory *shmem, + VhostUserShmemObject *shmem_obj) +{ + VirtioSharedMemoryMapping *mmap; + MemoryRegion *mr; + if (!shmem_obj) { + error_report("VhostUserShmemObject cannot be NULL"); + return -1; + } + mr =3D vhost_user_shmem_object_get_mr(shmem_obj); + if (!mr) { + error_report("VhostUserShmemObject has no MemoryRegion"); + return -1; + } + + /* Validate boundaries against the VIRTIO shared memory region */ + if (shmem_obj->shm_offset + shmem_obj->len > shmem->mr.size) { + error_report("Memory exceeds the shared memory boundaries"); + return -1; + } + + /* Create the VirtioSharedMemoryMapping wrapper */ + mmap =3D g_new0(VirtioSharedMemoryMapping, 1); + mmap->mem =3D mr; + mmap->offset =3D shmem_obj->shm_offset; + mmap->shmem_obj =3D shmem_obj; + + /* Take a reference on the VhostUserShmemObject */ + object_ref(OBJECT(shmem_obj)); + + /* Add as subregion to the VIRTIO shared memory */ + memory_region_add_subregion(&shmem->mr, mmap->offset, mmap->mem); + + /* Add to the mapped regions list */ + QTAILQ_INSERT_TAIL(&shmem->mmaps, mmap, link); + + return 0; +} + +VirtioSharedMemoryMapping *virtio_find_shmem_map(VirtioSharedMemory *shmem, + hwaddr offset, uint64_t size) +{ + VirtioSharedMemoryMapping *mmap; + QTAILQ_FOREACH(mmap, &shmem->mmaps, link) { + if (mmap->offset =3D=3D offset && mmap->mem->size =3D=3D size) { + return mmap; + } + } + return NULL; +} + +void virtio_del_shmem_map(VirtioSharedMemory *shmem, hwaddr offset, + uint64_t size) +{ + VirtioSharedMemoryMapping *mmap =3D virtio_find_shmem_map(shmem, offse= t, size); + if (mmap =3D=3D NULL) { + return; + } + + /* + * Unref the VhostUserShmemObject which will trigger automatic cleanup + * when the reference count reaches zero. + */ + object_unref(OBJECT(mmap->shmem_obj)); + + QTAILQ_REMOVE(&shmem->mmaps, mmap, link); + g_free(mmap); +} + /* 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) @@ -3521,6 +3618,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 /* @@ -4032,11 +4130,24 @@ 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 *mmap_reg =3D QTAILQ_FIRST(&shmem->m= maps); + virtio_del_shmem_map(shmem, mmap_reg->offset, mmap_reg->mem->s= ize); + } + + /* 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 { diff --git a/include/hw/virtio/vhost-user-shmem.h b/include/hw/virtio/vhost= -user-shmem.h new file mode 100644 index 0000000000..ffbbea9c54 --- /dev/null +++ b/include/hw/virtio/vhost-user-shmem.h @@ -0,0 +1,106 @@ +/* + * VHost-user Shared Memory Object + * + * Copyright Red Hat, Inc. 2024 + * + * Authors: + * Albert Esteve + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef VHOST_USER_SHMEM_H +#define VHOST_USER_SHMEM_H + +#include "qemu/osdep.h" +#include "qom/object.h" +#include "system/memory.h" +#include "qapi/error.h" + +/* vhost-user memory mapping flags */ +#define VHOST_USER_FLAG_MAP_RW (1u << 0) + +#define TYPE_VHOST_USER_SHMEM_OBJECT "vhost-user-shmem" +OBJECT_DECLARE_SIMPLE_TYPE(VhostUserShmemObject, VHOST_USER_SHMEM_OBJECT) + +/** + * VhostUserShmemObject: + * @parent: Parent object + * @shmid: VIRTIO Shared Memory Region ID + * @fd: File descriptor for the shared memory region + * @fd_offset: Offset within the file descriptor + * @shm_offset: Offset within the VIRTIO Shared Memory Region + * @len: Size of the mapping + * @flags: Mapping flags (read/write permissions) + * @mapped_addr: Pointer to the mapped memory region + * @mr: MemoryRegion associated with this shared memory mapping + * + * An intermediate QOM object that manages individual shared memory mappin= gs + * created by VHOST_USER_BACKEND_SHMEM_MAP requests. It acts as a parent f= or + * MemoryRegion objects, providing proper lifecycle management with refere= nce + * counting. When the object is unreferenced and its reference count drops + * to zero, it automatically cleans up the MemoryRegion and unmaps the mem= ory. + */ +struct VhostUserShmemObject { + Object parent; + + uint8_t shmid; + int fd; + uint64_t fd_offset; + uint64_t shm_offset; + uint64_t len; + uint16_t flags; + void *mapped_addr; + MemoryRegion *mr; +}; + +/** + * vhost_user_shmem_object_new() - Create a new VhostUserShmemObject + * @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 + * @flags: Mapping flags (VHOST_USER_FLAG_MAP_*) + * + * Creates a new VhostUserShmemObject that manages a shared memory mapping. + * The object will automatically map the memory using mmap() and create + * a MemoryRegion as a child object. When the object is finalized, it will + * automatically unmap the memory and close the file descriptor. + * Errors are reported via error_report(). + * + * Return: A new VhostUserShmemObject on success, NULL on error. + */ +VhostUserShmemObject *vhost_user_shmem_object_new(uint8_t shmid, + int fd, + uint64_t fd_offset, + uint64_t shm_offset, + uint64_t len, + uint16_t flags); + +/** + * vhost_user_shmem_object_get_mr() - Get the MemoryRegion + * @shmem_obj: VhostUserShmemObject instance + * + * Return: The MemoryRegion associated with this shared memory object. + */ +MemoryRegion *vhost_user_shmem_object_get_mr(VhostUserShmemObject *shmem_o= bj); + +/** + * vhost_user_shmem_object_get_fd() - Get the file descriptor + * @shmem_obj: VhostUserShmemObject instance + * + * Return: The file descriptor for the shared memory region. + */ +int vhost_user_shmem_object_get_fd(VhostUserShmemObject *shmem_obj); + +/** + * vhost_user_shmem_object_get_mapped_addr() - Get the mapped memory addre= ss + * @shmem_obj: VhostUserShmemObject instance + * + * Return: The mapped memory address. + */ +void *vhost_user_shmem_object_get_mapped_addr(VhostUserShmemObject *shmem_= obj); + +#endif /* VHOST_USER_SHMEM_H */ diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index c594764f23..a563bbac2c 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -98,6 +98,26 @@ enum virtio_device_endian { VIRTIO_DEVICE_ENDIAN_BIG, }; =20 +struct VhostUserShmemObject; + +struct VirtioSharedMemoryMapping { + MemoryRegion *mem; + hwaddr offset; + QTAILQ_ENTRY(VirtioSharedMemoryMapping) link; + struct VhostUserShmemObject *shmem_obj; /* Intermediate parent object = */ +}; + +typedef struct VirtioSharedMemoryMapping VirtioSharedMemoryMapping; + +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 @@ -167,6 +187,8 @@ struct VirtIODevice */ EventNotifier config_notifier; bool device_iotlb_enabled; + /* Shared memory region for mappings. */ + QSIMPLEQ_HEAD(, VirtioSharedMemory) shmem_list; }; =20 struct VirtioDeviceClass { @@ -295,6 +317,77 @@ 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 + * + * 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); + +/** + * 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_add_shmem_map() - Add a memory mapping to a shared region + * @shmem: VirtioSharedMemory region + * @shmem_obj: VhostUserShmemObject to add (takes a reference) + * + * Adds a memory mapping to the shared memory region. The VhostUserShmemOb= ject + * is added as a child of the mapping and will be automatically managed th= rough + * QOM reference counting. The mapping will be removed 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, + struct VhostUserShmemObject *shmem_obj); + +/** + * 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/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..26b710c92d 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_* */ + uint16_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 --=20 2.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160757; cv=none; d=zohomail.com; s=zohoarc; b=jo7I5b0SrNW45kobrCEeZN7zr4gWqV3swiBmG3jfE3NC0eD8bU70wvRZOR6lKUfIq6xHw5lEmxtxNTQBRzFmob0pgFR049t01IXTpNlptuuWnF1c3CN2x7oOvQ2mKA/B849qx4Xn5un+HTcXGtYT2WHjDtjPZcYkwsn7GOUIthU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160757; 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=2JRarTR2AYg3ChsZq/h++rQDJXjy/c1zeADcSA56lqE=; b=iuy1xOTTJK5yZIdz1w+7erY0Y7kQoqwZdG6crykNBmcZwnXIiTdeMSdkxblvMfjE7OdpUQrMNJldTGpeBii8GYvR3XN2X8IzLKXuiRAYhqEFhGEnOJaUszL9thyIMl/ejFeoaCJs7SdY1Dec4XCwhhFqnVYrsooDqoIIe07GnWA= 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 1755160757775755.9740883226376; Thu, 14 Aug 2025 01:39:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTTk-0007KE-Rk; Thu, 14 Aug 2025 04:38:34 -0400 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 1umTTi-0007Jo-1c for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:30 -0400 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 1umTTf-00061b-Po for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:29 -0400 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-511-EZ2h4Rf1P0ey0nxts75zLw-1; Thu, 14 Aug 2025 04:38:22 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 25FBB188280F; Thu, 14 Aug 2025 08:38:21 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id ECAC718003FC; Thu, 14 Aug 2025 08:38:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160706; 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=2JRarTR2AYg3ChsZq/h++rQDJXjy/c1zeADcSA56lqE=; b=aKl/qEv9rDupw3U/WS0NEf7gXLKyyV/srhFrk6/zDg2uIn3KCuMPjxhWKqnq4HFgiYu5rt 4L1L1x1e0Q5fI7HnjR1wJLmNB2WutPtFhT8dDDyFZMUf9fp0tKV1pq7PKdzrgXlN68m40w gwsmaR57Mf5zTn6smuioqUeJ8lYnIys= X-MC-Unique: EZ2h4Rf1P0ey0nxts75zLw-1 X-Mimecast-MFC-AGG-ID: EZ2h4Rf1P0ey0nxts75zLw_1755160701 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 2/8] vhost_user.rst: Align VhostUserMsg excerpt members Date: Thu, 14 Aug 2025 10:37:43 +0200 Message-ID: <20250814083749.1317197-3-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160760807124100 Content-Type: text/plain; charset="utf-8" Add missing members to the VhostUserMsg excerpt in the vhost-user spec documentation. 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 2e50f2ddfa..436a94c0ee 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.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160778; cv=none; d=zohomail.com; s=zohoarc; b=fiSKysw2KVpZGwQ6NsaBT2FvbPEkmkbOTAMjtGD/MIpfr7ViZOIKlWnPCevmDCBoY4vTd0VRRJUcpXdvUEhHBx6AVhOFcoQUmUhjR1EeYvu580dq3zSV4PvTTXD88/UJOEsvTntXvG0qZpIv6blQV1rRT8jH2weW7XB1SfVCdKc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160778; 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=56lEYxdS9u2mMEy3cKp25B8ggHhbMd+3/bl921MPr9g=; b=QzRKodWRDOljiaM1fGxYBexcjl0UdMVnx7EaBehMpBm1QLrb8nvAznX0b/eEqpv743RTByd4p3f8TjT5SIpo0Lh1Fvbbt/2jrTjOxYsw71B2WsUXFDfbG3ueAB4zH7JUTALnTLVmXad61RU1SITvichvsoNE0ZF007jLlbnivUc= 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 1755160778815977.7324844754223; Thu, 14 Aug 2025 01:39:38 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTTq-0007Ks-Aw; Thu, 14 Aug 2025 04:38:39 -0400 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 1umTTp-0007Kd-1a for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:37 -0400 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 1umTTl-00063i-1C for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:35 -0400 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-206-PLzfnzgBNcqt_B3sMdPJvw-1; Thu, 14 Aug 2025 04:38:28 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 6F5FD1800286; Thu, 14 Aug 2025 08:38:27 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AF79E180044F; Thu, 14 Aug 2025 08:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160712; 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=56lEYxdS9u2mMEy3cKp25B8ggHhbMd+3/bl921MPr9g=; b=CslSS99OnY3tSqConzCugW2Uhw5HXK0ROSKpnW2/88WlzFvYLEeN5UIxNJG0g9fOgSJZSC 8R+4iktFRi4xSkoXVRUJBkdHeOuOivVfVFvUVsZVZudtsX6aAwRrdC3Yp2adcX2TTPVFtA MEBv/lnm2HFJ6e5M4Pxe2hlw0ROtH+8= X-MC-Unique: PLzfnzgBNcqt_B3sMdPJvw-1 X-Mimecast-MFC-AGG-ID: PLzfnzgBNcqt_B3sMdPJvw_1755160707 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 3/8] vhost_user.rst: Add SHMEM_MAP/_UNMAP to spec Date: Thu, 14 Aug 2025 10:37:44 +0200 Message-ID: <20250814083749.1317197-4-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160780554124100 Content-Type: text/plain; charset="utf-8" Add SHMEM_MAP/_UNMAP request to the vhost-user spec documentation. Reviewed-by: Stefan Hajnoczi Signed-off-by: Albert Esteve --- docs/interop/vhost-user.rst | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 436a94c0ee..dab9f3af42 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 @@ -1057,6 +1079,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_XEN_MMAP 17 #define VHOST_USER_PROTOCOL_F_SHARED_OBJECT 18 #define VHOST_USER_PROTOCOL_F_DEVICE_STATE 19 + #define VHOST_USER_PROTOCOL_F_SHMEM 20 =20 Front-end message types ----------------------- @@ -1865,6 +1888,41 @@ 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. + +``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. + A reply is generated indicating whether unmapping succeeded. + .. _reply_ack: =20 VHOST_USER_PROTOCOL_F_REPLY_ACK --=20 2.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160811; cv=none; d=zohomail.com; s=zohoarc; b=h0dI1xUqjUwhUGzlrEOCLsmJBg6tjXg9w9mPZbrYvStJsIv8Q+6E7fqHRjYNWyNqkJcm1M2Iof/RJG3k0g6Yb245WtiaA1Jy2cp1/OLRRd0yJPLtxCYoYAFQv8enmnaTBc7UdgNMOXwPQ9al1qKA/JnxL4IpIMTwvIJOA0mpOZc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160811; 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=P9I8pN3Ic6kx4QGFOkHjvVo+AEU5MXFerKiYPdyNHE0=; b=aFBtLhHIRkUaSeohSu5erTkokc3+4XRfngb/zNjMlHoabi6JjS27bpeVMqpevQtORVlxqWSwc51UtkE4dodWZiYZh8ci378HJfIH8qjwOF79txKWw5czxU4Tnobd24ykYHSPX9X0OwHHG1bwVvwuudF75+rH8KqT9gp+h5YVESk= 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 1755160811029625.7870799850725; Thu, 14 Aug 2025 01:40:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTTv-0007Lm-QC; Thu, 14 Aug 2025 04:38:43 -0400 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 1umTTs-0007LE-4n for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:40 -0400 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 1umTTq-00065a-1B for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:39 -0400 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-281-rzllMo6aOOaF2aura_mTfg-1; Thu, 14 Aug 2025 04:38:34 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 9007B1800366; Thu, 14 Aug 2025 08:38:33 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2F32D18004D4; Thu, 14 Aug 2025 08:38:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160716; 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=P9I8pN3Ic6kx4QGFOkHjvVo+AEU5MXFerKiYPdyNHE0=; b=D1Q99AAgPbGWViA9Tjlw0M3pQapMOM5hlrgJR9PzCBpthvaHtHCz36ZdU17V70rZhCkeRj 9iSpPp52AqVLHT6N50aOVzUp84pJtWPJPzr8RnUtx43Fh/K+vUmudX2JeWmdzZPjfONtAT e0ouxlPF4n0k1cvSJ1AYOS/q3r+SMxY= X-MC-Unique: rzllMo6aOOaF2aura_mTfg-1 X-Mimecast-MFC-AGG-ID: rzllMo6aOOaF2aura_mTfg_1755160713 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 4/8] vhost_user: Add frontend get_shmem_config command Date: Thu, 14 Aug 2025 10:37:45 +0200 Message-ID: <20250814083749.1317197-5-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160811645116600 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: Stefan Hajnoczi Signed-off-by: Albert Esteve --- hw/virtio/vhost-user.c | 43 +++++++++++++++++++++++++++++++ include/hw/virtio/vhost-backend.h | 10 +++++++ include/hw/virtio/vhost-user.h | 1 + include/hw/virtio/virtio.h | 2 ++ 4 files changed, 56 insertions(+) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index eb3ad728b0..d1bf162497 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -105,6 +105,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 @@ -139,6 +140,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; @@ -245,6 +252,7 @@ typedef union { VhostUserShared object; VhostUserTransferDeviceState transfer_state; VhostUserMMap mmap; + VhostUserShMemConfig shmem; } VhostUserPayload; =20 typedef struct VhostUserMsg { @@ -3213,6 +3221,40 @@ 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)) { + 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; + } + + assert(msg.payload.shmem.nregions <=3D VIRTIO_MAX_SHMEM_REGIONS); + *nregions =3D msg.payload.shmem.nregions; + memcpy(memory_sizes, + &msg.payload.shmem.memory_sizes, + sizeof(uint64_t) * msg.payload.shmem.nregions); + return 0; +} + const VhostOps user_ops =3D { .backend_type =3D VHOST_BACKEND_TYPE_USER, .vhost_backend_init =3D vhost_user_backend_init, @@ -3251,4 +3293,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/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-ba= ckend.h index d6df209a2f..42400b276e 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -159,6 +159,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; @@ -214,6 +223,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 9a3f238b43..bacc7d184c 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -32,6 +32,7 @@ enum VhostUserProtocolFeature { /* Feature 17 reserved for VHOST_USER_PROTOCOL_F_XEN_MMAP. */ VHOST_USER_PROTOCOL_F_SHARED_OBJECT =3D 18, VHOST_USER_PROTOCOL_F_DEVICE_STATE =3D 19, + VHOST_USER_PROTOCOL_F_SHMEM =3D 20, VHOST_USER_PROTOCOL_F_MAX }; =20 diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index a563bbac2c..2109186d7d 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -81,6 +81,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.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160801; cv=none; d=zohomail.com; s=zohoarc; b=aCa4mJEhifQtaXDpfnVIOz3Fv077Oja5ObK/yq/XUo5I3Vv/jHbWjOWFw8I9CzqJxAmEyWQc0Vtl0elY14K5wmG3Uqu1JQJudm31C/EFDZ1faeFlZHeOd338CJA5EyKjk4Xhyojc/N85vTUAaHxFrozM31s27oSG8/lfyvaSA7o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160801; 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=4hVX23j1qg89GM2XTJ2f9M0XbvXysR1u9GM3HK6Mb+g=; b=e0q+tP3LSJHACHan7BRntGuJA48GpYUKfrlwZVYH4bAVsMpDdpQ+D3dtI4EL5GyQPeL0iHpJe0MnwZ3hNK2b4JUpAWGqGpBJ7Nhuu15+qkUTBqa/tPdO7JMLuKAIc1+iwoMAoqBofWlxZme5GYEgO0BARlKdb016bG0k2SYW3ns= 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 1755160801386268.48445772302193; Thu, 14 Aug 2025 01:40:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTU3-0007N2-6C; Thu, 14 Aug 2025 04:38:51 -0400 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 1umTU0-0007MX-EB for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:49 -0400 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 1umTTy-00068m-8j for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:47 -0400 Received: from mx-prod-mc-04.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-608-PbSvs82kMruTOxxJGv_jUA-1; Thu, 14 Aug 2025 04:38:42 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BAB701954B13; Thu, 14 Aug 2025 08:38:40 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3987818003FC; Thu, 14 Aug 2025 08:38:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160725; 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=4hVX23j1qg89GM2XTJ2f9M0XbvXysR1u9GM3HK6Mb+g=; b=iOo7PDFns0desVfxxq0bM0GcWXoOPjd6yNRp80jy9sqQ9U45U2nNzspY26qtXUPV/2aNOk HYq8anEflEZtiziy5WHeU86UcaEqFRL4b6/W0rNMjoEfMSrVG6JQKPsLPfV6UuflMN7IiG T0BO640UOAaYMBkVCmIlG74kb8qvQrc= X-MC-Unique: PbSvs82kMruTOxxJGv_jUA-1 X-Mimecast-MFC-AGG-ID: PbSvs82kMruTOxxJGv_jUA_1755160721 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 5/8] vhost_user.rst: Add GET_SHMEM_CONFIG message Date: Thu, 14 Aug 2025 10:37:46 +0200 Message-ID: <20250814083749.1317197-6-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160803446116600 Content-Type: text/plain; charset="utf-8" Add GET_SHMEM_CONFIG vhost-user frontend message to the spec documentation. 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 dab9f3af42..54d64ae75f 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -371,6 +371,20 @@ 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: contains ``num regions`` 64-bit fields representing the size of= each + VIRTIO Shared Memory Region + C structure ----------- =20 @@ -397,6 +411,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 @@ -1754,6 +1769,30 @@ 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. This can happen when the + device does not support an optional feature but does support a feature + that uses a higher shmid. + Back-end message types ---------------------- =20 --=20 2.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160776; cv=none; d=zohomail.com; s=zohoarc; b=RYAnxynmKeymz3k/Ct3Lnrly37HD762qGfMWREmWVtdZUHsHezhdV/i/v9EN8T+eUPJBfAuRN4UTO60Jiscg/XNCQR7WWRFOkc5Q4O/lgeHsODdyEzQG7Ds+yfaP7qPruiXnvsL5YA3Ctp45zn66tmjjqMELiK90IHshepXMyE0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160776; 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=VcgyWEw0UZlhydwF41sGf+kzWAR2qTmet/4n/K4pS3U=; b=fKNmdG/N/0YBN2E5pgoZtFempx9MnvU5f4MjeFm76jZsXt55CFdLM2OXPg3tgA1l3jLmhNmfSJ1WZ5sCbOt4/7ybSG50l+yB2izDp2qtLFtGQs77uz8zsd4N5Qewwii/09rMcngFutg34zo8s2G7JNTtSbxo+mZyNjPJBlM7H3c= 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 1755160776145491.72791295904244; Thu, 14 Aug 2025 01:39:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTUC-0007Nd-Ml; Thu, 14 Aug 2025 04:39:00 -0400 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 1umTUA-0007NL-W3 for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:59 -0400 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 1umTU4-0006A1-Iq for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:58 -0400 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-677-qGFyVk6vNeiZTPdrje3gHg-1; Thu, 14 Aug 2025 04:38:48 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 E152C1800371; Thu, 14 Aug 2025 08:38:46 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5522318003FC; Thu, 14 Aug 2025 08:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160731; 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=VcgyWEw0UZlhydwF41sGf+kzWAR2qTmet/4n/K4pS3U=; b=PFrMnTeNROJ13Fajls/q2ohmE2tUSIvtzoiBYGq8kjRW1Wn9welj/JFZWLeIUR9by7go0v kloeWmNfpJeVIjI7c2NUDtfsWFDUu7eD1L1TqeWYnWAhvBujPsNCtx+Bd88YVLsJlgtl+a WsU5A5PVfKtuM0xdBCtIDTbGzfYILsQ= X-MC-Unique: qGFyVk6vNeiZTPdrje3gHg-1 X-Mimecast-MFC-AGG-ID: qGFyVk6vNeiZTPdrje3gHg_1755160727 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 6/8] tests/qtest: Add GET_SHMEM validation test Date: Thu, 14 Aug 2025 10:37:47 +0200 Message-ID: <20250814083749.1317197-7-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, T_SPF_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160777229116600 Content-Type: text/plain; charset="utf-8" Improve vhost-user-test to properly validate VHOST_USER_GET_SHMEM_CONFIG message handling by directly simulating the message exchange. The test manually triggers the VHOST_USER_GET_SHMEM_CONFIG message by calling chr_read() with a crafted VhostUserMsg, allowing direct validation of the shmem configuration response handler. Added TestServerShmem structure to track shmem configuration state, including nregions_sent and sizes_sent arrays for comprehensive validation. The test verifies that the response contains the expected number of shared memory regions and their corresponding sizes. Signed-off-by: Albert Esteve --- tests/qtest/vhost-user-test.c | 91 +++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c index 75cb3e44b2..44a5e90b2e 100644 --- a/tests/qtest/vhost-user-test.c +++ b/tests/qtest/vhost-user-test.c @@ -88,6 +88,7 @@ typedef enum VhostUserRequest { VHOST_USER_SET_VRING_ENABLE =3D 18, VHOST_USER_GET_CONFIG =3D 24, VHOST_USER_SET_CONFIG =3D 25, + VHOST_USER_GET_SHMEM_CONFIG =3D 44, VHOST_USER_MAX } VhostUserRequest; =20 @@ -109,6 +110,20 @@ typedef struct VhostUserLog { uint64_t mmap_offset; } VhostUserLog; =20 +#define VIRTIO_MAX_SHMEM_REGIONS 256 + +typedef struct VhostUserShMemConfig { + uint32_t nregions; + uint32_t padding; + uint64_t memory_sizes[VIRTIO_MAX_SHMEM_REGIONS]; +} VhostUserShMemConfig; + +typedef struct TestServerShmem { + bool test_enabled; + uint32_t nregions_sent; + uint64_t sizes_sent[VIRTIO_MAX_SHMEM_REGIONS]; +} TestServerShmem; + typedef struct VhostUserMsg { VhostUserRequest request; =20 @@ -124,6 +139,7 @@ typedef struct VhostUserMsg { struct vhost_vring_addr addr; VhostUserMemory memory; VhostUserLog log; + VhostUserShMemConfig shmem; } payload; } QEMU_PACKED VhostUserMsg; =20 @@ -170,6 +186,7 @@ typedef struct TestServer { bool test_fail; int test_flags; int queues; + TestServerShmem shmem; struct vhost_user_ops *vu_ops; } TestServer; =20 @@ -513,6 +530,31 @@ static void chr_read(void *opaque, const uint8_t *buf,= int size) qos_printf("set_vring(%d)=3D%s\n", msg.payload.state.index, msg.payload.state.num ? "enabled" : "disabled"); break; + =20 + case VHOST_USER_GET_SHMEM_CONFIG: + if (!s->shmem.test_enabled) { + /* Reply with error if shmem feature not enabled */ + msg.flags |=3D VHOST_USER_REPLY_MASK; + msg.size =3D sizeof(uint64_t); + msg.payload.u64 =3D -1; /* Error */ + qemu_chr_fe_write_all(chr, (uint8_t *) &msg, VHOST_USER_HDR_SI= ZE + msg.size); + } else { + /* Reply with test shmem configuration */ + msg.flags |=3D VHOST_USER_REPLY_MASK; + msg.size =3D sizeof(VhostUserShMemConfig); + msg.payload.shmem.nregions =3D 2; /* Test with 2 regions */ + msg.payload.shmem.padding =3D 0; + msg.payload.shmem.memory_sizes[0] =3D 0x100000; /* 1MB */ + msg.payload.shmem.memory_sizes[1] =3D 0x200000; /* 2MB */ + =20 + /* Record what we're sending for test validation */ + s->shmem.nregions_sent =3D msg.payload.shmem.nregions; + s->shmem.sizes_sent[0] =3D msg.payload.shmem.memory_sizes[0]; + s->shmem.sizes_sent[1] =3D msg.payload.shmem.memory_sizes[1]; + =20 + qemu_chr_fe_write_all(chr, (uint8_t *) &msg, VHOST_USER_HDR_SI= ZE + msg.size); + } + break; =20 default: qos_printf("vhost-user: un-handled message: %d\n", msg.request); @@ -809,6 +851,22 @@ static void *vhost_user_test_setup_shm(GString *cmd_li= ne, void *arg) return server; } =20 +static void *vhost_user_test_setup_shmem_config(GString *cmd_line, void *a= rg) +{ + TestServer *server =3D test_server_new("vhost-user-test", arg); + test_server_listen(server); + + /* Enable shmem testing for this server */ + server->shmem.test_enabled =3D true; + + append_mem_opts(server, cmd_line, 256, TEST_MEMFD_SHM); + server->vu_ops->append_opts(server, cmd_line, ""); + + g_test_queue_destroy(vhost_user_test_cleanup, server); + + return server; +} + static void test_read_guest_mem(void *obj, void *arg, QGuestAllocator *all= oc) { TestServer *server =3D arg; @@ -1089,6 +1147,33 @@ static struct vhost_user_ops g_vu_net_ops =3D { .get_protocol_features =3D vu_net_get_protocol_features, }; =20 +/* Test function for VHOST_USER_GET_SHMEM_CONFIG message */ +static void test_shmem_config(void *obj, void *arg, QGuestAllocator *alloc) +{ + TestServer *s =3D arg; + =20 + g_assert_true(s->shmem.test_enabled); + =20 + g_mutex_lock(&s->data_mutex); + s->shmem.nregions_sent =3D 0; + s->shmem.sizes_sent[0] =3D 0; + s->shmem.sizes_sent[1] =3D 0; + g_mutex_unlock(&s->data_mutex); + =20 + VhostUserMsg msg =3D { + .request =3D VHOST_USER_GET_SHMEM_CONFIG, + .flags =3D VHOST_USER_VERSION, + .size =3D 0, + }; + chr_read(s, (uint8_t *) &msg, VHOST_USER_HDR_SIZE); + + g_mutex_lock(&s->data_mutex); + g_assert_cmpint(s->shmem.nregions_sent, =3D=3D, 2); + g_assert_cmpint(s->shmem.sizes_sent[0], =3D=3D, 0x100000); /* 1MB */ + g_assert_cmpint(s->shmem.sizes_sent[1], =3D=3D, 0x200000); /* 2MB */ + g_mutex_unlock(&s->data_mutex); +} + static void register_vhost_user_test(void) { QOSGraphTestOptions opts =3D { @@ -1136,6 +1221,12 @@ static void register_vhost_user_test(void) qos_add_test("vhost-user/multiqueue", "virtio-net", test_multiqueue, &opts); + =20 + opts.before =3D vhost_user_test_setup_shmem_config; + opts.edge.extra_device_opts =3D ""; + qos_add_test("vhost-user/shmem-config", + "virtio-net", + test_shmem_config, &opts); } libqos_init(register_vhost_user_test); =20 --=20 2.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160803; cv=none; d=zohomail.com; s=zohoarc; b=m3V7LDfpbw1v7iiUSGSyhtgx3Ni6m+nTvT8sC2O4tlkaZrE5tGNUVgqfULcArZUm4pyKCssWa/+YsQ3XEHdlfUr6MN3Xa6EYEIm957fhT+ztb9Fcqr7V+IIptXZitNZ1f5DZOSuneiIc+kbTkXUOL089/SiGVDqcOkjCB5cqPfw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160803; 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=FXG6nBRyssLRsnDK38URuLwEwpEb4ieR4NV7wjgJN8Q=; b=gJQq0FylJ2qwx0DLWQBp2OuXvQTjsWHYVVQfmAb5LSRSZnMvXyzlXtU40R5DVPPM1xX8auE/08n03LHWC6ZKl4OFi752mcC+6OWP+u7PnmLjMHwFHyRR1RHV7F1XhJf/DrJUYRhU55yPD2TDArpq6TSeg2GjBVDnhy8IXZ+2ndY= 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 175516080348967.89752801227428; Thu, 14 Aug 2025 01:40:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTUD-0007Ng-FE; Thu, 14 Aug 2025 04:39:01 -0400 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 1umTUB-0007NR-Kj for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:59 -0400 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 1umTU8-0006Bf-MX for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:38:59 -0400 Received: from mx-prod-mc-04.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-680-fKUfvU3XN7GFiBOuVWv6RA-1; Thu, 14 Aug 2025 04:38:54 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 040731955D69; Thu, 14 Aug 2025 08:38:53 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B4CA3180044F; Thu, 14 Aug 2025 08:38:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160735; 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=FXG6nBRyssLRsnDK38URuLwEwpEb4ieR4NV7wjgJN8Q=; b=WJR21Hv0vV/JVYgvq4uYqkGoKZZSs20ciS9EVIZzDeXU3QC4RWa0otEy2MfHFVRJN36zxi dhJR4z6qtZj/gC8R6kpONR60coNJVs+utyddslxLINxwxzno4THJ5rlPgze4kgZ8a116ej du/V0B4Xrph05Bx+caDqCrZn6HSwiqg= X-MC-Unique: fKUfvU3XN7GFiBOuVWv6RA-1 X-Mimecast-MFC-AGG-ID: fKUfvU3XN7GFiBOuVWv6RA_1755160733 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 7/8] qmp: add shmem feature map Date: Thu, 14 Aug 2025 10:37:48 +0200 Message-ID: <20250814083749.1317197-8-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160805420116600 Content-Type: text/plain; charset="utf-8" Add new vhost-user protocol VHOST_USER_PROTOCOL_F_SHMEM feature to feature map. 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 3b6377cf0d..8c2cfd0916 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.49.0 From nobody Sat Nov 15 05:30:42 2025 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=1755160836; cv=none; d=zohomail.com; s=zohoarc; b=W+Hoai4rpJh/NqyKrSBq28ekX8do0HT1/qLTJTQbRlk/YvGWEW4q3OmBssXg6p6vSvwMgkF+TxMAZDFDgda6lL3OW3rWOsYkCxb27yBMS+qMfSsHYAYphKoldFlHt9gkLmScVwel9n8H3M5W+CkeFCURU04YuyQg8rIdaOxxWDw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1755160836; 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=ydA5+q4d6HWwx0EkrM5TjW/EQBVY8+I+lJ5UM8QCE3g=; b=Y7NWJ3vavK8AeSaQYBtEOmjvVsTTpJhphcaW0aZB2+87vxzX1kqugZhAsykE04LAtAwg+qQ6ME3/81ZP5P6F2rNTOBGiDQwdhUF1ZULBzvz5XU+S1x9DIplYLHBVVrLfJt96b8bX67q8eoNe/xMvqTHce/i03JDjFauJVqR7XSM= 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 1755160836953964.6213776107616; Thu, 14 Aug 2025 01:40:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umTUL-0007P3-8u; Thu, 14 Aug 2025 04:39:09 -0400 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 1umTUI-0007OX-MQ for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:39:06 -0400 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 1umTUG-0006DN-C9 for qemu-devel@nongnu.org; Thu, 14 Aug 2025 04:39:06 -0400 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-134-RqRiSJ29N8uGbE7hE8Fy0A-1; Thu, 14 Aug 2025 04:39:00 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 D21FD1800366; Thu, 14 Aug 2025 08:38:59 +0000 (UTC) Received: from localhost.localdomain (unknown [10.45.225.203]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8F70718003FC; Thu, 14 Aug 2025 08:38:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755160743; 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=ydA5+q4d6HWwx0EkrM5TjW/EQBVY8+I+lJ5UM8QCE3g=; b=DMtPTyQOi4GvIJ7PybG0HLcJJowFNB3k6LnOkApw+gtmsNjr0K6ULRpWU8NarQ5+dq+dWn sQmGfokFqmdhcmLsP171v3I2v2pN4LqqmSc0TN9STvHhPkKLqxm6SIdoqVW8vSC6ytdcPJ 5n2gejcRQL1OD4tk1dVsJUY9go36ZnU= X-MC-Unique: RqRiSJ29N8uGbE7hE8Fy0A-1 X-Mimecast-MFC-AGG-ID: RqRiSJ29N8uGbE7hE8Fy0A_1755160739 From: Albert Esteve To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Fabiano Rosas , hi@alyssa.is, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Laurent Vivier , slp@redhat.com, Stefano Garzarella , Paolo Bonzini , david@redhat.com, jasowang@redhat.com, stefanha@redhat.com, dbassey@redhat.com, stevensd@chromium.org, Albert Esteve Subject: [PATCH v6 8/8] vhost-user-device: Add shared memory BAR Date: Thu, 14 Aug 2025 10:37:49 +0200 Message-ID: <20250814083749.1317197-9-aesteve@redhat.com> In-Reply-To: <20250814083749.1317197-1-aesteve@redhat.com> References: <20250814083749.1317197-1-aesteve@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: 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: 1755160839102124100 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(). Specifiically, it uses BAR 3 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. Signed-off-by: Albert Esteve --- hw/virtio/vhost-user-base.c | 49 +++++++++++++++++++++++++++++-- hw/virtio/vhost-user-device-pci.c | 34 +++++++++++++++++++-- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c index ff67a020b4..932f9b5596 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,9 @@ 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]; + g_autofree char *name =3D NULL; + int i, ret, nregions; =20 if (!vub->chardev.chr) { error_setg(errp, "vhost-user-base: missing chardev"); @@ -319,7 +322,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 +336,51 @@ 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 < nregions; i++) { + if (memory_sizes[i]) { + 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 power of= 2 " + "no smaller than the page size", i); + goto err; + } + + name =3D g_strdup_printf("vub-shm-%d", i); + memory_region_init(&virtio_new_shmem_region(vdev, i)->mr, + OBJECT(vdev), name, + 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-device-pci.c b/hw/virtio/vhost-user-devic= e-pci.c index f10bac874e..bac99e7c60 100644 --- a/hw/virtio/vhost-user-device-pci.c +++ b/hw/virtio/vhost-user-device-pci.c @@ -8,14 +8,18 @@ */ =20 #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/qdev-properties.h" #include "hw/virtio/vhost-user-base.h" #include "hw/virtio/virtio-pci.h" =20 +#define VIRTIO_DEVICE_PCI_SHMEM_BAR 3 + struct VHostUserDevicePCI { VirtIOPCIProxy parent_obj; =20 VHostUserBase vub; + MemoryRegion shmembar; }; =20 #define TYPE_VHOST_USER_DEVICE_PCI "vhost-user-device-pci-base" @@ -25,10 +29,36 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserDevicePCI, VHOST_US= ER_DEVICE_PCI) static void vhost_user_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error = **errp) { VHostUserDevicePCI *dev =3D VHOST_USER_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, *next; + uint64_t offset =3D 0, shmem_size =3D 0; =20 vpci_dev->nvectors =3D 1; - qdev_realize(vdev, BUS(&vpci_dev->bus), errp); + qdev_realize(dev_state, BUS(&vpci_dev->bus), errp); + + QSIMPLEQ_FOREACH_SAFE(shmem, &vdev->shmem_list, entry, next) { + if (shmem->mr.size > UINT64_MAX - shmem_size) { + error_setg(errp, "Total shared memory required overflow"); + return; + } + shmem_size =3D shmem_size + shmem->mr.size; + } + if (shmem_size) { + memory_region_init(&dev->shmembar, OBJECT(vpci_dev), + "vhost-device-pci-shmembar", shmem_size); + QSIMPLEQ_FOREACH_SAFE(shmem, &vdev->shmem_list, entry, next) { + memory_region_add_subregion(&dev->shmembar, offset, &shmem->mr= ); + virtio_pci_add_shm_cap(vpci_dev, VIRTIO_DEVICE_PCI_SHMEM_BAR, + offset, shmem->mr.size, shmem->shmid); + offset =3D offset + shmem->mr.size; + } + 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.49.0