Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2194498/?format=api
{ "id": 2194498, "url": "http://patchwork.ozlabs.org/api/patches/2194498/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260209073908.2125178-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": "<20260209073908.2125178-11-vsementsov@yandex-team.ru>", "list_archive_url": null, "date": "2026-02-09T07:39:07", "name": "[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/20260209073908.2125178-11-vsementsov@yandex-team.ru/mbox/", "series": [ { "id": 491471, "url": "http://patchwork.ozlabs.org/api/series/491471/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=491471", "date": "2026-02-09T07:38:57", "name": "vhost-user: VHOST_USER_PROTOCOL_F_GPA_ADDRESSES", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/491471/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2194498/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2194498/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=EHIs9MA8;\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=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)", "mail-nwsmtp-smtp-corp-main-56.klg.yp-c.yandex.net;\n dkim=pass header.i=@yandex-team.ru" ], "Received": [ "from lists.gnu.org (lists.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 4f8c7d2wDNz1xtr\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 09 Feb 2026 18:41:01 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vpLrv-0000rs-Ba; Mon, 09 Feb 2026 02:39:39 -0500", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.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 1vpLri-0000nD-Rb\n for qemu-devel@nongnu.org; Mon, 09 Feb 2026 02:39:27 -0500", "from forwardcorp1d.mail.yandex.net ([178.154.239.200])\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 1vpLrg-0004gV-G4\n for qemu-devel@nongnu.org; Mon, 09 Feb 2026 02:39:26 -0500", "from mail-nwsmtp-smtp-corp-main-56.klg.yp-c.yandex.net\n (mail-nwsmtp-smtp-corp-main-56.klg.yp-c.yandex.net\n [IPv6:2a02:6b8:c42:65a0:0:640:e1de:0])\n by forwardcorp1d.mail.yandex.net (Yandex) with ESMTPS id 7F2538083A;\n Mon, 09 Feb 2026 10:39:19 +0300 (MSK)", "from vsementsov-lin (unknown [2a02:6bf:8080:129::1:13])\n by mail-nwsmtp-smtp-corp-main-56.klg.yp-c.yandex.net (smtpcorp/Yandex) with\n ESMTPSA id BdLXu72As8c0-g7lEMdI3; Mon, 09 Feb 2026 10:39:18 +0300" ], "X-Yandex-Fwd": "1", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru;\n s=default; t=1770622758;\n bh=XAmPKftnRzjPjPUy+fdcodUISY/Fbko68AsWLmE4fYk=;\n h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From;\n b=EHIs9MA8iMb3Momd9y0Vdz1JbVENzw5hmeWdqtY44f5Qu5w/WgfqoTf3ek3Jbp3aW\n MLKr4BAeFU3hbtO9/3lCDtn0Ep2jy/wRIb4vzBceqcuGTs05PPjZYTuHDNPIXL771Q\n sDna7Xd24/Zg0Vv3703c+Zbq9v0DUILKhYoQwKQE=", "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 10/10] vhost-user: add VHOST_USER_PROTOCOL_F_GPA_ADDRESSES", "Date": "Mon, 9 Feb 2026 10:39:07 +0300", "Message-ID": "<20260209073908.2125178-11-vsementsov@yandex-team.ru>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20260209073908.2125178-1-vsementsov@yandex-team.ru>", "References": "<20260209073908.2125178-1-vsementsov@yandex-team.ru>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=178.154.239.200;\n envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1d.mail.yandex.net", "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, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n 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": "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 137c9f3669..8dcb030c53 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 2e58f38ac5..125b170c5b 100644\n--- a/hw/virtio/vhost-user.c\n+++ b/hw/virtio/vhost-user.c\n@@ -568,12 +568,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@@ -611,7 +621,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@@ -757,7 +767,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@@ -818,7 +828,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@@ -3154,4 +3164,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 0e576fc538..5ab70dab7e 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": [ "10/10" ] }