From: Hanna Czenczek <hreitz@redhat.com>
To: Connor Kite <connorkite@gmail.com>, qemu-devel@nongnu.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
"Stefano Garzarella" <sgarzare@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Viresh Kumar" <viresh.kumar@linaro.org>,
"Gerd Hoffmann" <kraxel@redhat.com>,
"Mathieu Poirier" <mathieu.poirier@linaro.org>,
"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Raphael Norwitz" <rnorwitz@nvidia.com>,
"Kevin Wolf" <kwolf@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Fam Zheng" <fam@euphon.net>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Milan Zamazal" <mzamazal@redhat.com>,
"Akihiko Odaki" <odaki@rsg.ci.i.u-tokyo.ac.jp>,
"Dmitry Osipenko" <dmitry.osipenko@collabora.com>,
qemu-block@nongnu.org, virtio-fs@lists.linux.dev,
"Gonglei (Arei)" <arei.gonglei@huawei.com>,
"zhenwei pi" <zhenwei.pi@linux.dev>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Eric Blake" <eblake@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Jason Wang" <jasowangio@gmail.com>,
"Peter Xu" <peterx@redhat.com>,
"Eugenio Pérez" <eperezma@redhat.com>,
"Alyssa Ross" <hi@alyssa.is>,
"Demi Marie Obenour" <demiobenour@gmail.com>,
20260817233147.2867623-1-connorkite@gmail.com
Subject: Re: [PATCH RFC v2 07/13] hw/virtio/vhost-user: create isolation region
Date: Tue, 25 Aug 2026 16:34:11 +0200 [thread overview]
Message-ID: <747e251a-3bfe-4d22-8541-7631de19ea51@redhat.com> (raw)
In-Reply-To: <20260817-vhost-user-isolated-memory-v2-7-948aae960abb@gmail.com>
On 18.08.26 07:12, Connor Kite wrote:
> If memory isolation mode is active for the vhost-user device adds
> features to:
> - Gather the size required for bounce buffers and vrings in shared
> isolation region
> - Allocate the required space in an anonymous file
> - Create a vhost-iova-tree with space to map entire isolation region
> - Map guest memory regions and shared vrings into the tree
> - Release these resources upon backend cleanup
>
> Signed-off-by: Connor Kite <connorkite@gmail.com>
> ---
> hw/virtio/vhost-user.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 136 insertions(+)
qemu does not compile with this patch applied because the
"hw/virtio/vhost-shadow-virtqueue.h" include is missing.
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 1c003e4d9d..7e9233e174 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -18,6 +18,7 @@
> #include "hw/virtio/vhost-backend.h"
> #include "hw/virtio/virtio.h"
> #include "hw/virtio/virtio-net.h"
> +#include "hw/virtio/vhost-iova-tree.h"
> #include "chardev/char-fe.h"
> #include "io/channel-socket.h"
> #include "system/kvm.h"
> @@ -25,6 +26,7 @@
> #include "qemu/main-loop.h"
> #include "qemu/uuid.h"
> #include "qemu/sockets.h"
> +#include "qemu/memfd.h"
> #include "system/runstate.h"
> #include "system/cryptodev.h"
> #include "migration/postcopy-ram.h"
> @@ -320,6 +322,17 @@ static VhostUserMsg m __attribute__ ((unused));
> /* The version of the protocol we support */
> #define VHOST_USER_VERSION (0x1)
>
> +/* Memory region shared with back-end when memory-isolation is active */
> +typedef struct {
> + void *shared_mem_addr; /* mapped shared memory */
> + VhostIOVATree *tree; /* controls mapping of regions into IOVA space */
> + void *vring_hva_addr; /* beginning of vring region in shared memory */
> + size_t vring_region_size; /* amount of shared memory reserved for vrings */
> + size_t size; /* size of the mapped shared memory */
> + int fd; /* descriptor of anonymous file backing shared iso region */
> + Int128 iso_iova_offset; /* translation from IOVA to hva of iso region */
> +} IsolationModeCtx;
Can you put the comments above each field instead of inline?
> +
> struct vhost_user {
> struct vhost_dev *dev;
> /* Shared between vhost devs of the same virtio device */
> @@ -353,6 +366,9 @@ struct vhost_user {
> * by the backend (see @features).
> */
> uint64_t protocol_features;
> +
> + /* Data specfic to isolated memory mode */
> + IsolationModeCtx iso_mem_ctx;
> };
>
> struct scrub_regions {
> @@ -1112,6 +1128,125 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
> return 0;
> }
>
> +static void cleanup_isolation_regions(struct vhost_dev *dev)
> +{
> + struct vhost_user *u = dev->opaque;
> + if (u->iso_mem_ctx.shared_mem_addr) {
> + vhost_iova_tree_delete(u->iso_mem_ctx.tree);
> + qemu_memfd_free(u->iso_mem_ctx.shared_mem_addr,
> + u->iso_mem_ctx.size,
> + u->iso_mem_ctx.fd);
> + memset(&u->iso_mem_ctx, 0, sizeof(IsolationModeCtx));
> + }
> +}
> +
> +__attribute__((unused))
> +static int init_isolation_regions(struct vhost_dev *dev,
> + VhostUserMsg *msg,
> + int *fds, size_t *fd_num)
> +{
> + Error *err = NULL;
> + struct vhost_user *u = dev->opaque;
> + uint32_t nregions = dev->mem->nregions;
> +
I don’t really feel like this empty line helps readability as it seems
arbitrarily placed.
> + g_autofree DMAMap *buffer_regions = g_new0(DMAMap, nregions);
> + size_t buffer_reg_size = 0;
> + size_t total_vring_size = 0;
> + size_t total_mmap_size;
> + char *reg_name;
> + uint64_t first_IOVA_addr;
> + uint64_t last_IOVA_addr;
> + DMAMap *map;
> + DMAMap vring_map;
> + int r;
> +
> + msg->hdr.request = VHOST_USER_SET_MEM_TABLE;
> +
> + /* In case of reset, clear old regions */
> + cleanup_isolation_regions(dev);
> +
> + /* Gather information for bounce buffers to be mapped */
> + for (u_int32_t i = 0; i < nregions; i++) {
uint32_t please, not u_int32_t.
> + hwaddr size = ROUND_UP(dev->mem->regions[i].memory_size,
> + qemu_real_host_page_size());
> + buffer_regions[i].size = size - 1;
> + buffer_regions[i].perm = IOMMU_RW;
> +
> + buffer_reg_size += size;
> + }
> +
> + /* Get space required for all vrings */
> + for (int i = 0; i < dev->nvqs; i++) {
> + VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
> + total_vring_size += vhost_svq_vring_total_size(dev->vdev, vq);
> + }
> +
> + total_mmap_size = buffer_reg_size + total_vring_size;
> + u->iso_mem_ctx.size = total_mmap_size;
> +
> + /* Allocate and map an anonymous file to hold the isolation region */
> + reg_name = g_strconcat("iso_mem_", dev->vdev->name, NULL);
> + u->iso_mem_ctx.shared_mem_addr = qemu_memfd_alloc(reg_name,
> + total_mmap_size,
> + F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
> + &u->iso_mem_ctx.fd, &err);
> +
> + assert(u->iso_mem_ctx.fd >= 0);
Does it make sense to check that before we took a look (via `err`)
whether the function even succeeded?
> + g_free(reg_name);
> +
> + if (err) {
> + error_report_err(err);
> + cleanup_isolation_regions(dev);
> + return -1;
Are you sure you can run cleanup_isolation_regions() if
qemu_memfd_alloc() left some fields in basically undefined state?
General note: We usually use `goto fail` and `fail:` patterns in qemu
for common clean-up paths (in this case cleanup_isolation_regions()).
> + }
> +
> + /* vhost-iova-tree enforces non-zero lower address */
> + first_IOVA_addr = qemu_real_host_page_size();
> + last_IOVA_addr = first_IOVA_addr + total_mmap_size - 1;
> + assert(last_IOVA_addr > first_IOVA_addr);
> +
> + /* Use 128-bit operation in case of large negative offset */
Yeah, as discussed (last week and with Akihiko on this thread), I think
all 128-bit operations can be replaced by `uintptr_t` operation with its
well-defined two's complement overflow/representation.
Hanna
> + u->iso_mem_ctx.iso_iova_offset =
> + int128_sub(int128_make64((uint64_t)u->iso_mem_ctx.shared_mem_addr),
> + int128_make64(first_IOVA_addr));
> +
> + /*
> + * Instantiates iova tree sized to map bounce buffers and vrings to the
> + * isolation region in host va.
> + */
> + u->iso_mem_ctx.tree =
> + vhost_iova_tree_new(first_IOVA_addr, last_IOVA_addr);
> +
> + /* Map vrings into IOVA tree */
> + vring_map.perm = IOMMU_RW;
> + vring_map.size = total_vring_size - 1;
> + r = vhost_iova_tree_map_alloc(u->iso_mem_ctx.tree, &vring_map,
> + (hwaddr)u->iso_mem_ctx.shared_mem_addr);
> +
> + if (r != IOVA_OK) {
> + cleanup_isolation_regions(dev);
> + return r;
> + }
> +
> + u->iso_mem_ctx.vring_hva_addr = (void *)int128_get64(
> + int128_add(int128_make64(vring_map.iova),
> + u->iso_mem_ctx.iso_iova_offset));
> + u->iso_mem_ctx.vring_region_size = total_vring_size;
> +
> + for (int i = 0; i < nregions; i++) {
> + map = &buffer_regions[i];
> + r = vhost_iova_tree_map_alloc_gpa(u->iso_mem_ctx.tree, map,
> + dev->mem->regions[i].guest_phys_addr);
> +
> + if (r != IOVA_OK) {
> + cleanup_isolation_regions(dev);
> + return r;
> + }
> + }
> +
> + return 0;
> +}
> +
> static int vhost_user_set_mem_table(struct vhost_dev *dev,
> struct vhost_memory *mem)
> {
> @@ -2684,6 +2819,7 @@ static int vhost_user_backend_cleanup(struct vhost_dev *dev)
> g_free(u->region_rb_offset);
> u->region_rb_offset = NULL;
> u->region_rb_len = 0;
> + cleanup_isolation_regions(dev);
> g_free(u);
> dev->opaque = 0;
>
>
next prev parent reply other threads:[~2026-08-25 14:34 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 5:12 [PATCH RFC v2 00/13] vhost-user: isolated memory Connor Kite
2026-08-18 5:12 ` [PATCH RFC v2 01/13] vhost-user: Consolidate chardev property definitions Connor Kite
2026-08-18 5:12 ` [PATCH RFC v2 02/13] util/iova-tree: g_tree_foreach wrapper Connor Kite
2026-08-18 5:12 ` [PATCH RFC v2 03/13] hw/virtio: iova_tree_foreach wrapper Connor Kite
2026-08-18 5:12 ` [PATCH RFC v2 04/13] hw/virtio/vhost-shadow-virtqueue: used callback Connor Kite
2026-08-19 6:23 ` Akihiko Odaki
2026-08-20 1:06 ` Connor Kite
2026-08-20 5:15 ` Akihiko Odaki
2026-08-20 23:42 ` Connor Kite
2026-08-21 7:21 ` Akihiko Odaki
2026-08-18 5:12 ` [PATCH RFC v2 05/13] hw/virtio/vhost-shadow-virtqueue: specified vring placement Connor Kite
2026-08-25 14:26 ` Hanna Czenczek
2026-08-28 12:15 ` Eugenio Perez Martin
2026-08-18 5:12 ` [PATCH RFC v2 06/13] vhost-user: add memory_isolation to VhostUserState Connor Kite
2026-08-18 5:12 ` [PATCH RFC v2 07/13] hw/virtio/vhost-user: create isolation region Connor Kite
2026-08-19 7:36 ` Akihiko Odaki
2026-08-21 2:57 ` Connor Kite
2026-08-25 14:34 ` Hanna Czenczek [this message]
2026-08-18 5:12 ` [PATCH RFC v2 08/13] hw/virtio/vhost-user: send isolation regions to device Connor Kite
2026-08-18 11:31 ` Akihiko Odaki
2026-08-25 14:36 ` Hanna Czenczek
2026-08-28 12:29 ` Eugenio Perez Martin
2026-08-18 5:12 ` [PATCH RFC v2 09/13] hw/virtio/vhost-user: add shadow virtqueues and eventfd intercepts Connor Kite
2026-08-18 12:34 ` Akihiko Odaki
2026-08-20 20:38 ` Connor Kite
2026-08-25 14:48 ` Hanna Czenczek
2026-08-18 5:12 ` [PATCH RFC v2 10/13] hw/virtio/vhost-user: handle data movement with shadow vqs Connor Kite
2026-08-19 7:37 ` Akihiko Odaki
2026-08-28 12:24 ` Eugenio Perez Martin
2026-08-18 5:12 ` [PATCH RFC v2 11/13] vhost-user: Add memory-isolation qdev property to vhost-user devices Connor Kite
2026-08-18 5:12 ` [PATCH RFC v2 12/13] backends/cryptodev-vhost-user: add memory isolation bool Connor Kite
2026-08-20 9:00 ` Markus Armbruster
2026-08-18 5:12 ` [PATCH RFC v2 13/13] net/vhost-user: add memory isolation Connor Kite
2026-08-19 7:37 ` Akihiko Odaki
2026-08-20 1:22 ` Connor Kite
2026-08-20 9:02 ` Markus Armbruster
2026-08-21 0:39 ` Connor Kite
2026-08-21 5:54 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=747e251a-3bfe-4d22-8541-7631de19ea51@redhat.com \
--to=hreitz@redhat.com \
--cc=20260817233147.2867623-1-connorkite@gmail.com \
--cc=alex.bennee@linaro.org \
--cc=arei.gonglei@huawei.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=connorkite@gmail.com \
--cc=demiobenour@gmail.com \
--cc=dmitry.osipenko@collabora.com \
--cc=eblake@redhat.com \
--cc=eperezma@redhat.com \
--cc=fam@euphon.net \
--cc=hi@alyssa.is \
--cc=jasowangio@gmail.com \
--cc=kraxel@redhat.com \
--cc=kwolf@redhat.com \
--cc=manos.pitsidianakis@linaro.org \
--cc=marcandre.lureau@redhat.com \
--cc=mathieu.poirier@linaro.org \
--cc=mst@redhat.com \
--cc=mzamazal@redhat.com \
--cc=odaki@rsg.ci.i.u-tokyo.ac.jp \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=rnorwitz@nvidia.com \
--cc=sgarzare@redhat.com \
--cc=stefanha@redhat.com \
--cc=viresh.kumar@linaro.org \
--cc=virtio-fs@lists.linux.dev \
--cc=zhenwei.pi@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.