From nobody Sat Jul 4 21:06:17 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1782730153; cv=none; d=zohomail.com; s=zohoarc; b=EASM2kKLr5fb7FZCbnsdiCbiTdEg4krnsxG0HRLyHIDkFm2v2pb7CbuNtusHbQ3PwDFAitqzsP9AGfboSFy2vfhNV5DsaJufWFT+O9njXVBPt2k3yJ5B/QRpmbDMMQCOQndM9YtDoyQ4nem02gUKxcC/AJa+U9ZdT8D8qfdcUU4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782730153; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bwvkO6znXhIa5qM7wiZu9yQsBOrMOtM8ilQjUKeprio=; b=LiNF+DSudrXODMTHBcnWv0eKXMwwqGpwkeri4EfsfEpLx3SOJ0HTBge2uusj/Rm8YdgC/klurKhx8yC2pHkvZ+QDKda9B7/gzNg7jBmEeU0FM6jWKvLpXqIyRsY+6QVTT/0B1SagjQdGHLVG4/4I6VrDKAbPgpvmXErc3//u/lc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1782730153275579.1360546082911; Mon, 29 Jun 2026 03:49:13 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1347468.1605311 (Exim 4.92) (envelope-from ) id 1we9Xc-0005Qz-Dl; Mon, 29 Jun 2026 10:48:40 +0000 Received: by outflank-mailman (output) from mailman id 1347468.1605311; Mon, 29 Jun 2026 10:48:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1we9Xc-0005Qs-AN; Mon, 29 Jun 2026 10:48:40 +0000 Received: by outflank-mailman (input) for mailman id 1347468; Mon, 29 Jun 2026 10:48:39 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1we9Xa-0005Qb-V6 for xen-devel@lists.xenproject.org; Mon, 29 Jun 2026 10:48:39 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1we9Xa-00HDHB-3H for xen-devel@lists.xenproject.org; Mon, 29 Jun 2026 12:48:38 +0200 Received: from [10.42.69.7] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a424d84-bab6-0a2a0a5309dd-0a2a4507b498-10 for ; Mon, 29 Jun 2026 12:48:38 +0200 Received: from [209.85.221.47] (helo=mail-wr1-f47.google.com) by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a424d85-9c8e-0a2a45070019-d155dd2fe96e-3 for ; Mon, 29 Jun 2026 12:48:37 +0200 Received: by mail-wr1-f47.google.com with SMTP id ffacd0b85a97d-4704d652e9cso1190428f8f.3 for ; Mon, 29 Jun 2026 03:48:37 -0700 (PDT) Received: from RTRKN1313-LIN.domain.local (cable-89-216-248-190.dynamic.sbb.rs. [89.216.248.190]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-46cf775a4f0sm39691675f8f.17.2026.06.29.03.48.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jun 2026 03:48:37 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Cc:To:In-Reply-To:References:Message-Id:Content-Transfer-Encoding:MIME-Version:Subject:Date:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782730117; x=1783334917; darn=lists.xenproject.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=bwvkO6znXhIa5qM7wiZu9yQsBOrMOtM8ilQjUKeprio=; b=mV7T5+VUwpfK1XCTdtd+iG4OvHu2n9RWi7rFl01EKALpHDhNIxGfBElU4v5UHPTqgn rQBIMdVSnDN8q3emVY7zLaaYLebhEPfUImbq+gCmNfisz1xuJ6CCrpN8h37+3QKcLNRC Zpgz1xaFdCARAZYQ4WmRaE3QtV7I4vbfp4ghMh4Z5u3vlLl4fkUADl55h/FpRqX6kiWs BG60nUtL6aHBiZxEQxDmP5FZM2oAQt6ZMyrcOz7d2JTj4Dcd+uMtloaC6W4pSvKgXBlj rzhDfasHa7TcJphOasU/ofbTTIjQ70qWdsWeFOZEzR0gi2gkIYaz4oAjg1lqIo2CEWF2 LOpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782730117; x=1783334917; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=bwvkO6znXhIa5qM7wiZu9yQsBOrMOtM8ilQjUKeprio=; b=CDe6Cn+ZlCj4k9YtR+BeTzDyFhN4dhaG38zuyT+/MLq7zOV/HV06TqsfMCxHMJDr4/ 2wWaZHKNouYy6nVp5IieEbecwDsmk8DqWCiVXphRIbARl61V0AxJ9SFBX860NqWy37Mh NdlTdZw1KvUnvDplPglGNPXeNbF/Ze7i+SNMmtMUF/PFnxVd3+zvkvgZpgh5yira/P+F Ry7YNDkVYoo9jq2J/j1Q+Hj+jglHXdiiWcXSKA6CaBMN6XywnWNVveFIGBJXnyd5GRtX 3fTiIPvdKIb5McPZbbd6imOUa1kdmZhbMjUXAPt9PAJjyT1ad8Wx4NzE8TV1OgNqIqFP XhSA== X-Forwarded-Encrypted: i=1; AHgh+RoU0X4VNdrl1bWiP8lS/90Rc05O1PvfKT5mXpf3n9Taz0YEtbVMRrnJQUhNaWInCy8EWWgz5lTg/iQ=@lists.xenproject.org X-Gm-Message-State: AOJu0Yxit913t+bHgPwSIb6xdGg4yTc8QNHnXuZRAlzC9JXG17rwASx6 IzZF1z2+ZRy69dJXLLeiFS0m0wF37RFLClqz0b1hynqOuNGpIyinn4oj X-Gm-Gg: AfdE7cnDk4Yka6yGfJvLMJfpi4ojKRtqr0iE+ULnIAvrjNMFK6yhODwN5kstNrZxpuF JngznfRVLgv7s8PDzcbTiURBG9ahrn2CW9GqRNycHCbNVsRDisofZ3sPJd1BYN2HAGX57PQ7/po 0UrUdde2ED4xEB0yNd9W3xtFXgUVVdevCybr5ZBhR/7NrjXuSz+7bl6qVMuhQKKkqyHFRqwr3uN 6vlsYAHrsYwTHVGcTGi7O/fUbZOFZIm85Ctv9SIJ0Kwwh/k5vRdNZU+NP6eNvaQEx26bWI0i8qu 8rsJ9JaDj61f+m7xXAKlDynododfIwFAqnVL6EPO49wR2HkBdEemA61KRpAz7ekDbevf4QYniN0 RDugjB0d5O+djKLGDgVtdByGVqjq1zohZxX68CoPVCKsjrQLZThmfDe14+KytNHn86cCiHTIWJE 30KJrg8k3RtDWVofSh6U81hodvqw8W13KZW2kKy08chDjwohYSp7YhqQrShLKUZKw7AqVp/3d5K m+mX3pQ4vsKlWaTqtt1 X-Received: by 2002:a05:6000:18a3:b0:473:975c:4fd1 with SMTP id ffacd0b85a97d-473975c51admr5618332f8f.25.1782730117239; Mon, 29 Jun 2026 03:48:37 -0700 (PDT) From: Dusan Stojkovic Date: Mon, 29 Jun 2026 12:46:25 +0200 Subject: [PATCH RFC v2 1/2] vhost: accept Xen guest RAM sections for vhost-user MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260629-vhost-xen-foreign-mapping-v2-1-19e4685e7575@rt-rk.com> References: <20260629-vhost-xen-foreign-mapping-v2-0-19e4685e7575@rt-rk.com> In-Reply-To: <20260629-vhost-xen-foreign-mapping-v2-0-19e4685e7575@rt-rk.com> To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Stefano Garzarella , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , xen-devel@lists.xenproject.org, Viresh Kumar , Dusan Stojkovic , Nikola Jelic X-Mailer: b4 0.13.0 X-purgate-ID: tlsNG-ef75cf/1782730118-FEB3B25E-1710D2AD/0/0 X-purgate-type: clean X-purgate-size: 3356 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1782730154312158500 From: Dusan Stojkovic When QEMU runs as a Xen device model, the guest's RAM is not allocated by QEMU and is not backed by a file descriptor that could be shared with a vhost-user backend: accesses from QEMU go through the Xen mapcache and memory_region_get_fd() returns -1. vhost_section() therefore filters out every RAM section, the vhost memory listener registers no regions, and starting any vhost-user device fails with "Failed initializing vhost-user memory map". With VHOST_USER_PROTOCOL_F_XEN_MMAP the backend does not need an fd or a process-local mapping it maps guest memory itself through the Xen foreign mapping interface, using the guest physical address and domain id. Accept the Xen RAM region in vhost_section() so that it reaches the backend's memory table. The Xen grant region (xen.grants) must never be accepted: grant references can only be mapped individually on demand via address_space_map(), and deriving a host pointer for the whole region, as vhost_region_add_section() does, aborts in the Xen mapcache. Note that xen_mr_is_memory() returns true for both the RAM and the grants region, so the grants region is excluded explicitly. Because of the necessity to exlude xen.grants, the missing stub for xen_mr_is_grants is added so that it can be called from common code. Signed-off-by: Dusan Stojkovic Signed-off-by: Nikola Jelic Reviewed-by: Stefano Stabellini --- hw/virtio/vhost.c | 18 ++++++++++++++++++ hw/xen/xen_stubs.c | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index af41841b52..26770d06d5 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -29,6 +29,7 @@ #include "system/dma.h" #include "system/memory.h" #include "system/ramblock.h" +#include "system/xen.h" #include "trace.h" =20 /* enabled until disconnected backend stabilizes */ @@ -657,6 +658,23 @@ static bool vhost_section(struct vhost_dev *dev, Memor= yRegionSection *section) return false; } =20 + /* + * Under Xen, the guest's RAM is not backed by an fd that + * be passed to a vhost-user backend. The backend instead + * guest memory through the Xen foreign mapping interface, + * by guest physical address and domain id (see + * VHOST_USER_PROTOCOL_F_XEN_MMAP), so accept the Xen RAM + * region even though it has no fd. + */ + if (xen_enabled()) { + if (xen_mr_is_memory(mr) && !xen_mr_is_grants(mr)) { + trace_vhost_section(mr->name); + return true; + } + trace_vhost_reject_section(mr->name, 4); + return false; + } + /* * Some backends (like vhost-user) can only handle memory regions * that have an fd (can be mapped into a different process). Filter diff --git a/hw/xen/xen_stubs.c b/hw/xen/xen_stubs.c index f830768d99..7af39bceb0 100644 --- a/hw/xen/xen_stubs.c +++ b/hw/xen/xen_stubs.c @@ -29,6 +29,11 @@ bool xen_mr_is_memory(const MemoryRegion *mr) g_assert_not_reached(); } =20 +bool xen_mr_is_grants(const MemoryRegion *mr) +{ + g_assert_not_reached(); +} + bool xen_map_cache_enabled(void) { return false; --=20 2.43.0 From nobody Sat Jul 4 21:06:17 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1782730153; cv=none; d=zohomail.com; s=zohoarc; b=ZDYJyCev2KqTFteyDGCJ2sW5KHOcOzATwneqCTJDnAFG5JkOlV/o6V4jReYzTwzNvF2ZRtd4s1XWBMwNpvjf578TIpPFkYRt9rSV6qCf7qD1grsWx/fkF3L/6FwzN/YUQ01wZ3ln3gbxWCRxoYrGON+iPFEprFpTbBCSmCw/m68= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782730153; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ylBpQ0bt/QK9zQ9BEMnv21TmNMn+xhUv/pb6/Do4RGs=; b=A3CB+kSdaex/5Zydp9tngrSMU2YKwkuYbz3Pe+ZMrdi24goL4Gsk0RLwy8NB21KLiFnslxeiEvQkCoxf/my1eFbPw1APDiUvI68U5J1O7hV+cpG6uU8/Ao8UI9x2L5g+c1/EuyDs4uSFYBTrs0yfv3VJxdMOWl9whpWTkYvFUZQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 178273015319347.98319681571252; Mon, 29 Jun 2026 03:49:13 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1347470.1605330 (Exim 4.92) (envelope-from ) id 1we9Xd-0005qT-Up; Mon, 29 Jun 2026 10:48:41 +0000 Received: by outflank-mailman (output) from mailman id 1347470.1605330; Mon, 29 Jun 2026 10:48:41 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1we9Xd-0005qM-Rb; Mon, 29 Jun 2026 10:48:41 +0000 Received: by outflank-mailman (input) for mailman id 1347470; Mon, 29 Jun 2026 10:48:40 +0000 Received: from mx.expurgate.net ([194.145.224.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1we9Xc-0005Qr-9T for xen-devel@lists.xenproject.org; Mon, 29 Jun 2026 10:48:40 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1we9Xb-00DYiu-8O for xen-devel@lists.xenproject.org; Mon, 29 Jun 2026 12:48:39 +0200 Received: from [10.42.69.3] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a424d86-e002-0a2a0a5209dd-0a2a4503e58a-6 for ; Mon, 29 Jun 2026 12:48:39 +0200 Received: from [209.85.221.49] (helo=mail-wr1-f49.google.com) by tlsNG-33051d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a424d87-ec1a-0a2a45030019-d155dd31d4bb-3 for ; Mon, 29 Jun 2026 12:48:39 +0200 Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-474303f3c72so378690f8f.0 for ; Mon, 29 Jun 2026 03:48:39 -0700 (PDT) Received: from RTRKN1313-LIN.domain.local (cable-89-216-248-190.dynamic.sbb.rs. [89.216.248.190]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-46cf775a4f0sm39691675f8f.17.2026.06.29.03.48.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jun 2026 03:48:38 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Cc:To:In-Reply-To:References:Message-Id:Content-Transfer-Encoding:MIME-Version:Subject:Date:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782730119; x=1783334919; darn=lists.xenproject.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ylBpQ0bt/QK9zQ9BEMnv21TmNMn+xhUv/pb6/Do4RGs=; b=sFKmMOcKm2byX3byPfNh0Jxl3I4lW+57m4xtEkszmCdHSPugQm7PYGAmg9YHezehKX ktAT4oF+PjITsWdoxnRZ/zH2htcwddHuI5mXHoWT8rK4vLkq9nL8TmExq1bi1lrbgk/K Rrv3/UBFTSjFlX5fMIcM2lS56L509uduOF1MQ03ppJCibYmJdYzi2ZUAu78Pk34G2W7J r0GGbCDc8TQKyYZ000bhed0nPA9PH+ofnM7aDTLg7wuDZnsalft+ucdlYDfwTiXgQr5/ yc4v16WXd4iyO4qxiUvZYBdE6JJ2ekLdkaFvjFwHN7wR/8HVvbpE6aOrCbMiZqkQ8wZa Wl3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782730119; x=1783334919; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ylBpQ0bt/QK9zQ9BEMnv21TmNMn+xhUv/pb6/Do4RGs=; b=p2zo3MPZrcYeVneRUpotv9r06BHeljyOZFbKjvyqQXRBzna1w28v2Xyqd4w8oFAq1E 1qnf/N2iZiJDRrEJxQAOEXRXxy1owhcD8B7YZBuO9RgUx8nH61uU7DLM2eqd409XDQR1 ryaCsl5O1SFG+Kj9Ah64z9hFE3LOvs5SKM+Fo0Hdpe5nub5NBtdwtRv23OHPbUBosEr4 rmo9JAnAZfT314Pol4/qMzgRvz9v3hAVgJE39zRsQk9mtfdpNNBQDzkfF9xQX2zfKW9X Q8WXo4q5ejHj02dkqOTA2cOSz0TV4Jasxb3AyYSSAlEz6kMrwigxt7sBK5hKlvwewKLH mu9w== X-Forwarded-Encrypted: i=1; AHgh+RoUH18BVk4ZBDu+3p/vqFUQxh71yCXK99KGrJsHUof51yT5q2boecegHmTOxApAPgFTYPmRID2PO0I=@lists.xenproject.org X-Gm-Message-State: AOJu0YxTYvfTF3U/iQhuDli75KXSgkgxoESXLKUwFQC4q8H84yB00DhQ MCD09uwX+2Il3HBUeowPbrvGRDSWBsUneHPq2vWiDEzf7srKV9/Pwxu6 X-Gm-Gg: AfdE7cl/M/U1suYzq/nRgc+yVFs1wS0NiHlnPSw9NGCBi2mfv+lvXQTiXshJHBlH9Rv PwwAgG2ajIuQSEcE5glrhAM/FeQ3Ii0t02C1LpHhZT/L3xdgB5pxIolo2jDqtKB0gzHOSkGFqps S3M4Jt51nDAeA/RqL7Tu6aPldZCFiPf+CnwaW7h+eECCe4ONkdEe9u/KxILMCa+q3c14eskqQiS sNR3qQA3kU3Iq5FU7V3sevEZyROYubHv49UHnYaNuqzSdI6MgSC/kZi9vpalaCft1NQowkTl7oI 1YG2r9fYhG6t/zekHUm4I4Sd14GRTl06XpqcYipMnvhumSejj7/Q6Kbx48oBcdf4We0xjzcn0Yj mJdS40/AGhiXXWeedv06Ywd/7r1aqez2hGy0VfRTMssZ69oEJy8hztpTDYAA3hoQwc1/zTNXdfL CggtAbonc/vt38jywyo7jmLKzi10Gssm5P/JUyppKW9gRGmr0WLd6IzEhfxzs6ZF2lrg4ks29Xz pSRzrDNpQ== X-Received: by 2002:a05:6000:290d:b0:472:6602:3347 with SMTP id ffacd0b85a97d-47266023809mr9813909f8f.43.1782730118404; Mon, 29 Jun 2026 03:48:38 -0700 (PDT) From: Dusan Stojkovic Date: Mon, 29 Jun 2026 12:46:26 +0200 Subject: [PATCH RFC v2 2/2] vhost-user: implement VHOST_USER_PROTOCOL_F_XEN_MMAP MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260629-vhost-xen-foreign-mapping-v2-2-19e4685e7575@rt-rk.com> References: <20260629-vhost-xen-foreign-mapping-v2-0-19e4685e7575@rt-rk.com> In-Reply-To: <20260629-vhost-xen-foreign-mapping-v2-0-19e4685e7575@rt-rk.com> To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Stefano Garzarella , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" , xen-devel@lists.xenproject.org, Viresh Kumar , Dusan Stojkovic , Nikola Jelic X-Mailer: b4 0.13.0 X-purgate-ID: tlsNG-33051d/1782730119-BCF835D1-B00FCFC4/0/0 X-purgate-type: clean X-purgate-size: 12093 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1782730154407158500 From: Dusan Stojkovic The vhost-user specification reserves protocol feature bit 17 and documents an extended memory region description for backends that map guest memory through Xen rather than mapping a file descriptor each region carries two extra fields, "xen mmap flags" and "domid" (see docs/interop/vhost-user.rst, "Memory region description"). The layout is implemented by rust-vmm's vhost and vm-memory crates and used by Xen vhost-user device backends. Implement the front-end side for foreign mappings: - negotiate VHOST_USER_PROTOCOL_F_XEN_MMAP - when negotiated, build SET_MEM_TABLE payloads from the extended region layout, with xen_mmap_flags =3D FOREIGN and xen_mmap_data set to the guest's domain id. - under Xen, do not call vhost_user_get_mr_data(): guest RAM has no fd and its userspace_addr does not correspond to a valid mapping in the address space. Backends map regions through privcmd using the guest physical address and domid; the fd accompanying each region only satisfies the protocol's one-fd-per-region requirement. Pass a /dev/xen/privcmd fd and close it once the message has been sent. Tracepoints for opening and closing xen fds are added as well. - suppress VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS under Xen: Postcopy is likewise refused. The userspace_addr field is carried unchanged; Xen backends derive mappings from guest_phys_addr and domid and do not interpret it. Signed-off-by: Dusan Stojkovic Signed-off-by: Nikola Jelic --- hw/virtio/trace-events | 2 + hw/virtio/vhost-user.c | 120 +++++++++++++++++++++++++++++++++++++= ++-- include/hw/virtio/vhost-user.h | 2 +- 3 files changed, 120 insertions(+), 4 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 2a57edc21e..0f3c58fd78 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -30,6 +30,8 @@ vhost_user_postcopy_fault_handler_found(int i, uint64_t r= egion_offset, uint64_t vhost_user_postcopy_listen(void) "" vhost_user_set_mem_table_postcopy(uint64_t client_addr, uint64_t qhva, int= reply_i, int region_i) "client:0x%"PRIx64" for hva: 0x%"PRIx64" reply %d r= egion %d" vhost_user_set_mem_table_withfd(int index, const char *name, uint64_t memo= ry_size, uint64_t guest_phys_addr, uint64_t userspace_addr, uint64_t offset= ) "%d:%s: size:0x%"PRIx64" GPA:0x%"PRIx64" QVA/userspace:0x%"PRIx64" RB off= set:0x%"PRIx64 +vhost_user_open_region_fd(int index, int fd) "region:%d fd:%d" +vhost_user_put_region_fds(int index, int fd) "region:%d fd:%d" vhost_user_postcopy_waker(const char *rb, uint64_t rb_offset) "%s + 0x%"PR= Ix64 vhost_user_postcopy_waker_found(uint64_t client_addr) "0x%"PRIx64 vhost_user_postcopy_waker_nomatch(const char *rb, uint64_t rb_offset) "%s = + 0x%"PRIx64 diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index d627351f45..932ead4eeb 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -30,6 +30,8 @@ #include "migration/postcopy-ram.h" #include "trace.h" #include "system/ramblock.h" +#include "system/xen.h" +#include "hw/xen/xen.h" =20 #include #include @@ -181,12 +183,36 @@ typedef struct VhostUserMemoryRegion { uint64_t mmap_offset; } VhostUserMemoryRegion; =20 +/* + * Memory region flags for VHOST_USER_PROTOCOL_F_XEN_MMAP, matching the + * values used by rust-vmm's vm-memory (MmapXenFlags). + */ +#define VHOST_USER_XEN_MMAP_FLAG_FOREIGN 0x1 +#define VHOST_USER_XEN_MMAP_FLAG_GRANT 0x2 + +/* + * Extended memory region description, used when + * VHOST_USER_PROTOCOL_F_XEN_MMAP has been negotiated. + */ +typedef struct VhostUserMemoryRegionXen { + VhostUserMemoryRegion region; + uint32_t xen_mmap_flags; + uint32_t xen_mmap_data; /* domain id for FOREIGN/GRANT mappings */ +} VhostUserMemoryRegionXen; + + typedef struct VhostUserMemory { uint32_t nregions; uint32_t padding; VhostUserMemoryRegion regions[VHOST_MEMORY_BASELINE_NREGIONS]; } VhostUserMemory; =20 +typedef struct VhostUserMemoryXen { + uint32_t nregions; + uint32_t padding; + VhostUserMemoryRegionXen regions[VHOST_MEMORY_BASELINE_NREGIONS]; +} VhostUserMemoryXen; + typedef struct VhostUserMemRegMsg { uint64_t padding; VhostUserMemoryRegion region; @@ -294,6 +320,7 @@ typedef union { struct vhost_vring_state state; struct vhost_vring_addr addr; VhostUserMemory memory; + VhostUserMemoryXen memory_xen; VhostUserMemRegMsg mem_reg; VhostUserLog log; struct vhost_iotlb_msg iotlb; @@ -594,6 +621,8 @@ static MemoryRegion *vhost_user_get_mr_data(uint64_t ad= dr, ram_addr_t *offset, static bool vhost_user_gpa_addresses(struct vhost_dev *dev) { return vhost_user_has_protocol_feature( + dev, VHOST_USER_PROTOCOL_F_XEN_MMAP) || + vhost_user_has_protocol_feature( dev, VHOST_USER_PROTOCOL_F_GPA_ADDRESSES); } =20 @@ -612,6 +641,23 @@ static void vhost_user_fill_msg_region(struct vhost_de= v *dev, dst->mmap_offset =3D mmap_offset; } =20 +/* + * With VHOST_USER_PROTOCOL_F_XEN_MMAP the region fds are opened by us + * rather than owned by the RAMBlocks, so they must be closed once the + * message carrying them has been sent (or on error). + */ +static void vhost_user_put_region_fds(struct vhost_dev *dev, int *fds, + size_t fd_num) +{ + if (!vhost_user_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_XEN_MM= AP)) { + return; + } + for (size_t i =3D 0; i < fd_num; i++) { + trace_vhost_user_put_region_fds(i, fds[i]); + close(fds[i]); + } +} + static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u, struct vhost_dev *dev, VhostUserMsg *msg, @@ -623,13 +669,41 @@ static int vhost_user_fill_set_mem_table_msg(struct v= host_user *u, MemoryRegion *mr; struct vhost_memory_region *reg; VhostUserMemoryRegion region_buffer; + bool xen_mmap =3D vhost_user_has_protocol_feature(dev, + VHOST_USER_PROTOCOL_F_XEN_MMAP); + + if (track_ramblocks && xen_mmap) { + error_report("vhost-user: postcopy is not supported under Xen"); + return -ENOTSUP; + } =20 msg->hdr.request =3D VHOST_USER_SET_MEM_TABLE; =20 for (i =3D 0; i < dev->mem->nregions; ++i) { reg =3D dev->mem->regions + i; =20 - mr =3D vhost_user_get_mr_data(reg->userspace_addr, &offset, &fd); + if (xen_mmap) { + /* + * Under Xen the guest RAM is not mapped into our address + * space; the backend maps it through the Xen foreign + * mapping interface using the guest physical address and + * domain id carried in the region descriptor. The file + * descriptor only satisfies the one-fd-per-region + * requirement of the protocol: pass /dev/xen/privcmd and + * close it once the message has been sent. + */ + mr =3D NULL; + offset =3D 0; + fd =3D open("/dev/xen/privcmd", O_RDWR | O_CLOEXEC); + if (fd < 0) { + error_report("vhost-user: failed to open /dev/xen/privcmd:" + " %s", strerror(errno)); + return -errno; + } + trace_vhost_user_open_region_fd(i, fd); + } else { + mr =3D vhost_user_get_mr_data(reg->userspace_addr, &offset, &f= d); + } if (fd > 0) { if (track_ramblocks) { assert(*fd_num < VHOST_MEMORY_BASELINE_NREGIONS); @@ -642,10 +716,21 @@ static int vhost_user_fill_set_mem_table_msg(struct v= host_user *u, u->region_rb[i] =3D mr->ram_block; } else if (*fd_num =3D=3D VHOST_MEMORY_BASELINE_NREGIONS) { error_report("Failed preparing vhost-user memory table msg= "); + if (xen_mmap) { + close(fd); + } return -ENOBUFS; } vhost_user_fill_msg_region(dev, ®ion_buffer, reg, offset); - msg->payload.memory.regions[*fd_num] =3D region_buffer; + if (xen_mmap) { + msg->payload.memory_xen.regions[*fd_num].region =3D region= _buffer; + msg->payload.memory_xen.regions[*fd_num].xen_mmap_flags = =3D + VHOST_USER_XEN_MMAP_FLAG_FOREIGN; + msg->payload.memory_xen.regions[*fd_num].xen_mmap_data =3D + xen_domid; + } else { + msg->payload.memory.regions[*fd_num] =3D region_buffer; + } fds[(*fd_num)++] =3D fd; } else if (track_ramblocks) { u->region_rb_offset[i] =3D 0; @@ -663,7 +748,11 @@ static int vhost_user_fill_set_mem_table_msg(struct vh= ost_user *u, =20 msg->hdr.size =3D sizeof(msg->payload.memory.nregions); msg->hdr.size +=3D sizeof(msg->payload.memory.padding); - msg->hdr.size +=3D *fd_num * sizeof(VhostUserMemoryRegion); + if (xen_mmap) { + msg->hdr.size +=3D *fd_num * sizeof(VhostUserMemoryRegionXen); + } else { + msg->hdr.size +=3D *fd_num * sizeof(VhostUserMemoryRegion); + } =20 return 0; } @@ -1149,10 +1238,12 @@ static int vhost_user_set_mem_table(struct vhost_de= v *dev, ret =3D vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_n= um, false); if (ret < 0) { + vhost_user_put_region_fds(dev, fds, fd_num); return ret; } =20 ret =3D vhost_user_write(dev, &msg, fds, fd_num); + vhost_user_put_region_fds(dev, fds, fd_num); if (ret < 0) { return ret; } @@ -2551,6 +2642,29 @@ static int vhost_user_backend_init(struct vhost_dev = *dev, void *opaque, VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIG= HT); } =20 + if (!xen_enabled()) { + /* + * Xen memory mappings only make sense when QEMU itself runs + * as a Xen device model. + */ + protocol_features &=3D ~(1ULL << VHOST_USER_PROTOCOL_F_XEN_MMA= P); + } else { + if (!virtio_has_feature(protocol_features, + VHOST_USER_PROTOCOL_F_XEN_MMAP)) { + error_setg(errp, "vhost-user backend does not support " + "VHOST_USER_PROTOCOL_F_XEN_MMAP, which is " + "required when running under Xen"); + return -EPROTO; + } + /* + * The ADD/REM_MEM_REG message path has not been adapted to + * the Xen region format. Xen guests expose a single RAM + * region, so fall back to SET_MEM_TABLE. + */ + protocol_features &=3D + ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS); + } + /* final set of protocol features */ u->protocol_features =3D protocol_features; err =3D vhost_user_set_protocol_features(dev, u->protocol_features= ); diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h index 06c360af18..46be9cd57c 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -30,7 +30,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS =3D 14, VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS =3D 15, VHOST_USER_PROTOCOL_F_STATUS =3D 16, - /* Feature 17 reserved for VHOST_USER_PROTOCOL_F_XEN_MMAP. */ + VHOST_USER_PROTOCOL_F_XEN_MMAP =3D 17, VHOST_USER_PROTOCOL_F_SHARED_OBJECT =3D 18, VHOST_USER_PROTOCOL_F_DEVICE_STATE =3D 19, VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT =3D 20, --=20 2.43.0