Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2225327/?format=api
{ "id": 2225327, "url": "http://patchwork.ozlabs.org/api/patches/2225327/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260420202032.714884-11-vsementsov@yandex-team.ru/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260420202032.714884-11-vsementsov@yandex-team.ru>", "list_archive_url": null, "date": "2026-04-20T20:20:31", "name": "[v2,10/10] vhost-user: add VHOST_USER_PROTOCOL_F_GPA_ADDRESSES", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "30bcf754f6cc07a17523089b0c020109a20be205", "submitter": { "id": 84116, "url": "http://patchwork.ozlabs.org/api/people/84116/?format=api", "name": "Vladimir Sementsov-Ogievskiy", "email": "vsementsov@yandex-team.ru" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260420202032.714884-11-vsementsov@yandex-team.ru/mbox/", "series": [ { "id": 500676, "url": "http://patchwork.ozlabs.org/api/series/500676/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=500676", "date": "2026-04-20T20:20:24", "name": "vhost-user: VHOST_USER_PROTOCOL_F_GPA_ADDRESSES", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/500676/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2225327/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2225327/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=yandex-team.ru header.i=@yandex-team.ru\n header.a=rsa-sha256 header.s=default header.b=p3eith/K;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)", "mail-nwsmtp-smtp-corp-main-80.iva.yp-c.yandex.net;\n dkim=pass header.i=@yandex-team.ru" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fzxjS4bZzz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 06:22:04 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wEv76-00065a-Jy; Mon, 20 Apr 2026 16:21:00 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <vsementsov@yandex-team.ru>)\n id 1wEv72-000646-NJ\n for qemu-devel@nongnu.org; Mon, 20 Apr 2026 16:20:57 -0400", "from forwardcorp1a.mail.yandex.net\n ([2a02:6b8:c0e:500:1:45:d181:df01])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <vsementsov@yandex-team.ru>)\n id 1wEv6y-0006QH-Ox\n for qemu-devel@nongnu.org; Mon, 20 Apr 2026 16:20:56 -0400", "from mail-nwsmtp-smtp-corp-main-80.iva.yp-c.yandex.net\n (mail-nwsmtp-smtp-corp-main-80.iva.yp-c.yandex.net\n [IPv6:2a02:6b8:c0c:c00c:0:640:e0de:0])\n by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id 93BEBC01B9;\n Mon, 20 Apr 2026 23:20:49 +0300 (MSK)", "from vsementsov-lin (unknown [2a02:6bf:8080:54b::1:34])\n by mail-nwsmtp-smtp-corp-main-80.iva.yp-c.yandex.net (smtpcorp) with ESMTPSA\n id XKYwe10MOSw0-XUxjBteE; Mon, 20 Apr 2026 23:20:48 +0300" ], "X-Yandex-Fwd": "1", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru;\n s=default; t=1776716448;\n bh=koxXe7SjW7IxzgK2obLjAe99mFTGm2Jl9M9elMSN1Fk=;\n h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From;\n b=p3eith/KkV7jaGDkzSaBBcSBbmsMwPtU5zcsQn6WNRZPi2oD2zD6GT4oxfS+anxLW\n nziD0ySP8gWLITLGiprGVbNSO3/oIOkgGgtWNJ7ddK5wgvB/OwgzWujWumFRr8yzut\n QI3hplKdqSDpbE6zTy7yPy7kzwjsTCbpIW2Aqk1M=", "From": "Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>", "To": "mst@redhat.com", "Cc": "sgarzare@redhat.com, qemu-devel@nongnu.org, vsementsov@yandex-team.ru,\n d-tatianin@yandex-team.ru, Pierrick Bouvier <pierrick.bouvier@linaro.org>", "Subject": "[PATCH v2 10/10] vhost-user: add VHOST_USER_PROTOCOL_F_GPA_ADDRESSES", "Date": "Mon, 20 Apr 2026 23:20:31 +0300", "Message-ID": "<20260420202032.714884-11-vsementsov@yandex-team.ru>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20260420202032.714884-1-vsementsov@yandex-team.ru>", "References": "<20260420202032.714884-1-vsementsov@yandex-team.ru>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=2a02:6b8:c0e:500:1:45:d181:df01;\n envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.mail.yandex.net", "X-Spam_score_int": "-27", "X-Spam_score": "-2.8", "X-Spam_bar": "--", "X-Spam_report": "(-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001,\n 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": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Unlike the kernel, vhost-user backend knows nothing about QEMU's\nuserspace addresses. We can pass GPA instead and nothing changes.\nGenerally, vhost-user servers need these addresses only to calculate\noffsets inside memory regions. Still, some servers (QEMU's internal\nis one example) may do checks for passed addresses to be \"userspace\naddresses\", for example check for non-zero. That's why we need\nadditional negotiation for the feature.\n\nThe benefit: this opens the doors for further implementation of\nlocal migration (live-update) with passing open vhost-related FDs\nthrough UNIX domain socket. This way the connection with backend is\nkept live and untouched.\n\nWithout this change, we would have to communicate with backend to\ninform it about UVA address changes, but it's better to simply use\nmore stable GPA numbers, which don't change after migration.\n\nAdditionally, the current implementation exposes QEMU's process\naddress space by passing UVA, which breaks ASLR. New protocol\nfeature avoids that.\n\nNote, that we do nothing with backend messages and replies.\nFrontends have to work with backends userspace addresses anyway,\nbecause they come from userfaultfd.\n\nSigned-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>\n---\n docs/interop/vhost-user.rst | 21 +++++++++++++++++----\n hw/virtio/vhost-user.c | 22 +++++++++++++++++-----\n include/hw/virtio/vhost-user.h | 1 +\n 3 files changed, 35 insertions(+), 9 deletions(-)", "diff": "diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst\nindex 137c9f3669d..8dcb030c530 100644\n--- a/docs/interop/vhost-user.rst\n+++ b/docs/interop/vhost-user.rst\n@@ -164,8 +164,16 @@ A vring address description\n \n :log: a 64-bit guest address for logging\n \n-Note that a ring address is an IOVA if ``VIRTIO_F_IOMMU_PLATFORM`` has\n-been negotiated. Otherwise it is a user address.\n+.. Note::\n+ When ``VIRTIO_F_IOMMU_PLATFORM`` is negotiated, ring addresses are IOVAs.\n+\n+ Otherwise, when ``VHOST_USER_PROTOCOL_F_GPA_ADDRESSES`` is negotiated, the\n+ ring addresses are guest physical addresses for frontend messages. That\n+ does not apply to backend replies.\n+\n+ Finally, when neither ``VIRTIO_F_IOMMU_PLATFORM`` nor\n+ ``VHOST_USER_PROTOCOL_F_GPA_ADDRESSES`` features are negotiated, ring\n+ addresses are user virtual addresses.\n \n .. _memory_region_description:\n \n@@ -180,7 +188,9 @@ Memory region description\n \n :size: a 64-bit size\n \n-:user address: a 64-bit user address\n+:user address: a 64-bit user address. When ``VHOST_USER_PROTOCOL_F_GPA_ADDRESSES``\n+ is negotiated, this field contain guest physical address instead and must\n+ duplicate ``guest address`` field.\n \n :mmap offset: a 64-bit offset where region starts in the mapped memory\n \n@@ -252,7 +262,9 @@ An IOTLB message\n \n :size: a 64-bit size\n \n-:user address: a 64-bit user address\n+:user address: a 64-bit user address. When ``VHOST_USER_PROTOCOL_F_GPA_ADDRESSES``\n+ is negotiated, this field contain guest physical address instead, except for\n+ ``VHOST_USER_BACKEND_IOTLB_MSG``, where it's user address anyway.\n \n :permissions flags: an 8-bit value:\n - 0: No access\n@@ -1063,6 +1075,7 @@ Protocol features\n #define VHOST_USER_PROTOCOL_F_SHARED_OBJECT 18\n #define VHOST_USER_PROTOCOL_F_DEVICE_STATE 19\n #define VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT 20\n+ #define VHOST_USER_PROTOCOL_F_GPA_ADDRESSES 21\n \n Front-end message types\n -----------------------\ndiff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c\nindex 78ffb25d6b1..15042c0f3c2 100644\n--- a/hw/virtio/vhost-user.c\n+++ b/hw/virtio/vhost-user.c\n@@ -563,12 +563,22 @@ static MemoryRegion *vhost_user_get_mr_data(uint64_t addr, ram_addr_t *offset,\n return mr;\n }\n \n-static void vhost_user_fill_msg_region(VhostUserMemoryRegion *dst,\n+static bool vhost_user_gpa_addresses(struct vhost_dev *dev)\n+{\n+ return vhost_user_has_protocol_feature(\n+ dev, VHOST_USER_PROTOCOL_F_GPA_ADDRESSES);\n+}\n+\n+static void vhost_user_fill_msg_region(struct vhost_dev *dev,\n+ VhostUserMemoryRegion *dst,\n struct vhost_memory_region *src,\n uint64_t mmap_offset)\n {\n+ bool use_phys = vhost_user_gpa_addresses(dev);\n+\n assert(src != NULL && dst != NULL);\n- dst->userspace_addr = src->userspace_addr;\n+\n+ dst->userspace_addr = use_phys ? src->guest_phys_addr : src->userspace_addr;\n dst->memory_size = src->memory_size;\n dst->guest_phys_addr = src->guest_phys_addr;\n dst->mmap_offset = mmap_offset;\n@@ -606,7 +616,7 @@ static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u,\n error_report(\"Failed preparing vhost-user memory table msg\");\n return -ENOBUFS;\n }\n- vhost_user_fill_msg_region(®ion_buffer, reg, offset);\n+ vhost_user_fill_msg_region(dev, ®ion_buffer, reg, offset);\n msg->payload.memory.regions[*fd_num] = region_buffer;\n fds[(*fd_num)++] = fd;\n } else if (track_ramblocks) {\n@@ -752,7 +762,7 @@ static int send_remove_regions(struct vhost_dev *dev,\n \n if (fd > 0) {\n msg->hdr.request = VHOST_USER_REM_MEM_REG;\n- vhost_user_fill_msg_region(®ion_buffer, shadow_reg, 0);\n+ vhost_user_fill_msg_region(dev, ®ion_buffer, shadow_reg, 0);\n msg->payload.mem_reg.region = region_buffer;\n \n ret = vhost_user_write(dev, msg, NULL, 0);\n@@ -813,7 +823,7 @@ static int send_add_regions(struct vhost_dev *dev,\n u->region_rb[reg_idx] = mr->ram_block;\n }\n msg->hdr.request = VHOST_USER_ADD_MEM_REG;\n- vhost_user_fill_msg_region(®ion_buffer, reg, offset);\n+ vhost_user_fill_msg_region(dev, ®ion_buffer, reg, offset);\n msg->payload.mem_reg.region = region_buffer;\n \n ret = vhost_user_write(dev, msg, &fd, 1);\n@@ -3151,4 +3161,6 @@ const VhostOps user_ops = {\n .vhost_supports_device_state = vhost_user_supports_device_state,\n .vhost_set_device_state_fd = vhost_user_set_device_state_fd,\n .vhost_check_device_state = vhost_user_check_device_state,\n+ .vhost_phys_vring_addr = vhost_user_gpa_addresses,\n+ .vhost_phys_iotlb_msg = vhost_user_gpa_addresses,\n };\ndiff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h\nindex 0e576fc5386..5ab70dab7e4 100644\n--- a/include/hw/virtio/vhost-user.h\n+++ b/include/hw/virtio/vhost-user.h\n@@ -34,6 +34,7 @@ enum VhostUserProtocolFeature {\n VHOST_USER_PROTOCOL_F_SHARED_OBJECT = 18,\n VHOST_USER_PROTOCOL_F_DEVICE_STATE = 19,\n VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT = 20,\n+ VHOST_USER_PROTOCOL_F_GPA_ADDRESSES = 21,\n VHOST_USER_PROTOCOL_F_MAX\n };\n \n", "prefixes": [ "v2", "10/10" ] }