From patchwork Mon Feb 17 16:40:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978289 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1E934C021AA for ; Mon, 17 Feb 2025 16:43:02 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4C7-0004Wo-A9; Mon, 17 Feb 2025 11:42:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C5-0004WN-Ib for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:05 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C1-0007wp-VI for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810521; 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=uyNhzrr1DeEeNg443omaN6Fe2+QnPDF5gl9hKYrI+WU=; b=Q0oX2D631Swv44oI6jTlQVCwdmlByZxOFzMiYWl/5KZ8Atge/dPeIhdaHhzTUiQFMDfW6R 2DTn8DB/cqC7hK/Jfl5MQkyuQIpzdYs2ONz2PERMXE4L3YWYxJSRFALlEAmsXNpRaA8MR/ d7T+bKnMdRGkVytYKL+5HJ2qoPGq7LM= 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-649-4KyFTZjCOtKbaraZN2ipCw-1; Mon, 17 Feb 2025 11:40:26 -0500 X-MC-Unique: 4KyFTZjCOtKbaraZN2ipCw-1 X-Mimecast-MFC-AGG-ID: 4KyFTZjCOtKbaraZN2ipCw_1739810425 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C826718D95F1; Mon, 17 Feb 2025 16:40:24 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 01F691800874; Mon, 17 Feb 2025 16:40:19 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 1/9] vhost-user: Add VirtIO Shared Memory map request Date: Mon, 17 Feb 2025 17:40:04 +0100 Message-ID: <20250217164012.246727-2-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add SHMEM_MAP/UNMAP requests to vhost-user to handle VIRTIO Shared Memory mappings. This request allows backends to dynamically map fds into a VIRTIO Shared Memory Region indentified by its `shmid`. The map is performed by calling `memory_region_init_ram_from_fd` and adding the new region as a subregion of the shmem container MR. Then, the fd memory is advertised to the driver as a base addres + offset, so it can be read/written (depending on the mmap flags requested) while it is valid. The backend can unmap the memory range in a given VIRTIO Shared Memory Region (again, identified by its `shmid`), to free it. Upon receiving this message, the front-end must delete the MR as a subregion of the shmem container region and free its resources. Note that commit all these operations need to be delayed to after we respond the request to the backend to avoid deadlocks. The device model needs to create VirtSharedMemory instances for the VirtIO Shared Memory Regions and add them to the `VirtIODevice` instance. Signed-off-by: Albert Esteve --- hw/virtio/vhost-user.c | 134 ++++++++++++++++++++++ hw/virtio/virtio.c | 81 +++++++++++++ include/hw/virtio/virtio.h | 27 +++++ subprojects/libvhost-user/libvhost-user.c | 70 +++++++++++ subprojects/libvhost-user/libvhost-user.h | 55 +++++++++ 5 files changed, 367 insertions(+) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 267b612587..d88e6f8c3c 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -115,6 +115,8 @@ typedef enum VhostUserBackendRequest { VHOST_USER_BACKEND_SHARED_OBJECT_ADD = 6, VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE = 7, VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP = 8, + VHOST_USER_BACKEND_SHMEM_MAP = 9, + VHOST_USER_BACKEND_SHMEM_UNMAP = 10, VHOST_USER_BACKEND_MAX } VhostUserBackendRequest; @@ -192,6 +194,24 @@ typedef struct VhostUserShared { unsigned char uuid[16]; } VhostUserShared; +/* For the flags field of VhostUserMMap */ +#define VHOST_USER_FLAG_MAP_R (1u << 0) +#define VHOST_USER_FLAG_MAP_W (1u << 1) + +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_* */ + uint64_t flags; +} VhostUserMMap; + typedef struct { VhostUserRequest request; @@ -224,6 +244,7 @@ typedef union { VhostUserInflight inflight; VhostUserShared object; VhostUserTransferDeviceState transfer_state; + VhostUserMMap mmap; } VhostUserPayload; typedef struct VhostUserMsg { @@ -1770,6 +1791,111 @@ vhost_user_backend_handle_shared_object_lookup(struct vhost_user *u, return 0; } +static int +vhost_user_backend_handle_shmem_map(struct vhost_dev *dev, + QIOChannel *ioc, + VhostUserHeader *hdr, + VhostUserPayload *payload, + int fd, Error **errp) +{ + VirtSharedMemory *shmem = NULL; + VhostUserMMap *vu_mmap = &payload->mmap; + g_autoptr(GString) shm_name = g_string_new(NULL); + + if (fd < 0) { + error_report("Bad fd for map"); + return -EBADF; + } + + if (!dev->vdev->shmem_list || + dev->vdev->n_shmem_regions <= vu_mmap->shmid) { + error_report("Device only has %d VIRTIO Shared Memory Regions. " + "Requested ID: %d", + dev->vdev->n_shmem_regions, vu_mmap->shmid); + return -EFAULT; + } + + shmem = &dev->vdev->shmem_list[vu_mmap->shmid]; + + if (!shmem) { + error_report("VIRTIO Shared Memory Region at " + "ID %d 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(); + virtio_add_shmem_map(shmem, shm_name->str, vu_mmap->shm_offset, + vu_mmap->fd_offset, vu_mmap->len, fd, errp); + + hdr->size = sizeof(payload->u64); + vhost_user_send_resp(ioc, hdr, payload, errp); + memory_region_transaction_commit(); + + return 0; +} + +static int +vhost_user_backend_handle_shmem_unmap(struct vhost_dev *dev, + QIOChannel *ioc, + VhostUserHeader *hdr, + VhostUserPayload *payload, + Error **errp) +{ + VirtSharedMemory *shmem = NULL; + MappedMemoryRegion *mmap = NULL; + VhostUserMMap *vu_mmap = &payload->mmap; + + if (!dev->vdev->shmem_list || + dev->vdev->n_shmem_regions <= vu_mmap->shmid) { + error_report("Device only has %d VIRTIO Shared Memory Regions. " + "Requested ID: %d", + dev->vdev->n_shmem_regions, vu_mmap->shmid); + return -EFAULT; + } + + shmem = &dev->vdev->shmem_list[vu_mmap->shmid]; + + if (!shmem) { + error_report("VIRTIO Shared Memory Region at " + "ID %d 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 = virtio_find_shmem_map(shmem, vu_mmap->shm_offset, vu_mmap->len); + if (!mmap) { + return -EFAULT; + } + + memory_region_transaction_begin(); + memory_region_del_subregion(shmem->mr, mmap->mem); + + hdr->size = sizeof(payload->u64); + vhost_user_send_resp(ioc, hdr, payload, errp); + 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); @@ -1837,6 +1963,14 @@ static gboolean backend_read(QIOChannel *ioc, GIOCondition condition, case VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP: ret = vhost_user_backend_handle_shared_object_lookup(dev->opaque, ioc, &hdr, &payload); + case VHOST_USER_BACKEND_SHMEM_MAP: + ret = vhost_user_backend_handle_shmem_map(dev, ioc, &hdr, &payload, + fd ? fd[0] : -1, &local_err); + break; + case VHOST_USER_BACKEND_SHMEM_UNMAP: + ret = vhost_user_backend_handle_shmem_unmap(dev, ioc, &hdr, &payload, + &local_err); + break; break; default: error_report("Received unexpected msg type: %d.", hdr.request); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 85110bce37..47d0ddb820 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3063,6 +3063,75 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f) return vmstate_save_state(f, &vmstate_virtio, vdev, NULL); } +VirtSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev) +{ + ++vdev->n_shmem_regions; + vdev->shmem_list = g_renew(VirtSharedMemory, vdev->shmem_list, + vdev->n_shmem_regions); + vdev->shmem_list[vdev->n_shmem_regions - 1].mr = g_new0(MemoryRegion, 1); + QTAILQ_INIT(&vdev->shmem_list[vdev->n_shmem_regions - 1].mmaps); + return &vdev->shmem_list[vdev->n_shmem_regions - 1]; +} + +void virtio_add_shmem_map(VirtSharedMemory *shmem, const char *shm_name, + hwaddr shm_offset, hwaddr fd_offset, uint64_t size, + int fd, Error **errp) +{ + MappedMemoryRegion *mmap; + fd = dup(fd); + if (fd < 0) { + error_setg_errno(errp, errno, "Failed to duplicate fd"); + return; + } + + if (shm_offset + size > shmem->mr->size) { + error_setg(errp, "Memory exceeds the shared memory boundaries"); + return; + } + + mmap = g_new0(MappedMemoryRegion, 1); + mmap->mem = g_new0(MemoryRegion, 1); + mmap->offset = shm_offset; + if (!memory_region_init_ram_from_fd(mmap->mem, + OBJECT(shmem->mr), + shm_name, size, RAM_SHARED, + fd, fd_offset, errp)) { + error_setg(errp, "Failed to mmap region %s", shm_name); + close(fd); + g_free(mmap->mem); + g_free(mmap); + return; + } + memory_region_add_subregion(shmem->mr, shm_offset, mmap->mem); + + QTAILQ_INSERT_TAIL(&shmem->mmaps, mmap, link); +} + +MappedMemoryRegion *virtio_find_shmem_map(VirtSharedMemory *shmem, + hwaddr offset, uint64_t size) +{ + MappedMemoryRegion *mmap; + QTAILQ_FOREACH(mmap, &shmem->mmaps, link) { + if (mmap->offset == offset && mmap->mem->size == size) { + return mmap; + } + } + return NULL; +} + +void virtio_del_shmem_map(VirtSharedMemory *shmem, hwaddr offset, + uint64_t size) +{ + MappedMemoryRegion *mmap = virtio_find_shmem_map(shmem, offset, size); + if (mmap == NULL) { + return; + } + + object_unparent(OBJECT(mmap->mem)); + 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 *vmdesc) @@ -3492,6 +3561,8 @@ void virtio_init(VirtIODevice *vdev, uint16_t device_id, size_t config_size) virtio_vmstate_change, vdev); vdev->device_endian = virtio_default_endian(); vdev->use_guest_notifier_mask = true; + vdev->shmem_list = NULL; + vdev->n_shmem_regions = 0; } /* @@ -4005,11 +4076,21 @@ static void virtio_device_free_virtqueues(VirtIODevice *vdev) static void virtio_device_instance_finalize(Object *obj) { VirtIODevice *vdev = VIRTIO_DEVICE(obj); + VirtSharedMemory *shmem = NULL; + int i; virtio_device_free_virtqueues(vdev); g_free(vdev->config); g_free(vdev->vector_queues); + for (i = 0; i< vdev->n_shmem_regions; i++) { + shmem = &vdev->shmem_list[i]; + while (!QTAILQ_EMPTY(&shmem->mmaps)) { + MappedMemoryRegion *mmap_reg = QTAILQ_FIRST(&shmem->mmaps); + QTAILQ_REMOVE(&shmem->mmaps, mmap_reg, link); + g_free(mmap_reg); + } + } } static const Property virtio_properties[] = { diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 6386910280..a778547c79 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -98,6 +98,21 @@ enum virtio_device_endian { VIRTIO_DEVICE_ENDIAN_BIG, }; +struct MappedMemoryRegion { + MemoryRegion *mem; + hwaddr offset; + QTAILQ_ENTRY(MappedMemoryRegion) link; +}; + +typedef struct MappedMemoryRegion MappedMemoryRegion; + +struct VirtSharedMemory { + MemoryRegion *mr; + QTAILQ_HEAD(, MappedMemoryRegion) mmaps; +}; + +typedef struct VirtSharedMemory VirtSharedMemory; + /** * struct VirtIODevice - common VirtIO structure * @name: name of the device @@ -167,6 +182,9 @@ struct VirtIODevice */ EventNotifier config_notifier; bool device_iotlb_enabled; + /* Shared memory region for vhost-user mappings. */ + VirtSharedMemory *shmem_list; + int n_shmem_regions; }; struct VirtioDeviceClass { @@ -289,6 +307,15 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); int virtio_save(VirtIODevice *vdev, QEMUFile *f); +VirtSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev); +void virtio_add_shmem_map(VirtSharedMemory *shmem, const char *shm_name, + hwaddr shm_offset, hwaddr fd_offset, uint64_t size, + int fd, Error **errp); +MappedMemoryRegion *virtio_find_shmem_map(VirtSharedMemory *shmem, hwaddr offset, + uint64_t size); +void virtio_del_shmem_map(VirtSharedMemory *shmem, hwaddr offset, + uint64_t size); + extern const VMStateInfo virtio_vmstate_info; #define VMSTATE_VIRTIO_DEVICE \ diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-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[UUID_LEN]) return vu_send_message(dev, &msg); } +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 = { + .request = VHOST_USER_BACKEND_SHMEM_MAP, + .size = sizeof(vmsg.payload.mmap), + .flags = VHOST_USER_VERSION, + .payload.mmap = { + .shmid = shmid, + .fd_offset = fd_offset, + .shm_offset = shm_offset, + .len = len, + .flags = flags, + }, + .fd_num = 1, + .fds[0] = 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 |= 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 len) +{ + VhostUserMsg vmsg = { + .request = VHOST_USER_BACKEND_SHMEM_UNMAP, + .size = sizeof(vmsg.payload.mmap), + .flags = VHOST_USER_VERSION, + .payload.mmap = { + .shmid = shmid, + .fd_offset = 0, + .shm_offset = shm_offset, + .len = 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 |= 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/libvhost-user/libvhost-user.h index 2ffc58c11b..e9adb836f0 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 = 18, + /* Feature 19 is reserved for VHOST_USER_PROTOCOL_F_DEVICE_STATE */ + VHOST_USER_PROTOCOL_F_SHMEM = 20, VHOST_USER_PROTOCOL_F_MAX }; @@ -127,6 +129,8 @@ typedef enum VhostUserBackendRequest { VHOST_USER_BACKEND_SHARED_OBJECT_ADD = 6, VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE = 7, VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP = 8, + VHOST_USER_BACKEND_SHMEM_MAP = 9, + VHOST_USER_BACKEND_SHMEM_UNMAP = 10, VHOST_USER_BACKEND_MAX } VhostUserBackendRequest; @@ -186,6 +190,24 @@ typedef struct VhostUserShared { unsigned char uuid[UUID_LEN]; } VhostUserShared; +/* For the flags field of VhostUserMMap */ +#define VHOST_USER_FLAG_MAP_R (1u << 0) +#define VHOST_USER_FLAG_MAP_W (1u << 1) + +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_* */ + uint64_t flags; +} VhostUserMMap; + #define VU_PACKED __attribute__((packed)) typedef struct VhostUserMsg { @@ -210,6 +232,7 @@ typedef struct VhostUserMsg { VhostUserVringArea area; VhostUserInflight inflight; VhostUserShared object; + VhostUserMMap mmap; } payload; int fds[VHOST_MEMORY_BASELINE_NREGIONS]; @@ -593,6 +616,38 @@ bool vu_add_shared_object(VuDev *dev, unsigned char uuid[UUID_LEN]); */ bool vu_rm_shared_object(VuDev *dev, unsigned char uuid[UUID_LEN]); +/** + * 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 Region. + * + * 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 fd); + +/** + * 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 From patchwork Mon Feb 17 16:40:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978286 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D3496C021AD for ; Mon, 17 Feb 2025 16:42:23 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4C4-0004VY-E5; Mon, 17 Feb 2025 11:42:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C3-0004VM-F9 for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:03 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C1-0007wq-Ve for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810521; 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=4SjDTh66mEQX1doULZPhA4TPZA1F/E9TYQcDWSRSI7Y=; b=hDyf8z/JjR7li/n5OifLBvSnlHrI+8WqD9fHzOWz26/ngDhEIoXjj/q+DiRZSDkirtwKwu 4PO8Pu8KHvyNMcDECnr6vTKAMkVqIiZcvNqg1/B1o2IFppWBpSb6lRaIBq7uyJcXlTrXF+ pF1wPqk/mCM6TwtkhvDPVa7UFokbEbE= 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-553-YIBB2mrrPiiXAgUHpiYVgg-1; Mon, 17 Feb 2025 11:40:34 -0500 X-MC-Unique: YIBB2mrrPiiXAgUHpiYVgg-1 X-Mimecast-MFC-AGG-ID: YIBB2mrrPiiXAgUHpiYVgg_1739810431 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A7CA818D95E0; Mon, 17 Feb 2025 16:40:31 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 978DB1800358; Mon, 17 Feb 2025 16:40:25 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 2/9] vhost_user.rst: Align VhostUserMsg excerpt members Date: Mon, 17 Feb 2025 17:40:05 +0100 Message-ID: <20250217164012.246727-3-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add missing members to the VhostUserMsg excerpt in the vhost-user spec documentation. Signed-off-by: Albert Esteve Reviewed-by: Stefan Hajnoczi --- 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 the 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; From patchwork Mon Feb 17 16:40:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978288 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 31579C021A9 for ; Mon, 17 Feb 2025 16:42:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4Bt-0004Rt-JK; Mon, 17 Feb 2025 11:41:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4Br-0004Q2-3K for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:41:51 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4Bp-0007ub-E9 for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:41:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810508; 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=Uw+kJrcc03MeOrITLQiE+ix6zWcHlf6Spg7JUuKfvQo=; b=c/3qmZQCoAnSP9OQ5ZWQHvq/nS2IrFMq1So4/yEGTvJQ2vtuJibfNC00191Iz0u7z/Xtol mdJQGGh6vyN2Mdr7icvqLoiWrREZRme2O9u3VKLusMujiakU3PkruNTfCPto+DFSK/jz6y Vli3CELgj7ce8YvCYw3ptnkdpUbK6Ho= 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-442-lMYQWpJ4O4OyNhBZn4ZmJQ-1; Mon, 17 Feb 2025 11:40:38 -0500 X-MC-Unique: lMYQWpJ4O4OyNhBZn4ZmJQ-1 X-Mimecast-MFC-AGG-ID: lMYQWpJ4O4OyNhBZn4ZmJQ_1739810437 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 111501800989; Mon, 17 Feb 2025 16:40:37 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 41A871800358; Mon, 17 Feb 2025 16:40:31 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 3/9] vhost_user.rst: Add SHMEM_MAP/_UNMAP to spec Date: Mon, 17 Feb 2025 17:40:06 +0100 Message-ID: <20250217164012.246727-4-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 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 | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 436a94c0ee..c15d6ac467 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -375,6 +375,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; @@ -1057,6 +1058,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 Front-end message types ----------------------- @@ -1865,6 +1867,38 @@ 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. +``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 Region. + Upon receiving the message, the front-end will mmap the given fd into the + VIRTIO Shared Memory Region with the requested ``shmid``. A reply is + generated indicating whether mapping succeeded. + + Mapping over an already existing map is not allowed and request shall fail. + 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 resources + 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-mmap a given range (``shm_offset``, ``len``) in the + 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: VHOST_USER_PROTOCOL_F_REPLY_ACK From patchwork Mon Feb 17 16:40:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A056BC021AB for ; Mon, 17 Feb 2025 16:43:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4Bt-0004S0-PG; Mon, 17 Feb 2025 11:41:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4Bs-0004RT-Kv for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:41:52 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4Bp-0007uc-E3 for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:41:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810508; 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=wCSNIO7Jgf7K3cQLPo9RJhFfSt1MZtQLVJpGD1sBS0c=; b=R/4jU1JxZLereAV5u3j3sT/+SpqX+x6NWlfTkImpwSCQ4J39BU/GUMZsIOrFqg/mWgBcve oNVpxco5f+/qJ1C98+p5eWUsCHYbMa8/ehDsqoLxBju1F5TcFhXCdgI2XEoeQv/7inyVWM Ph9MRa1pFWra09j10YrE4cGqqFmMYGM= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-542-lGnC1vm1PJ-rRDDAmJG2yg-1; Mon, 17 Feb 2025 11:40:42 -0500 X-MC-Unique: lGnC1vm1PJ-rRDDAmJG2yg-1 X-Mimecast-MFC-AGG-ID: lGnC1vm1PJ-rRDDAmJG2yg_1739810441 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9552F19783B3; Mon, 17 Feb 2025 16:40:41 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A9E7E1800352; Mon, 17 Feb 2025 16:40:37 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 4/9] vhost_user: Add frontend get_shmem_config command Date: Mon, 17 Feb 2025 17:40:07 +0100 Message-ID: <20250217164012.246727-5-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 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. Signed-off-by: Albert Esteve --- hw/virtio/vhost-user.c | 43 +++++++++++++++++++++++++++++++ include/hw/virtio/vhost-backend.h | 9 +++++++ include/hw/virtio/vhost-user.h | 1 + include/hw/virtio/virtio.h | 2 ++ 4 files changed, 55 insertions(+) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index d88e6f8c3c..9cc148f726 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -104,6 +104,7 @@ typedef enum VhostUserRequest { VHOST_USER_GET_SHARED_OBJECT = 41, VHOST_USER_SET_DEVICE_STATE_FD = 42, VHOST_USER_CHECK_DEVICE_STATE = 43, + VHOST_USER_GET_SHMEM_CONFIG = 44, VHOST_USER_MAX } VhostUserRequest; @@ -138,6 +139,12 @@ typedef struct VhostUserMemRegMsg { VhostUserMemoryRegion region; } VhostUserMemRegMsg; +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; typedef struct VhostUserMsg { @@ -3146,6 +3154,40 @@ static int vhost_user_check_device_state(struct vhost_dev *dev, Error **errp) return 0; } +static int vhost_user_get_shmem_config(struct vhost_dev *dev, + int *nregions, + uint64_t *memory_sizes, + Error **errp) +{ + int ret; + VhostUserMsg msg = { + .hdr.request = VHOST_USER_GET_SHMEM_CONFIG, + .hdr.flags = VHOST_USER_VERSION, + }; + + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_SHMEM)) { + return 0; + } + + ret = vhost_user_write(dev, &msg, NULL, 0); + if (ret < 0) { + return ret; + } + + ret = vhost_user_read(dev, &msg); + if (ret < 0) { + return ret; + } + + assert(msg.payload.shmem.nregions <= VIRTIO_MAX_SHMEM_REGIONS); + *nregions = msg.payload.shmem.nregions; + memcpy(memory_sizes, + &msg.payload.shmem.memory_sizes, + sizeof(uint64_t) * VHOST_MEMORY_BASELINE_NREGIONS); + return 0; +} + const VhostOps user_ops = { .backend_type = VHOST_BACKEND_TYPE_USER, .vhost_backend_init = vhost_user_backend_init, @@ -3184,4 +3226,5 @@ const VhostOps user_ops = { .vhost_supports_device_state = vhost_user_supports_device_state, .vhost_set_device_state_fd = vhost_user_set_device_state_fd, .vhost_check_device_state = vhost_user_check_device_state, + .vhost_get_shmem_config = vhost_user_get_shmem_config, }; diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index 70c2e8ffee..b40d82a111 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -159,6 +159,14 @@ typedef int (*vhost_set_device_state_fd_op)(struct vhost_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); + typedef struct VhostOps { VhostBackendType backend_type; @@ -214,6 +222,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; 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 = 18, VHOST_USER_PROTOCOL_F_DEVICE_STATE = 19, + VHOST_USER_PROTOCOL_F_SHMEM = 20, VHOST_USER_PROTOCOL_F_MAX }; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index a778547c79..319e2f5b06 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -81,6 +81,8 @@ typedef struct VirtQueueElement #define VIRTIO_NO_VECTOR 0xffff +#define VIRTIO_MAX_SHMEM_REGIONS 256 + /* special index value used internally for config irqs */ #define VIRTIO_CONFIG_IRQ_IDX -1 From patchwork Mon Feb 17 16:40:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3656DC021AA for ; Mon, 17 Feb 2025 16:42:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4C9-0004Xp-9L; Mon, 17 Feb 2025 11:42:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C5-0004W2-0N for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:05 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C2-0007wl-Ei for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810521; 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=ETv3rIMw2ZiMS20wCD23KE5549xc0CWPXx7VojiRKr0=; b=gQeYqiugvn0jSX4drnPV5nzXTe3s3zU3rcQRebR+orYPt6wx1oxzfJ6dEDz4yP5UIGwFsO 1jctp2d1e9NkyVlWjQ78JvsXdVlxcYMlfQAYUQyGstfUeeZ6mx711c08bbCxxcDQPPmcaZ qg5iR1Ti+mji4Ct/N8H9K25E5jXH7Cc= 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-527-DkwQ77lBOLq1QSrxQJQjLA-1; Mon, 17 Feb 2025 11:40:47 -0500 X-MC-Unique: DkwQ77lBOLq1QSrxQJQjLA-1 X-Mimecast-MFC-AGG-ID: DkwQ77lBOLq1QSrxQJQjLA_1739810446 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 539831800874; Mon, 17 Feb 2025 16:40:46 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3157C1800352; Mon, 17 Feb 2025 16:40:41 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 5/9] vhost_user.rst: Add GET_SHMEM_CONFIG message Date: Mon, 17 Feb 2025 17:40:08 +0100 Message-ID: <20250217164012.246727-6-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add GET_SHMEM_CONFIG vhost-user frontend message to the spec documentation. Reviewed-by: Alyssa Ross Signed-off-by: Albert Esteve Reviewed-by: Stefan Hajnoczi --- 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 c15d6ac467..96156f1900 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -350,6 +350,20 @@ Device state transfer parameters In the future, additional phases might be added e.g. to allow iterative migration while the device is running. +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 ----------- @@ -376,6 +390,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; @@ -1733,6 +1748,30 @@ Front-end message types Using this function requires prior negotiation of the ``VHOST_USER_PROTOCOL_F_DEVICE_STATE`` feature. +``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 will + 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 ---------------------- From patchwork Mon Feb 17 16:40:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 89C2BC021AB for ; Mon, 17 Feb 2025 16:43:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4CG-0004b1-B0; Mon, 17 Feb 2025 11:42:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4CB-0004YE-6d for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:11 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C7-0007xq-Fb for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810526; 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=R95NeY5El2VbpjDQaOmPH3r2sZasiLY8XwdCzZn/RTA=; b=Q20a/J5tXVgHJMT/bkd+8sXa2U9+c6Yl7ib7nSKDaopCgSm1aKILS3R8f4VR+d8uyM0TT3 Z5J6qvfk2yxcJFUbH0Erz3FARlOWReAiQLerI5xRB4tayqrpDUaLGWvufzBUTuKF7Y4GSE 30v+b52n7TQp+deAeSLlTxZMn6dmLXA= 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-318-_8ZBgASaM8-seegCx8txQQ-1; Mon, 17 Feb 2025 11:40:53 -0500 X-MC-Unique: _8ZBgASaM8-seegCx8txQQ-1 X-Mimecast-MFC-AGG-ID: _8ZBgASaM8-seegCx8txQQ_1739810451 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 087691800873; Mon, 17 Feb 2025 16:40:51 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D907E1800352; Mon, 17 Feb 2025 16:40:46 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 6/9] qmp: add shmem feature map Date: Mon, 17 Feb 2025 17:40:09 +0100 Message-ID: <20250217164012.246727-7-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add new vhost-user protocol VHOST_USER_PROTOCOL_F_SHMEM feature to feature map. Signed-off-by: Albert Esteve Reviewed-by: Stefan Hajnoczi --- 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_protocol_map[] = { FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_DEVICE_STATE, \ "VHOST_USER_PROTOCOL_F_DEVICE_STATE: Backend device state transfer " "supported"), + FEATURE_ENTRY(VHOST_USER_PROTOCOL_F_SHMEM, \ + "VHOST_USER_PROTOCOL_F_SHMEM: Backend shared memory mapping " + "supported"), { -1, "" } }; From patchwork Mon Feb 17 16:40:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978293 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3ECACC021A9 for ; Mon, 17 Feb 2025 16:43:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4CG-0004ai-0w; Mon, 17 Feb 2025 11:42:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4CB-0004YD-6F for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:11 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4C8-0007xy-Nt for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810526; 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=ubezkmUehuzQvAhFogyPP24DcAfnGVx9m7LdWtywJrs=; b=BXzdt2ShQaBwji82AwgwDfuzsD2fnnty39xtI2uBpMnznWc8DauI+NEJbIK6JNKBrzGDOe iRi/WiPMw+BRMkW1GaNRmiG3xkYM0ArFxoz3wZAjvgLyImdfI9Yrix0F3XG3ImED0D/dJE mjYTIgMVVn4wCmSNs8eFe6ln078iK68= Received: from mx-prod-mc-02.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-600-5Dsiq_VsMKS9rJjEU_sZEA-1; Mon, 17 Feb 2025 11:40:57 -0500 X-MC-Unique: 5Dsiq_VsMKS9rJjEU_sZEA-1 X-Mimecast-MFC-AGG-ID: 5Dsiq_VsMKS9rJjEU_sZEA_1739810457 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D664418EB2CE; Mon, 17 Feb 2025 16:40:56 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8F4C11800352; Mon, 17 Feb 2025 16:40:51 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 7/9] vhost-user-devive: Add shmem BAR Date: Mon, 17 Feb 2025 17:40:10 +0100 Message-ID: <20250217164012.246727-8-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a shmem BAR block in the vhost-user-device, which files can be directly mapped into. The number, shmid, and size of the VIRTIO Shared Memory subregions is retrieved through a get_shmem_config message sent by the vhost-user-base module on the realize step, after virtio_init(). By default, if VHOST_USER_PROTOCOL_F_SHMEM feature is not supported by the backend, there is no cache. Signed-off-by: Albert Esteve --- hw/virtio/vhost-user-base.c | 47 +++++++++++++++++++++++++++++-- hw/virtio/vhost-user-device-pci.c | 36 +++++++++++++++++++++-- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c index 2bc3423326..8d4bca98a8 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" static void vub_start(VirtIODevice *vdev) { @@ -271,7 +272,8 @@ static void vub_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VHostUserBase *vub = VHOST_USER_BASE(dev); - int ret; + uint64_t memory_sizes[VIRTIO_MAX_SHMEM_REGIONS]; + int i, ret, nregions; if (!vub->chardev.chr) { error_setg(errp, "vhost-user-base: missing chardev"); @@ -314,7 +316,7 @@ static void vub_device_realize(DeviceState *dev, Error **errp) /* Allocate queues */ vub->vqs = g_ptr_array_sized_new(vub->num_vqs); - for (int i = 0; i < vub->num_vqs; i++) { + for (i = 0; i < vub->num_vqs; i++) { g_ptr_array_add(vub->vqs, virtio_add_queue(vdev, vub->vq_size, vub_handle_output)); @@ -328,11 +330,50 @@ static void vub_device_realize(DeviceState *dev, Error **errp) VHOST_BACKEND_TYPE_USER, 0, errp); if (ret < 0) { - do_vhost_user_cleanup(vdev, vub); + goto err; + } + + ret = vub->vhost_dev.vhost_ops->vhost_get_shmem_config(&vub->vhost_dev, + &nregions, + memory_sizes, + errp); + + if (ret < 0) { + goto err; + } + + for (i = 0; i < nregions; i++) { + if (memory_sizes[i]) { + if (vub->vhost_dev.migration_blocker == NULL) { + error_setg(&vub->vhost_dev.migration_blocker, + "Migration disabled: devices with VIRTIO Shared Memory " + "Regions do not support migration yet."); + ret = migrate_add_blocker_normal( + &vub->vhost_dev.migration_blocker, + errp); + + if (ret < 0) { + goto err; + } + } + + if (memory_sizes[i] % qemu_real_host_page_size() != 0) { + error_setg(errp, "Shared memory %d size must be a power of 2 " + "no smaller than the page size", i); + goto err; + } + + memory_region_init(virtio_new_shmem_region(vdev)->mr, + OBJECT(vdev), "vub-shm-" + i, + memory_sizes[i]); + } } qemu_chr_fe_set_handlers(&vub->chardev, NULL, NULL, vub_event, NULL, dev, NULL, true); + return; +err: + do_vhost_user_cleanup(vdev, vub); } static void vub_device_unrealize(DeviceState *dev) diff --git a/hw/virtio/vhost-user-device-pci.c b/hw/virtio/vhost-user-device-pci.c index efaf55d3dd..f215cae925 100644 --- a/hw/virtio/vhost-user-device-pci.c +++ b/hw/virtio/vhost-user-device-pci.c @@ -8,14 +8,18 @@ */ #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" +#define VIRTIO_DEVICE_PCI_SHMEM_BAR 2 + struct VHostUserDevicePCI { VirtIOPCIProxy parent_obj; VHostUserBase vub; + MemoryRegion shmembar; }; #define TYPE_VHOST_USER_DEVICE_PCI "vhost-user-device-pci-base" @@ -25,10 +29,38 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserDevicePCI, VHOST_USER_DEVICE_PCI) static void vhost_user_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VHostUserDevicePCI *dev = VHOST_USER_DEVICE_PCI(vpci_dev); - DeviceState *vdev = DEVICE(&dev->vub); + DeviceState *dev_state = DEVICE(&dev->vub); + VirtIODevice *vdev = VIRTIO_DEVICE(dev_state); + MemoryRegion *mr; + uint64_t offset = 0, shmem_size = 0; + int i; vpci_dev->nvectors = 1; - qdev_realize(vdev, BUS(&vpci_dev->bus), errp); + qdev_realize(dev_state, BUS(&vpci_dev->bus), errp); + + for (i = 0; i < vdev->n_shmem_regions; i++) { + mr = vdev->shmem_list[i].mr; + if (mr->size > UINT64_MAX - shmem_size) { + error_setg(errp, "Total shared memory required overflow"); + return; + } + shmem_size = shmem_size + mr->size; + } + if (shmem_size) { + memory_region_init(&dev->shmembar, OBJECT(vpci_dev), + "vhost-device-pci-shmembar", shmem_size); + for (i = 0; i < vdev->n_shmem_regions; i++) { + memory_region_add_subregion(&dev->shmembar, offset, mr); + virtio_pci_add_shm_cap(vpci_dev, VIRTIO_DEVICE_PCI_SHMEM_BAR, + offset, mr->size, i); + offset = offset + 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); + } } static void vhost_user_device_pci_class_init(ObjectClass *klass, void *data) From patchwork Mon Feb 17 16:40:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978294 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0F782C021A9 for ; Mon, 17 Feb 2025 16:44:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4CK-0004cz-Qt; Mon, 17 Feb 2025 11:42:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4CI-0004c4-TA for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:18 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4CG-0007yy-0f for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810534; 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=pzvuro8eKFYDs1uS55wHTgebiFb0lbyNlTrCJNYvvJ8=; b=hwZzeFilx+rIC7aaka7noXyQou+SFpqON3Ngt5osSnhDQdcB0/1jVWiasZQadJnO/VijWs VwLTYBIQEx33YFONYzDZZv7NTfXm/dUoMgN/9uVU4BqoCEknxU3WfACQ599O5gsbPtlGkw 3X8LyGGUU6ycysDiPKHGlLRcF8LUEfY= 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-613-IK9rLLDDM5uq6Ke8R1t3MQ-1; Mon, 17 Feb 2025 11:41:02 -0500 X-MC-Unique: IK9rLLDDM5uq6Ke8R1t3MQ-1 X-Mimecast-MFC-AGG-ID: IK9rLLDDM5uq6Ke8R1t3MQ_1739810461 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A67A718E6952; Mon, 17 Feb 2025 16:41:01 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 65FD71800352; Mon, 17 Feb 2025 16:40:57 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 8/9] vhost_user: Add mem_read/write backend requests Date: Mon, 17 Feb 2025 17:40:11 +0100 Message-ID: <20250217164012.246727-9-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org With SHMEM_MAP messages, sharing descriptors between devices will cause that these devices do not see the mappings, and fail to access these memory regions. To solve this, introduce MEM_READ/WRITE requests that will get triggered as a fallback when vhost-user memory translation fails. MEM_READ/WRITE requests have flexible array members, since we do not know in advance the number of bytes in the mapped region. Therefore, we need to allow bigger message sizes for these types, and ensure we allocate sufficient memory for them. Signed-off-by: Albert Esteve --- hw/virtio/vhost-user.c | 99 +++++++++++++++++------ subprojects/libvhost-user/libvhost-user.c | 90 +++++++++++++++++++++ subprojects/libvhost-user/libvhost-user.h | 37 +++++++++ 3 files changed, 202 insertions(+), 24 deletions(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 9cc148f726..ab92905a36 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -118,6 +118,8 @@ typedef enum VhostUserBackendRequest { VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP = 8, VHOST_USER_BACKEND_SHMEM_MAP = 9, VHOST_USER_BACKEND_SHMEM_UNMAP = 10, + VHOST_USER_BACKEND_MEM_READ = 11, + VHOST_USER_BACKEND_MEM_WRITE = 12, VHOST_USER_BACKEND_MAX } VhostUserBackendRequest; @@ -145,6 +147,12 @@ typedef struct VhostUserShMemConfig { uint64_t memory_sizes[VIRTIO_MAX_SHMEM_REGIONS]; } VhostUserShMemConfig; +typedef struct VhostUserMemRWMsg { + uint64_t guest_address; + uint32_t size; + uint8_t data[]; +} VhostUserMemRWMsg; + typedef struct VhostUserLog { uint64_t mmap_size; uint64_t mmap_offset; @@ -253,6 +261,7 @@ typedef union { VhostUserTransferDeviceState transfer_state; VhostUserMMap mmap; VhostUserShMemConfig shmem; + VhostUserMemRWMsg mem_rw; } VhostUserPayload; typedef struct VhostUserMsg { @@ -341,17 +350,23 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg) return r; } - /* validate message size is sane */ - if (msg->hdr.size > VHOST_USER_PAYLOAD_SIZE) { - error_report("Failed to read msg header." - " Size %d exceeds the maximum %zu.", msg->hdr.size, - VHOST_USER_PAYLOAD_SIZE); - return -EPROTO; - } - if (msg->hdr.size) { p += VHOST_USER_HDR_SIZE; size = msg->hdr.size; + /* validate message size is sane */ + if (msg->hdr.size > VHOST_USER_PAYLOAD_SIZE) { + switch(msg->hdr.request) { + case VHOST_USER_BACKEND_MEM_READ: + case VHOST_USER_BACKEND_MEM_WRITE: + p = g_malloc0(size); + break; + default: + error_report("Failed to read msg header." + " Size %d exceeds the maximum %zu.", + size, VHOST_USER_PAYLOAD_SIZE); + return -EPROTO; + } + } r = qemu_chr_fe_read_all(chr, p, size); if (r != size) { int saved_errno = errno; @@ -1904,6 +1919,28 @@ vhost_user_backend_handle_shmem_unmap(struct vhost_dev *dev, return 0; } +static int +vhost_user_backend_handle_mem_read(struct vhost_dev *dev, + VhostUserMemRWMsg *mem_rw) +{ + MemTxResult result; + result = address_space_read(dev->vdev->dma_as, mem_rw->guest_address, + MEMTXATTRS_UNSPECIFIED, &mem_rw->data, + mem_rw->size); + return result; +} + +static int +vhost_user_backend_handle_mem_write(struct vhost_dev *dev, + VhostUserMemRWMsg *mem_rw) +{ + MemTxResult result; + result = address_space_write(dev->vdev->dma_as, mem_rw->guest_address, + MEMTXATTRS_UNSPECIFIED, &mem_rw->data, + mem_rw->size); + return result; +} + static void close_backend_channel(struct vhost_user *u) { g_source_destroy(u->backend_src); @@ -1919,7 +1956,7 @@ static gboolean backend_read(QIOChannel *ioc, GIOCondition condition, struct vhost_dev *dev = opaque; struct vhost_user *u = dev->opaque; VhostUserHeader hdr = { 0, }; - VhostUserPayload payload = { 0, }; + VhostUserPayload *payload = g_new0(VhostUserPayload, 1); Error *local_err = NULL; gboolean rc = G_SOURCE_CONTINUE; int ret = 0; @@ -1938,47 +1975,60 @@ static gboolean backend_read(QIOChannel *ioc, GIOCondition condition, } if (hdr.size > VHOST_USER_PAYLOAD_SIZE) { - error_report("Failed to read msg header." - " Size %d exceeds the maximum %zu.", hdr.size, - VHOST_USER_PAYLOAD_SIZE); - goto err; + switch (hdr.request) { + case VHOST_USER_BACKEND_MEM_READ: + case VHOST_USER_BACKEND_MEM_WRITE: + payload = g_malloc0(hdr.size); + break; + default: + error_report("Failed to read msg header." + " Size %d exceeds the maximum %zu.", hdr.size, + VHOST_USER_PAYLOAD_SIZE); + goto err; + } } /* Read payload */ - if (qio_channel_read_all(ioc, (char *) &payload, hdr.size, &local_err)) { + if (qio_channel_read_all(ioc, (char *) payload, hdr.size, &local_err)) { error_report_err(local_err); goto err; } switch (hdr.request) { case VHOST_USER_BACKEND_IOTLB_MSG: - ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb); + ret = vhost_backend_handle_iotlb_msg(dev, &payload->iotlb); break; case VHOST_USER_BACKEND_CONFIG_CHANGE_MSG: ret = vhost_user_backend_handle_config_change(dev); break; case VHOST_USER_BACKEND_VRING_HOST_NOTIFIER_MSG: - ret = vhost_user_backend_handle_vring_host_notifier(dev, &payload.area, + ret = vhost_user_backend_handle_vring_host_notifier(dev, &payload->area, fd ? fd[0] : -1); break; case VHOST_USER_BACKEND_SHARED_OBJECT_ADD: - ret = vhost_user_backend_handle_shared_object_add(dev, &payload.object); + ret = vhost_user_backend_handle_shared_object_add(dev, &payload->object); break; case VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE: ret = vhost_user_backend_handle_shared_object_remove(dev, - &payload.object); + &payload->object); break; case VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP: ret = vhost_user_backend_handle_shared_object_lookup(dev->opaque, ioc, - &hdr, &payload); + &hdr, payload); + break; case VHOST_USER_BACKEND_SHMEM_MAP: - ret = vhost_user_backend_handle_shmem_map(dev, ioc, &hdr, &payload, + ret = vhost_user_backend_handle_shmem_map(dev, ioc, &hdr, payload, fd ? fd[0] : -1, &local_err); break; case VHOST_USER_BACKEND_SHMEM_UNMAP: - ret = vhost_user_backend_handle_shmem_unmap(dev, ioc, &hdr, &payload, + ret = vhost_user_backend_handle_shmem_unmap(dev, ioc, &hdr, payload, &local_err); break; + case VHOST_USER_BACKEND_MEM_READ: + ret = vhost_user_backend_handle_mem_read(dev, &payload->mem_rw); + break; + case VHOST_USER_BACKEND_MEM_WRITE: + ret = vhost_user_backend_handle_mem_write(dev, &payload->mem_rw); break; default: error_report("Received unexpected msg type: %d.", hdr.request); @@ -1990,10 +2040,10 @@ static gboolean backend_read(QIOChannel *ioc, GIOCondition condition, * directly in their request handlers. */ if (hdr.flags & VHOST_USER_NEED_REPLY_MASK) { - payload.u64 = !!ret; - hdr.size = sizeof(payload.u64); + payload->u64 = !!ret; + hdr.size = sizeof(payload->u64); - if (!vhost_user_send_resp(ioc, &hdr, &payload, &local_err)) { + if (!vhost_user_send_resp(ioc, &hdr, payload, &local_err)) { error_report_err(local_err); goto err; } @@ -2011,6 +2061,7 @@ fdcleanup: close(fd[i]); } } + g_free(payload); return rc; } diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c index 034cbfdc3c..575a0af556 100644 --- a/subprojects/libvhost-user/libvhost-user.c +++ b/subprojects/libvhost-user/libvhost-user.c @@ -1662,6 +1662,96 @@ vu_shmem_unmap(VuDev *dev, uint8_t shmid, uint64_t shm_offset, uint64_t len) return vu_process_message_reply(dev, &vmsg); } +bool +vu_send_mem_read(VuDev *dev, uint64_t guest_addr, uint32_t size, + uint8_t *data) +{ + VhostUserMsg msg_reply; + VhostUserMsg msg = { + .request = VHOST_USER_BACKEND_MEM_READ, + .size = sizeof(msg.payload.mem_rw), + .flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK, + .payload = { + .mem_rw = { + .guest_address = guest_addr, + .size = size, + } + } + }; + + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_SHMEM)) { + return false; + } + + pthread_mutex_lock(&dev->backend_mutex); + if (!vu_message_write(dev, dev->backend_fd, &msg)) { + goto out_err; + } + + if (!vu_message_read_default(dev, dev->backend_fd, &msg_reply)) { + goto out_err; + } + + if (msg_reply.request != msg.request) { + DPRINT("Received unexpected msg type. Expected %d, received %d", + msg.request, msg_reply.request); + goto out_err; + } + + if (msg_reply.payload.mem_rw.size != size) { + DPRINT("Received unexpected number of bytes in the response. " + "Expected %d, received %d", + size, msg_reply.payload.mem_rw.size); + goto out_err; + } + + /* TODO: It should be possible to avoid memcpy() here by receiving + * directly into the caller's buffer. */ + memcpy(data, msg_reply.payload.mem_rw.data, size); + pthread_mutex_unlock(&dev->backend_mutex); + return true; + +out_err: + pthread_mutex_unlock(&dev->backend_mutex); + return false; +} + +bool +vu_send_mem_write(VuDev *dev, uint64_t guest_addr, uint32_t size, + uint8_t *data) +{ + VhostUserMsg msg = { + .request = VHOST_USER_BACKEND_MEM_WRITE, + .size = sizeof(msg.payload.mem_rw), + .flags = VHOST_USER_VERSION, + .payload = { + .mem_rw = { + .guest_address = guest_addr, + .size = size, + } + } + }; + /* TODO: It should be possible to avoid memcpy() here by receiving + * directly into the caller's buffer. */ + memcpy(msg.payload.mem_rw.data, data, size); + + 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)) { + msg.flags |= VHOST_USER_NEED_REPLY_MASK; + } + + if (!vu_message_write(dev, dev->backend_fd, &msg)) { + pthread_mutex_unlock(&dev->backend_mutex); + return false; + } + + /* Also unlocks the backend_mutex */ + return vu_process_message_reply(dev, &msg); +} + static bool vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg) { diff --git a/subprojects/libvhost-user/libvhost-user.h b/subprojects/libvhost-user/libvhost-user.h index e9adb836f0..57e2fb9c98 100644 --- a/subprojects/libvhost-user/libvhost-user.h +++ b/subprojects/libvhost-user/libvhost-user.h @@ -131,6 +131,8 @@ typedef enum VhostUserBackendRequest { VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP = 8, VHOST_USER_BACKEND_SHMEM_MAP = 9, VHOST_USER_BACKEND_SHMEM_UNMAP = 10, + VHOST_USER_BACKEND_MEM_READ = 11, + VHOST_USER_BACKEND_MEM_WRITE = 12, VHOST_USER_BACKEND_MAX } VhostUserBackendRequest; @@ -154,6 +156,12 @@ typedef struct VhostUserMemRegMsg { VhostUserMemoryRegion region; } VhostUserMemRegMsg; +typedef struct VhostUserMemRWMsg { + uint64_t guest_address; + uint32_t size; + uint8_t data[]; +} VhostUserMemRWMsg; + typedef struct VhostUserLog { uint64_t mmap_size; uint64_t mmap_offset; @@ -233,6 +241,7 @@ typedef struct VhostUserMsg { VhostUserInflight inflight; VhostUserShared object; VhostUserMMap mmap; + VhostUserMemRWMsg mem_rw; } payload; int fds[VHOST_MEMORY_BASELINE_NREGIONS]; @@ -647,6 +656,34 @@ bool vu_shmem_map(VuDev *dev, uint8_t shmid, uint64_t fd_offset, */ bool vu_shmem_unmap(VuDev *dev, uint8_t shmid, uint64_t shm_offset, uint64_t len); +/** + * vu_send_mem_read: + * @dev: a VuDev context + * @guest_addr: guest physical address to read + * @size: number of bytes to read + * @data: head of an unitialized bytes array + * + * Reads `size` bytes of `guest_addr` in the frontend and stores + * them in `data`. + * + * Returns: TRUE on success, FALSE on failure. + */ +bool vu_send_mem_read(VuDev *dev, uint64_t guest_addr, uint32_t size, + uint8_t *data); + +/** + * vu_send_mem_write: + * @dev: a VuDev context + * @guest_addr: guest physical address to write + * @size: number of bytes to write + * @data: head of an array with `size` bytes to write + * + * Writes `size` bytes from `data` into `guest_addr` in the frontend. + * + * Returns: TRUE on success, FALSE on failure. + */ +bool vu_send_mem_write(VuDev *dev, uint64_t guest_addr, uint32_t size, + uint8_t *data); /** * vu_queue_set_notification: From patchwork Mon Feb 17 16:40:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert Esteve X-Patchwork-Id: 13978292 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5BE8DC021AA for ; Mon, 17 Feb 2025 16:43:23 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tk4CN-0004ed-Ip; Mon, 17 Feb 2025 11:42:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4CI-0004cB-VW for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:18 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tk4CG-0007z9-3r for qemu-devel@nongnu.org; Mon, 17 Feb 2025 11:42:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1739810535; 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=rrOHEASD5ETftMjnPAsJydFA8UyEJ3azffjK7xeCoRc=; b=CH2Z1DMfPwMUgMpbnoUTHU0NjABD2fOR6NnI7fZfqRqv7jD1xqrUgZbmlBUZ/5YxyNFFDF k/TuogsPG97Nv1UFLgYYDe1DeEENkzByRgHnAko+5pkwVOyITpZl+tsiMS5OC7YDjdUzBM DfkZnsF9JQXXYuJne6FR2fZ7QVIA09M= 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-679-Ghl4AiDdM6Wz8Gl_v4r54Q-1; Mon, 17 Feb 2025 11:41:07 -0500 X-MC-Unique: Ghl4AiDdM6Wz8Gl_v4r54Q-1 X-Mimecast-MFC-AGG-ID: Ghl4AiDdM6Wz8Gl_v4r54Q_1739810466 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AFE121801A13; Mon, 17 Feb 2025 16:41:06 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.225.252]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 42A8D1800352; Mon, 17 Feb 2025 16:41:01 +0000 (UTC) From: Albert Esteve To: qemu-devel@nongnu.org Cc: slp@redhat.com, stevensd@chromium.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Stefano Garzarella , stefanha@redhat.com, david@redhat.com, hi@alyssa.is, mst@redhat.com, jasowang@redhat.com, Albert Esteve Subject: [PATCH v4 9/9] vhost_user.rst: Add MEM_READ/WRITE messages Date: Mon, 17 Feb 2025 17:40:12 +0100 Message-ID: <20250217164012.246727-10-aesteve@redhat.com> In-Reply-To: <20250217164012.246727-1-aesteve@redhat.com> References: <20250217164012.246727-1-aesteve@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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_NONE=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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add MEM_READ/WRITE request to the vhost-user spec documentation. Signed-off-by: Albert Esteve --- docs/interop/vhost-user.rst | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst index 96156f1900..9f7a2c4cf7 100644 --- a/docs/interop/vhost-user.rst +++ b/docs/interop/vhost-user.rst @@ -391,6 +391,7 @@ In QEMU the vhost-user message is implemented with the following struct: VhostUserTransferDeviceState transfer_state; VhostUserMMap mmap; VhostUserShMemConfig shmem; + VhostUserMemRWMsg mem_rw; }; } QEMU_PACKED VhostUserMsg; @@ -1938,6 +1939,38 @@ is sent by the front-end. given range shall correspond to the entirety of a valid mapped region. A reply is generated indicating whether unmapping succeeded. +``VHOST_USER_BACKEND_MEM_READ`` + :id: 11 + :equivalent ioctl: N/A + :request payload: ``struct VhostUserMemRWMsg`` + :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 + read a memory region that has failed to resolve a translation due to an + incomplete memory table, after another device called + ``VHOST_USER_BACKEND_SHMEM_MAP`` for the same region on a shared + descriptor file. + + This mechanism works as a fallback for resolving those memory + accesses and ensure that DMA works with Shared Memory Regions. + +``VHOST_USER_BACKEND_MEM_WRITE`` + :id: 12 + :equivalent ioctl: N/A + :request payload: ``struct VhostUserMemRWMsg`` + :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 + write a memory region that has failed due to resolve a translation an + incomplete memory table after another device called + ``VHOST_USER_BACKEND_SHMEM_MAP`` for the same region on a shared + descriptor file. + + This mechanism works as a fallback for resolving those memory + accesses and ensure that DMA works with Shared Memory Regions. + .. _reply_ack: VHOST_USER_PROTOCOL_F_REPLY_ACK