All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/15] vhost-user: isolated memory
@ 2026-07-23 22:29 ConKite
  2026-07-23 22:30 ` [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions ConKite
                   ` (14 more replies)
  0 siblings, 15 replies; 23+ messages in thread
From: ConKite @ 2026-07-23 22:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

This patch series implements a memory isolation mode in vhost-user. The
purpose of this mode is to provide the option of additional security by
eliminating direct access of guest memory by vhost-user devices.
At a high level this works by:

1. Adding qdev and qapi properties required to enable isolation mode for
   various devices.
2. Allocating an isolation memory region in an anonymous file and mapping it
   to host memory.  This isolation region will hold the bounce buffers and
   vrings necessary to move data.
3. Using a vhost-iova-tree to allocate and track the mapping between
   guest regions and their corresponding bounce buffers in the isolation
   memory.
4. Creating shadow virtqueues to intercept request notifications.  As
   kick and call events are received by an svq, it copies buffer
   contents and descriptors between isolation and guest memory before
   notifying the backend or guest.   

Note: This project is currently in a partially functional state. For
example, in testing vhost-user-input and a keyboard, keystrokes may
register correctly or be double counted depending on the combination
of backend daemon and guest OS used. However, the desire is to make
this work public at this stage for comment on the overall
approach.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
ConKite (2):
      vhost-user: Consolidate chardev property definitions
      vhost-user: Add memory-isolation qdev property to vhost-user devices

Connor Kite (13):
      backends/cryptodev-vhost-user: add memory isolation bool
      net/vhost-user: add memory isolation
      vhost-user: add memory_isolation to VhostUserState
      util/iova-tree: g_tree_foreach wrapper
      hw/virtio: iova_tree_foreach wrapper
      hw/virtio/vhost-shadow-virtqueue: used handler
      hw/virtio/vhost-shadow-virtqueue: specified vring placement
      hw/virtio/vhost-shadow-virtqueue: range boundary in translation
      hw/virtio/vhost-user: create isolation region
      hw/virtio/vhost-user: send isolation regions to device
      hw/virtio/vhost-user: add shadow virtqueues and eventfd intercepts
      hw/virtio/vhost-user: handle data movement with shadow vqs
      hw/virtio/vhost-user: shadow vq cleanup

 backends/cryptodev-vhost-user.c      |  24 +-
 backends/vhost-user.c                |   4 +-
 hw/block/vhost-user-blk.c            |   4 +-
 hw/display/vhost-user-gpu.c          |   4 +-
 hw/scsi/vhost-user-scsi.c            |   4 +-
 hw/virtio/vhost-iova-tree.c          |  15 ++
 hw/virtio/vhost-iova-tree.h          |   3 +
 hw/virtio/vhost-shadow-virtqueue.c   |  30 ++-
 hw/virtio/vhost-shadow-virtqueue.h   |  17 ++
 hw/virtio/vhost-stub.c               |   3 +-
 hw/virtio/vhost-user-base.c          |  13 +-
 hw/virtio/vhost-user-fs.c            |   4 +-
 hw/virtio/vhost-user-gpio.c          |   4 -
 hw/virtio/vhost-user-i2c.c           |   5 -
 hw/virtio/vhost-user-input.c         |   5 -
 hw/virtio/vhost-user-rng.c           |   5 -
 hw/virtio/vhost-user-rtc.c           |   4 -
 hw/virtio/vhost-user-scmi.c          |   4 +-
 hw/virtio/vhost-user-snd.c           |   1 -
 hw/virtio/vhost-user-spi.c           |   5 -
 hw/virtio/vhost-user-test-device.c   |   1 -
 hw/virtio/vhost-user-vsock.c         |   4 +-
 hw/virtio/vhost-user.c               | 441 ++++++++++++++++++++++++++++++++++-
 include/hw/virtio/vhost-user-base.h  |   1 +
 include/hw/virtio/vhost-user-blk.h   |   1 +
 include/hw/virtio/vhost-user-fs.h    |   1 +
 include/hw/virtio/vhost-user-scmi.h  |   1 +
 include/hw/virtio/vhost-user-vsock.h |   1 +
 include/hw/virtio/vhost-user.h       |   6 +-
 include/hw/virtio/virtio-gpu.h       |   1 +
 include/hw/virtio/virtio-scsi.h      |   1 +
 include/qemu/iova-tree.h             |  13 ++
 include/system/vhost-user-backend.h  |   3 +-
 net/passt.c                          |  16 +-
 net/vhost-user.c                     |  11 +-
 qapi/net.json                        |  15 +-
 qapi/qom.json                        |   6 +-
 util/iova-tree.c                     |   5 +
 38 files changed, 622 insertions(+), 64 deletions(-)
---
base-commit: 006a22cb26998998385b104db1ff9466ef2f3153
change-id: 20260604-vhost-user-isolated-memory-070ed4833ee7

Best regards,
-- 
Connor Kite <connorkite@gmail.com>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
@ 2026-07-23 22:30 ` ConKite
  2026-07-24  6:09   ` Markus Armbruster
  2026-07-23 22:30 ` [PATCH RFC 02/15] vhost-user: Add memory-isolation qdev property to vhost-user devices ConKite
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: ConKite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Move chardev qdev property definitions from children into
VHostUserBase. This reduces code duplication and allows children
to simply inherit the property during initialization.

Signed-off-by: Connor Kite <connorkite@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/virtio/vhost-user-base.c        | 9 +++++++++
 hw/virtio/vhost-user-gpio.c        | 4 ----
 hw/virtio/vhost-user-i2c.c         | 5 -----
 hw/virtio/vhost-user-input.c       | 5 -----
 hw/virtio/vhost-user-rng.c         | 5 -----
 hw/virtio/vhost-user-rtc.c         | 4 ----
 hw/virtio/vhost-user-snd.c         | 1 -
 hw/virtio/vhost-user-spi.c         | 5 -----
 hw/virtio/vhost-user-test-device.c | 1 -
 9 files changed, 9 insertions(+), 30 deletions(-)

diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 478ec68f09..90bd2903db 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -407,9 +407,16 @@ static void vub_device_unrealize(DeviceState *dev)
     do_vhost_user_cleanup(vdev, vub);
 }
 
+/*Define common qdev properties.  Inherited by all children*/
+static const Property vub_properties[] = {
+    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev)
+};
+
+
 static void vub_class_init(ObjectClass *klass, const void *data)
 {
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     vdc->realize = vub_device_realize;
     vdc->unrealize = vub_device_unrealize;
@@ -417,6 +424,8 @@ static void vub_class_init(ObjectClass *klass, const void *data)
     vdc->get_config = vub_get_config;
     vdc->set_config = vub_set_config;
     vdc->set_status = vub_set_status;
+
+    device_class_set_props(dc, vub_properties);
 }
 
 static const TypeInfo vub_types[] = {
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index d473f87077..33b8752282 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -14,9 +14,6 @@
 #include "standard-headers/linux/virtio_ids.h"
 #include "standard-headers/linux/virtio_gpio.h"
 
-static const Property vgpio_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
-};
 
 static void vgpio_realize(DeviceState *dev, Error **errp)
 {
@@ -42,7 +39,6 @@ static void vu_gpio_class_init(ObjectClass *klass, const void *data)
     VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
 
     dc->vmsd = &vu_gpio_vmstate;
-    device_class_set_props(dc, vgpio_properties);
     device_class_set_parent_realize(dc, vgpio_realize,
                                     &vubc->parent_realize);
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 152b1f6740..3f5427b5b2 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,10 +14,6 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const Property vi2c_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
-};
-
 static void vi2c_realize(DeviceState *dev, Error **errp)
 {
     VHostUserBase *vub = VHOST_USER_BASE(dev);
@@ -42,7 +38,6 @@ static void vu_i2c_class_init(ObjectClass *klass, const void *data)
     VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
 
     dc->vmsd = &vu_i2c_vmstate;
-    device_class_set_props(dc, vi2c_properties);
     device_class_set_parent_realize(dc, vi2c_realize,
                                     &vubc->parent_realize);
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
diff --git a/hw/virtio/vhost-user-input.c b/hw/virtio/vhost-user-input.c
index 5cfc5bbb56..8fe6349ffc 100644
--- a/hw/virtio/vhost-user-input.c
+++ b/hw/virtio/vhost-user-input.c
@@ -7,10 +7,6 @@
 #include "qemu/osdep.h"
 #include "hw/virtio/virtio-input.h"
 
-static const Property vinput_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
-};
-
 static void vinput_realize(DeviceState *dev, Error **errp)
 {
     VHostUserBase *vub = VHOST_USER_BASE(dev);
@@ -36,7 +32,6 @@ static void vhost_input_class_init(ObjectClass *klass, const void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &vmstate_vhost_input;
-    device_class_set_props(dc, vinput_properties);
     device_class_set_parent_realize(dc, vinput_realize,
                                     &vubc->parent_realize);
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index 106c8f211a..664aee403d 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -20,10 +20,6 @@ static const VMStateDescription vu_rng_vmstate = {
     .unmigratable = 1,
 };
 
-static const Property vrng_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
-};
-
 static void vu_rng_base_realize(DeviceState *dev, Error **errp)
 {
     VHostUserBase *vub = VHOST_USER_BASE(dev);
@@ -43,7 +39,6 @@ static void vu_rng_class_init(ObjectClass *klass, const void *data)
     VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
 
     dc->vmsd = &vu_rng_vmstate;
-    device_class_set_props(dc, vrng_properties);
     device_class_set_parent_realize(dc, vu_rng_base_realize,
                                     &vubc->parent_realize);
 
diff --git a/hw/virtio/vhost-user-rtc.c b/hw/virtio/vhost-user-rtc.c
index 88b0c70b90..6d80cb6263 100644
--- a/hw/virtio/vhost-user-rtc.c
+++ b/hw/virtio/vhost-user-rtc.c
@@ -19,9 +19,6 @@ static const VMStateDescription vu_rtc_vmstate = {
     .unmigratable = 1,
 };
 
-static const Property vrtc_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
-};
 
 static void vu_rtc_base_realize(DeviceState *dev, Error **errp)
 {
@@ -42,7 +39,6 @@ static void vu_rtc_class_init(ObjectClass *klass, const void *data)
     VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
 
     dc->vmsd = &vu_rtc_vmstate;
-    device_class_set_props(dc, vrtc_properties);
     device_class_set_parent_realize(dc, vu_rtc_base_realize,
                                     &vubc->parent_realize);
 
diff --git a/hw/virtio/vhost-user-snd.c b/hw/virtio/vhost-user-snd.c
index 7129b77d9c..3663450aed 100644
--- a/hw/virtio/vhost-user-snd.c
+++ b/hw/virtio/vhost-user-snd.c
@@ -34,7 +34,6 @@ static const VMStateDescription vu_snd_vmstate = {
 };
 
 static const Property vsnd_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
     DEFINE_PROP_BIT64("controls", VHostUserBase,
                       parent_obj.host_features, VIRTIO_SND_F_CTLS, false),
 };
diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
index 707f96c250..fb6168d391 100644
--- a/hw/virtio/vhost-user-spi.c
+++ b/hw/virtio/vhost-user-spi.c
@@ -15,10 +15,6 @@
 #include "standard-headers/linux/virtio_ids.h"
 #include "standard-headers/linux/virtio_spi.h"
 
-static const Property vspi_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
-};
-
 static void vspi_realize(DeviceState *dev, Error **errp)
 {
     VHostUserBase *vub = VHOST_USER_BASE(dev);
@@ -44,7 +40,6 @@ static void vu_spi_class_init(ObjectClass *klass, const void *data)
     VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
 
     dc->vmsd = &vu_spi_vmstate;
-    device_class_set_props(dc, vspi_properties);
     device_class_set_parent_realize(dc, vspi_realize,
                                     &vubc->parent_realize);
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
diff --git a/hw/virtio/vhost-user-test-device.c b/hw/virtio/vhost-user-test-device.c
index a2f963fdf6..91e23bf07a 100644
--- a/hw/virtio/vhost-user-test-device.c
+++ b/hw/virtio/vhost-user-test-device.c
@@ -30,7 +30,6 @@ static const VMStateDescription vud_vmstate = {
 };
 
 static const Property vud_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
     DEFINE_PROP_UINT16("virtio-id", VHostUserBase, virtio_id, 0),
     DEFINE_PROP_UINT32("vq_size", VHostUserBase, vq_size, 64),
     DEFINE_PROP_UINT32("num_vqs", VHostUserBase, num_vqs, 1),

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 02/15] vhost-user: Add memory-isolation qdev property to vhost-user devices
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
  2026-07-23 22:30 ` [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions ConKite
@ 2026-07-23 22:30 ` ConKite
  2026-07-24 10:56   ` Akihiko Odaki
  2026-07-23 22:30 ` [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool Connor Kite
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: ConKite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

In support of future work to add a memory isolation mode to vhost-user devices, a
qdev property, "memory-isolation", is added to all vhost-user devices. This is
simply a bool representing whether the mode is active or not.

Signed-off-by: Connor Kite <connorkite@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/block/vhost-user-blk.c            | 1 +
 hw/display/vhost-user-gpu.c          | 1 +
 hw/scsi/vhost-user-scsi.c            | 1 +
 hw/virtio/vhost-user-base.c          | 3 ++-
 hw/virtio/vhost-user-fs.c            | 1 +
 hw/virtio/vhost-user-scmi.c          | 1 +
 hw/virtio/vhost-user-vsock.c         | 1 +
 include/hw/virtio/vhost-user-base.h  | 1 +
 include/hw/virtio/vhost-user-blk.h   | 1 +
 include/hw/virtio/vhost-user-fs.h    | 1 +
 include/hw/virtio/vhost-user-scmi.h  | 1 +
 include/hw/virtio/vhost-user-vsock.h | 1 +
 include/hw/virtio/virtio-gpu.h       | 1 +
 include/hw/virtio/virtio-scsi.h      | 1 +
 14 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 2e5b3ae1b1..9830dc6c35 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -631,6 +631,7 @@ static const VMStateDescription vmstate_vhost_user_blk = {
 
 static const Property vhost_user_blk_properties[] = {
     DEFINE_PROP_CHR("chardev", VHostUserBlk, chardev),
+    DEFINE_PROP_BOOL("memory-isolation", VHostUserBlk, memory_isolation, false),
     DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues,
                        VHOST_USER_BLK_AUTO_NUM_QUEUES),
     DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 57360898ca..6d0ede672a 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -659,6 +659,7 @@ static struct vhost_dev *vhost_user_gpu_get_vhost(VirtIODevice *vdev)
 
 static const Property vhost_user_gpu_properties[] = {
     VIRTIO_GPU_BASE_PROPERTIES(VhostUserGPU, parent_obj.conf),
+    DEFINE_PROP_BOOL("memory-isolation", VhostUserGPU, memory_isolation, false),
 };
 
 static void
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 5070178dc2..c1a0393220 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -346,6 +346,7 @@ static void vhost_user_scsi_unrealize(DeviceState *dev)
 
 static const Property vhost_user_scsi_properties[] = {
     DEFINE_PROP_CHR("chardev", VirtIOSCSICommon, conf.chardev),
+    DEFINE_PROP_BOOL("memory-isolation", VirtIOSCSICommon, conf.memory_isolation, false),
     DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
     DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
                        VIRTIO_SCSI_AUTO_NUM_QUEUES),
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 90bd2903db..d2a74a2860 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -409,7 +409,8 @@ static void vub_device_unrealize(DeviceState *dev)
 
 /*Define common qdev properties.  Inherited by all children*/
 static const Property vub_properties[] = {
-    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev)
+    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+    DEFINE_PROP_BOOL("memory-isolation", VHostUserBase, memory_isolation, false)
 };
 
 
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 209993918a..3d980d814b 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -410,6 +410,7 @@ static const VMStateDescription vuf_backend_vmstate = {
 
 static const Property vuf_properties[] = {
     DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
+    DEFINE_PROP_BOOL("memory-isolation", VHostUserFS, conf.memory_isolation, false),
     DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
     DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
                        conf.num_request_queues, 1),
diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c
index 02dc088ea9..d514d89392 100644
--- a/hw/virtio/vhost-user-scmi.c
+++ b/hw/virtio/vhost-user-scmi.c
@@ -287,6 +287,7 @@ static const VMStateDescription vu_scmi_vmstate = {
 
 static const Property vu_scmi_properties[] = {
     DEFINE_PROP_CHR("chardev", VHostUserSCMI, chardev),
+    DEFINE_PROP_BOOL("memory-isolation", VHostUserSCMI, memory_isolation, false),
 };
 
 static void vu_scmi_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
index c2cd376e73..89aa789e22 100644
--- a/hw/virtio/vhost-user-vsock.c
+++ b/hw/virtio/vhost-user-vsock.c
@@ -154,6 +154,7 @@ static void vuv_device_unrealize(DeviceState *dev)
 
 static const Property vuv_properties[] = {
     DEFINE_PROP_CHR("chardev", VHostUserVSock, conf.chardev),
+    DEFINE_PROP_BOOL("memory-isolation", VHostUserVSock, conf.memory_isolation, false),
 };
 
 static void vuv_class_init(ObjectClass *klass, const void *data)
diff --git a/include/hw/virtio/vhost-user-base.h b/include/hw/virtio/vhost-user-base.h
index d5d2f081ae..29bc40736c 100644
--- a/include/hw/virtio/vhost-user-base.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -25,6 +25,7 @@ struct VHostUserBase {
     uint32_t num_vqs;
     uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
     uint32_t config_size;
+    bool memory_isolation;
     /* State tracking */
     VhostUserState vhost_user;
     struct vhost_virtqueue *vhost_vq;
diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
index dee848cfd8..8126447a86 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -30,6 +30,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserBlk, VHOST_USER_BLK)
 struct VHostUserBlk {
     VirtIODevice parent_obj;
     CharFrontend chardev;
+    bool memory_isolation;
     int32_t bootindex;
     struct virtio_blk_config blkcfg;
     uint16_t num_queues;
diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
index 5699ea03a1..bf71990b9c 100644
--- a/include/hw/virtio/vhost-user-fs.h
+++ b/include/hw/virtio/vhost-user-fs.h
@@ -28,6 +28,7 @@ typedef struct {
     char *tag;
     uint16_t num_request_queues;
     uint16_t queue_size;
+    bool memory_isolation;
 } VHostUserFSConf;
 
 struct VHostUserFS {
diff --git a/include/hw/virtio/vhost-user-scmi.h b/include/hw/virtio/vhost-user-scmi.h
index 30ab0d7ab7..d346b42ed8 100644
--- a/include/hw/virtio/vhost-user-scmi.h
+++ b/include/hw/virtio/vhost-user-scmi.h
@@ -19,6 +19,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSCMI, VHOST_USER_SCMI);
 struct VHostUserSCMI {
     VirtIODevice parent;
     CharFrontend chardev;
+    bool memory_isolation;
     struct vhost_virtqueue *vhost_vqs;
     struct vhost_dev vhost_dev;
     VhostUserState vhost_user;
diff --git a/include/hw/virtio/vhost-user-vsock.h b/include/hw/virtio/vhost-user-vsock.h
index 5db6938b8b..6288b26fa4 100644
--- a/include/hw/virtio/vhost-user-vsock.h
+++ b/include/hw/virtio/vhost-user-vsock.h
@@ -21,6 +21,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserVSock, VHOST_USER_VSOCK)
 
 typedef struct {
     CharFrontend chardev;
+    bool memory_isolation;
 } VHostUserVSockConf;
 
 struct VHostUserVSock {
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index b9bad27c97..707612c3a4 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -277,6 +277,7 @@ struct VhostUserGPU {
     CharFrontend vhost_chr;
     QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
     bool backend_blocked;
+    bool memory_isolation;
 };
 
 #define MAX_SLOTS 4096
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index b6028bb5cd..47fdc3785c 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -59,6 +59,7 @@ struct VirtIOSCSIConf {
     char *vhostfd;
     char *wwpn;
     CharFrontend chardev;
+    bool memory_isolation;
     uint32_t boot_tpgt;
     IOThread *iothread;
     IOThreadVirtQueueMappingList *iothread_vq_mapping_list;

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
  2026-07-23 22:30 ` [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions ConKite
  2026-07-23 22:30 ` [PATCH RFC 02/15] vhost-user: Add memory-isolation qdev property to vhost-user devices ConKite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-24  6:06   ` Markus Armbruster
  2026-07-24 11:03   ` Akihiko Odaki
  2026-07-23 22:30 ` [PATCH RFC 04/15] net/vhost-user: add memory isolation Connor Kite
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Add a memory_isolation property to CryptoDevBackendVhostUser and
add add it as an optional member of CryptodevVhostUserProperties
in qapi.

This is needed to be able to specify memory isolation for
cryptodev-vhost-user objects, and the bool will eventually be
passed to vhost_user_init() in a future patch.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 backends/cryptodev-vhost-user.c | 22 ++++++++++++++++++++++
 qapi/qom.json                   |  6 +++++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index cc478d9902..e0547c5d40 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -49,6 +49,7 @@ struct CryptoDevBackendVhostUser {
     CharFrontend chr;
     char *chr_name;
     bool opened;
+    bool memory_isolation;
     CryptoDevBackendVhost *vhost_crypto[MAX_CRYPTO_QUEUE_NUM];
 };
 
@@ -392,6 +393,23 @@ static void cryptodev_vhost_user_finalize(Object *obj)
     g_free(s->chr_name);
 }
 
+static void cryptodev_vhost_user_set_mem_isolation(Object *obj, bool value,
+                                                   Error **errp)
+{
+    CryptoDevBackendVhostUser *s =
+                      CRYPTODEV_BACKEND_VHOST_USER(obj);
+
+    s->memory_isolation = value;
+}
+
+static bool cryptodev_vhost_user_get_mem_isolation(Object *obj, Error **errp)
+{
+    CryptoDevBackendVhostUser *s =
+                      CRYPTODEV_BACKEND_VHOST_USER(obj);
+
+    return s->memory_isolation;
+}
+
 static void
 cryptodev_vhost_user_class_init(ObjectClass *oc, const void *data)
 {
@@ -407,6 +425,10 @@ cryptodev_vhost_user_class_init(ObjectClass *oc, const void *data)
                                   cryptodev_vhost_user_get_chardev,
                                   cryptodev_vhost_user_set_chardev);
 
+    object_class_property_add_bool(oc, "memory-isolation",
+                                   cryptodev_vhost_user_get_mem_isolation,
+                                   cryptodev_vhost_user_set_mem_isolation);
+
 }
 
 static const TypeInfo cryptodev_vhost_user_info = {
diff --git a/qapi/qom.json b/qapi/qom.json
index c55776af7d..d7ca1b4203 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -350,11 +350,15 @@
 # @chardev: the name of a Unix domain socket character device that
 #     connects to the vhost-user server
 #
+# @memory-isolation: disables access from cryptodev to guest memory.
+#     (default: false)
+#
 # Since: 2.12
 ##
 { 'struct': 'CryptodevVhostUserProperties',
   'base': 'CryptodevBackendProperties',
-  'data': { 'chardev': 'str' },
+  'data': { 'chardev': 'str',
+            '*memory-isolation': 'bool' },
   'if': 'CONFIG_VHOST_CRYPTO' }
 
 ##

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 04/15] net/vhost-user: add memory isolation
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (2 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 05/15] vhost-user: add memory_isolation to VhostUserState Connor Kite
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Add a memory-isolation property to NetdevPassOptions and
NetDevVhostUserOptions in net.json.  This property will
be used for vhost-user devices to disable access to guest
memory from devices.

It will be passed into vhost_user_init() in a future patch.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 net/passt.c      |  7 +++++++
 net/vhost-user.c |  4 ++++
 qapi/net.json    | 15 +++++++++++----
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/net/passt.c b/net/passt.c
index 45440c399b..ce80186883 100644
--- a/net/passt.c
+++ b/net/passt.c
@@ -735,6 +735,13 @@ int net_init_passt(const Netdev *netdev, const char *name,
     s->pidfile = pidfile;
 
     if (netdev->u.passt.has_vhost_user && netdev->u.passt.vhost_user) {
+        bool memory_isolation G_GNUC_UNUSED = false;
+
+        if (netdev->u.passt.has_memory_isolation &&
+           netdev->u.passt.memory_isolation) {
+            memory_isolation = true;
+        }
+
         if (net_passt_vhost_user_init(s, errp) == -1) {
             qemu_del_net_client(nc);
             return -1;
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 2d0fc49b4d..8fa303f901 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -459,6 +459,7 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
     int queues;
     const NetdevVhostUserOptions *vhost_user_opts;
     Chardev *chr;
+    bool memory_isolation G_GNUC_UNUSED;
 
     assert(netdev->type == NET_CLIENT_DRIVER_VHOST_USER);
     vhost_user_opts = &netdev->u.vhost_user;
@@ -476,5 +477,8 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
         return -1;
     }
 
+    memory_isolation = vhost_user_opts->has_memory_isolation ?
+                       vhost_user_opts->memory_isolation : false;
+
     return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
 }
diff --git a/qapi/net.json b/qapi/net.json
index 1a6382825c..4588c7014b 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -213,6 +213,9 @@
 #
 # @param: parameter to pass to passt command
 #
+# @memory-isolation: enable memory isolation.  Only has effect if
+#     using vhost-user.  (default: false)
+#
 # Since: 10.1
 ##
 { 'struct': 'NetdevPasstOptions',
@@ -250,7 +253,8 @@
     '*ipv6':               'bool',
     '*tcp-ports':          ['PasstPortForward'],
     '*udp-ports':          ['PasstPortForward'],
-    '*param':              ['PasstParameter'] },
+    '*param':              ['PasstParameter'],
+    '*memory-isolation':   'bool'},
     'if': 'CONFIG_PASST' }
 
 ##
@@ -685,13 +689,16 @@
 # @queues: number of queues to be created for multiqueue vhost-user
 #     (default: 1) (Since 2.5)
 #
+# @memory-isolation: isolate guest memory from device (default: false)
+#
 # Since: 2.1
 ##
 { 'struct': 'NetdevVhostUserOptions',
   'data': {
-    'chardev':        'str',
-    '*vhostforce':    'bool',
-    '*queues':        'int' } }
+    'chardev':              'str',
+    '*vhostforce':          'bool',
+    '*queues':              'int',
+    '*memory-isolation':    'bool' } }
 
 ##
 # @NetdevVhostVDPAOptions:

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 05/15] vhost-user: add memory_isolation to VhostUserState
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (3 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 04/15] net/vhost-user: add memory isolation Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-24 11:09   ` Akihiko Odaki
  2026-07-23 22:30 ` [PATCH RFC 06/15] util/iova-tree: g_tree_foreach wrapper Connor Kite
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Add a memory_isolation bool to the VhostUserState struct. This
bool is set within vhost_user_init(), which takes a
memory_isolation bool as an argument.

Refactor all call locations of vhost_user_init to include the new
argument.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 backends/cryptodev-vhost-user.c     |  2 +-
 backends/vhost-user.c               |  4 ++--
 hw/block/vhost-user-blk.c           |  3 ++-
 hw/display/vhost-user-gpu.c         |  3 ++-
 hw/scsi/vhost-user-scsi.c           |  3 ++-
 hw/virtio/vhost-stub.c              |  3 ++-
 hw/virtio/vhost-user-base.c         |  3 ++-
 hw/virtio/vhost-user-fs.c           |  3 ++-
 hw/virtio/vhost-user-scmi.c         |  3 ++-
 hw/virtio/vhost-user-vsock.c        |  3 ++-
 hw/virtio/vhost-user.c              |  5 ++++-
 include/hw/virtio/vhost-user.h      |  6 +++++-
 include/system/vhost-user-backend.h |  3 ++-
 net/passt.c                         | 13 ++++++++-----
 net/vhost-user.c                    |  9 +++++----
 15 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index e0547c5d40..328d7fbdfe 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -214,7 +214,7 @@ static void cryptodev_vhost_user_init(
         }
     }
 
-    if (!vhost_user_init(&s->vhost_user, &s->chr, errp)) {
+    if (!vhost_user_init(&s->vhost_user, &s->chr, s->memory_isolation, errp)) {
         return;
     }
 
diff --git a/backends/vhost-user.c b/backends/vhost-user.c
index 380d825023..470eba1775 100644
--- a/backends/vhost-user.c
+++ b/backends/vhost-user.c
@@ -22,13 +22,13 @@
 
 int
 vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
-                            unsigned nvqs, Error **errp)
+                            unsigned nvqs, bool memory_isolation, Error **errp)
 {
     int ret;
 
     assert(!b->vdev && vdev);
 
-    if (!vhost_user_init(&b->vhost_user, &b->chr, errp)) {
+    if (!vhost_user_init(&b->vhost_user, &b->chr, memory_isolation, errp)) {
         return -1;
     }
 
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 9830dc6c35..5c1a19eb50 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -505,7 +505,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (!vhost_user_init(&s->vhost_user, &s->chardev, errp)) {
+    if (!vhost_user_init(&s->vhost_user, &s->chardev,
+                         s->memory_isolation, errp)) {
         return;
     }
 
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 6d0ede672a..b44c989f58 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -625,7 +625,8 @@ vhost_user_gpu_device_realize(DeviceState *qdev, Error **errp)
     VirtIODevice *vdev = VIRTIO_DEVICE(g);
 
     vhost_dev_set_config_notifier(&g->vhost->dev, &config_ops);
-    if (vhost_user_backend_dev_init(g->vhost, vdev, 2, errp) < 0) {
+    if (vhost_user_backend_dev_init(g->vhost, vdev, 2, g->memory_isolation,
+                                    errp) < 0) {
         return;
     }
 
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index c1a0393220..5a19182f2b 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -276,7 +276,8 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev, errp)) {
+    if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev,
+                         vs->conf.memory_isolation, errp)) {
         goto free_virtio;
     }
 
diff --git a/hw/virtio/vhost-stub.c b/hw/virtio/vhost-stub.c
index 7321dc9210..d1e1075a31 100644
--- a/hw/virtio/vhost-stub.c
+++ b/hw/virtio/vhost-stub.c
@@ -12,7 +12,8 @@ unsigned int vhost_get_free_memslots(void)
     return UINT_MAX;
 }
 
-bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp)
+bool vhost_user_init(VhostUserState *user, CharFrontend *chr,
+                     bool memory_isolation, Error **errp)
 {
     return false;
 }
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index d2a74a2860..11864a3f08 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -317,7 +317,8 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
         vub->vhost_user.supports_config = true;
     }
 
-    if (!vhost_user_init(&vub->vhost_user, &vub->chardev, errp)) {
+    if (!vhost_user_init(&vub->vhost_user, &vub->chardev,
+                         vub->memory_isolation, errp)) {
         return;
     }
 
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 3d980d814b..07ff2a35e0 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -238,7 +238,8 @@ static void vuf_device_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
+    if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev,
+                         fs->conf.memory_isolation, errp)) {
         return;
     }
 
diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c
index d514d89392..2c1dbb723e 100644
--- a/hw/virtio/vhost-user-scmi.c
+++ b/hw/virtio/vhost-user-scmi.c
@@ -244,7 +244,8 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
 
     vdev->host_features |= (1ULL << VIRTIO_SCMI_F_P2A_CHANNELS);
 
-    if (!vhost_user_init(&scmi->vhost_user, &scmi->chardev, errp)) {
+    if (!vhost_user_init(&scmi->vhost_user, &scmi->chardev,
+                         scmi->memory_isolation, errp)) {
         return;
     }
 
diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
index 89aa789e22..33ab3b69e6 100644
--- a/hw/virtio/vhost-user-vsock.c
+++ b/hw/virtio/vhost-user-vsock.c
@@ -106,7 +106,8 @@ static void vuv_device_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (!vhost_user_init(&vsock->vhost_user, &vsock->conf.chardev, errp)) {
+    if (!vhost_user_init(&vsock->vhost_user, &vsock->conf.chardev,
+                         vsock->conf.memory_isolation, errp)) {
         return;
     }
 
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 517cc4ca71..f296b63fb9 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -3118,13 +3118,16 @@ static void vhost_user_state_destroy(gpointer data)
     vhost_user_host_notifier_remove(n, NULL, true);
 }
 
-bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp)
+bool vhost_user_init(VhostUserState *user, CharFrontend *chr,
+                     bool memory_isolation,
+                     Error **errp)
 {
     if (user->chr) {
         error_setg(errp, "Cannot initialize vhost-user state");
         return false;
     }
     user->chr = chr;
+    user->memory_isolation = memory_isolation;
     user->memory_slots = 0;
     user->notifiers = g_ptr_array_new_full(VIRTIO_QUEUE_MAX / 4,
                                            &vhost_user_state_destroy);
diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
index 06c360af18..72b5787efe 100644
--- a/include/hw/virtio/vhost-user.h
+++ b/include/hw/virtio/vhost-user.h
@@ -66,6 +66,7 @@ typedef struct VhostUserHostNotifier {
  * @chr: the character backend for the socket
  * @notifiers: GPtrArray of @VhostUserHostnotifier
  * @memory_slots:
+ * @memory_isolation: determines whether data is shared or copied
  */
 typedef struct VhostUserState {
     CharFrontend *chr;
@@ -73,12 +74,14 @@ typedef struct VhostUserState {
     int memory_slots;
     bool supports_config;
     bool supports_inflight_migration;
+    bool memory_isolation;
 } VhostUserState;
 
 /**
  * vhost_user_init() - initialise shared vhost_user state
  * @user: allocated area for storing shared state
  * @chr: the chardev for the vhost socket
+ * @memory_isolation: disables device access to guest memory
  * @errp: error handle
  *
  * User can either directly g_new() space for the state or embed
@@ -87,7 +90,8 @@ typedef struct VhostUserState {
  *
  * Return: true on success, false on error while setting errp.
  */
-bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp);
+bool vhost_user_init(VhostUserState *user, CharFrontend *chr,
+                     bool memory_isolation, Error **errp);
 
 /**
  * vhost_user_cleanup() - cleanup state
diff --git a/include/system/vhost-user-backend.h b/include/system/vhost-user-backend.h
index 3184c8e799..c23f689182 100644
--- a/include/system/vhost-user-backend.h
+++ b/include/system/vhost-user-backend.h
@@ -41,7 +41,8 @@ struct VhostUserBackend {
 };
 
 int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
-                                unsigned nvqs, Error **errp);
+                                unsigned nvqs, bool memory_isolation,
+                                Error **errp);
 void vhost_user_backend_start(VhostUserBackend *b);
 int vhost_user_backend_stop(VhostUserBackend *b);
 
diff --git a/net/passt.c b/net/passt.c
index ce80186883..a3021f37ef 100644
--- a/net/passt.c
+++ b/net/passt.c
@@ -433,7 +433,9 @@ static void passt_vhost_user_event(void *opaque, QEMUChrEvent event)
     }
 }
 
-static int net_passt_vhost_user_init(NetPasstState *s, Error **errp)
+static int net_passt_vhost_user_init(NetPasstState *s,
+                                     bool memory_isolation,
+                                     Error **errp)
 {
     Chardev *chr;
     int sv[2];
@@ -457,7 +459,8 @@ static int net_passt_vhost_user_init(NetPasstState *s, Error **errp)
 
     s->vhost_user = g_new0(struct VhostUserState, 1);
     if (!qemu_chr_fe_init(&s->vhost_chr, chr, errp) ||
-        !vhost_user_init(s->vhost_user, &s->vhost_chr, errp)) {
+        !vhost_user_init(s->vhost_user, &s->vhost_chr, memory_isolation,
+                         errp)) {
         goto err;
     }
 
@@ -735,14 +738,14 @@ int net_init_passt(const Netdev *netdev, const char *name,
     s->pidfile = pidfile;
 
     if (netdev->u.passt.has_vhost_user && netdev->u.passt.vhost_user) {
-        bool memory_isolation G_GNUC_UNUSED = false;
+        bool memory_isolation = false;
 
         if (netdev->u.passt.has_memory_isolation &&
-           netdev->u.passt.memory_isolation) {
+            netdev->u.passt.memory_isolation) {
             memory_isolation = true;
         }
 
-        if (net_passt_vhost_user_init(s, errp) == -1) {
+        if (net_passt_vhost_user_init(s, memory_isolation, errp) == -1) {
             qemu_del_net_client(nc);
             return -1;
         }
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 8fa303f901..722ab20228 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -370,7 +370,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event)
 
 static int net_vhost_user_init(NetClientState *peer, const char *device,
                                const char *name, Chardev *chr,
-                               int queues)
+                               int queues, bool memory_isolation)
 {
     Error *err = NULL;
     NetClientState *nc, *nc0 = NULL;
@@ -390,7 +390,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
             nc0 = nc;
             s = DO_UPCAST(NetVhostUserState, nc, nc);
             if (!qemu_chr_fe_init(&s->chr, chr, &err) ||
-                !vhost_user_init(user, &s->chr, &err)) {
+                !vhost_user_init(user, &s->chr, memory_isolation, &err)) {
                 error_report_err(err);
                 goto err;
             }
@@ -459,7 +459,7 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
     int queues;
     const NetdevVhostUserOptions *vhost_user_opts;
     Chardev *chr;
-    bool memory_isolation G_GNUC_UNUSED;
+    bool memory_isolation;
 
     assert(netdev->type == NET_CLIENT_DRIVER_VHOST_USER);
     vhost_user_opts = &netdev->u.vhost_user;
@@ -480,5 +480,6 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
     memory_isolation = vhost_user_opts->has_memory_isolation ?
                        vhost_user_opts->memory_isolation : false;
 
-    return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
+    return net_vhost_user_init(peer, "vhost_user", name, chr, queues,
+                               memory_isolation);
 }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 06/15] util/iova-tree: g_tree_foreach wrapper
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (4 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 05/15] vhost-user: add memory_isolation to VhostUserState Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 07/15] hw/virtio: iova_tree_foreach wrapper Connor Kite
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Add a wrapper to iova-tree to call g_tree_foreach.  Provies a means to
execute some function on each node of the iova-tree.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 include/qemu/iova-tree.h | 13 +++++++++++++
 util/iova-tree.c         |  5 +++++
 2 files changed, 18 insertions(+)

diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index 14e82a22d5..4d77f4dc57 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -161,4 +161,17 @@ int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin,
  */
 void iova_tree_destroy(IOVATree *tree);
 
+/**
+ * iova_tree_foreach:
+ *
+ * @tree: the iova tree to traverse
+ * @func: the function called at every node. A true return value ends traversal
+ * @data: an argument passed to func
+ *
+ * Wrapper to call g_tree_foreach on underlying g_tree
+ *
+ * Return: None
+ */
+void iova_tree_foreach(IOVATree *tree, GTraverseFunc func, gpointer data);
+
 #endif
diff --git a/util/iova-tree.c b/util/iova-tree.c
index 5b0c95ff15..2239bb6ae1 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -303,3 +303,8 @@ int gpa_tree_insert(IOVATree *tree, const DMAMap *map)
 
     return IOVA_OK;
 }
+
+void iova_tree_foreach(IOVATree *tree, GTraverseFunc func, gpointer data)
+{
+    g_tree_foreach(tree->tree, func, data);
+}

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 07/15] hw/virtio: iova_tree_foreach wrapper
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (5 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 06/15] util/iova-tree: g_tree_foreach wrapper Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-24 11:14   ` Akihiko Odaki
  2026-07-23 22:30 ` [PATCH RFC 08/15] hw/virtio/vhost-shadow-virtqueue: used handler Connor Kite
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Add a wrapper to vhost-iova-tree that calls iova_tree_foreach on the
underlying iova_map.  This provides a means to execute some function on
each node of the tree.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-iova-tree.c | 15 +++++++++++++++
 hw/virtio/vhost-iova-tree.h |  3 +++
 2 files changed, 18 insertions(+)

diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c
index fa4147b773..d8206379bf 100644
--- a/hw/virtio/vhost-iova-tree.c
+++ b/hw/virtio/vhost-iova-tree.c
@@ -189,3 +189,18 @@ void vhost_iova_tree_remove_gpa(VhostIOVATree *iova_tree, DMAMap map)
     iova_tree_remove(iova_tree->gpa_iova_map, map);
     iova_tree_remove(iova_tree->iova_map, map);
 }
+
+
+/**
+ * Traverse through the iova tree in sorted order
+ *
+ * @tree: The VhostIOVATree
+ * @func: Function called at every node.  A false return value ends traversal
+ * @data: An argument passed to func
+ */
+void vhost_iova_tree_foreach(VhostIOVATree *tree,
+                             GTraverseFunc func,
+                             gpointer data)
+{
+    iova_tree_foreach(tree->iova_map, func, data);
+}
diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h
index 08f63b61cd..f3b7c48cb9 100644
--- a/hw/virtio/vhost-iova-tree.h
+++ b/hw/virtio/vhost-iova-tree.h
@@ -29,5 +29,8 @@ const DMAMap *vhost_iova_tree_find_gpa(const VhostIOVATree *iova_tree,
 int vhost_iova_tree_map_alloc_gpa(VhostIOVATree *iova_tree, DMAMap *map,
                                   hwaddr taddr);
 void vhost_iova_tree_remove_gpa(VhostIOVATree *iova_tree, DMAMap map);
+void vhost_iova_tree_foreach(VhostIOVATree *tree, GTraverseFunc func,
+                               gpointer data);
+
 
 #endif

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 08/15] hw/virtio/vhost-shadow-virtqueue: used handler
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (6 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 07/15] hw/virtio: iova_tree_foreach wrapper Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-24 11:29   ` Akihiko Odaki
  2026-07-23 22:30 ` [PATCH RFC 09/15] hw/virtio/vhost-shadow-virtqueue: specified vring placement Connor Kite
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Adds a handler callback to shadow virtqueues in order to enable
non-default processing of used vring elements from the device.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-shadow-virtqueue.c |  4 ++++
 hw/virtio/vhost-shadow-virtqueue.h | 14 ++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index bcb7f2ffc7..eb86c1ee37 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -669,6 +669,10 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
                 break;
             }
 
+            if (svq->ops && svq->ops->used_handler) {
+                svq->ops->used_handler(svq, elem, svq->ops_opaque);
+            }
+
             if (unlikely(i >= svq->vring.num)) {
                 qemu_log_mask(LOG_GUEST_ERROR,
                          "More than %u used buffers obtained in a %u size SVQ",
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
index ec16a1e838..ccfeee36d7 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -56,8 +56,22 @@ typedef int (*VirtQueueAvailCallback)(VhostShadowVirtqueue *svq,
                                       VirtQueueElement *elem,
                                       void *vq_callback_opaque);
 
+/**
+ * Callback to handle a used buffer
+ *
+ * @svq: Shadow virtqueue
+ * @elem: Element placed in the queue by the device
+ * @vq_callback_opaque: Used to pass arguments to callback
+ *
+ * Returns 0 if the vq is running as expected
+ */
+typedef int (*VirtQueueUsedCallback)(VhostShadowVirtqueue *svq,
+                                      VirtQueueElement *elem,
+                                      void *vq_callback_opaque);
+
 typedef struct VhostShadowVirtqueueOps {
     VirtQueueAvailCallback avail_handler;
+    VirtQueueUsedCallback used_handler;
 } VhostShadowVirtqueueOps;
 
 /* Shadow virtqueue to relay notifications */

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 09/15] hw/virtio/vhost-shadow-virtqueue: specified vring placement
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (7 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 08/15] hw/virtio/vhost-shadow-virtqueue: used handler Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 10/15] hw/virtio/vhost-shadow-virtqueue: range boundary in translation Connor Kite
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

By default svq vrings are placed in an anonymous memory map. As svqs
will be leveraged to enable memory isolation in vhost-user, it is useful
to be able to place the vrings in a shared isolation memory region.

Adds the option to specify vring placement by providing a vring base
address before starting the svq.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-shadow-virtqueue.c | 22 +++++++++++++++-------
 hw/virtio/vhost-shadow-virtqueue.h |  3 +++
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index eb86c1ee37..9e3c359f50 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -857,14 +857,21 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
 
     svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq));
     svq->num_free = svq->vring.num;
-    svq->vring.desc = mmap(NULL, vhost_svq_driver_area_size(svq),
-                           PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-                           -1, 0);
     desc_size = sizeof(vring_desc_t) * svq->vring.num;
-    svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
-    svq->vring.used = mmap(NULL, vhost_svq_device_area_size(svq),
-                           PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-                           -1, 0);
+    if (svq->base_addr == NULL) {
+        svq->vring.desc = mmap(NULL, vhost_svq_driver_area_size(svq),
+                            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
+                            -1, 0);
+        svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
+        svq->vring.used = mmap(NULL, vhost_svq_device_area_size(svq),
+                            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
+                            -1, 0);
+    } else {
+        svq->vring.desc = (void *) svq->base_addr;
+        svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
+        svq->vring.used = (void *)((char *)svq->base_addr +
+                          vhost_svq_driver_area_size(svq));
+    }
     svq->desc_state = g_new0(SVQDescState, svq->vring.num);
     if (virtio_vdev_has_feature(svq->vdev, VIRTIO_F_IN_ORDER)) {
         svq->batch_last.id = VIRTIO_RING_NOT_IN_BATCH;
@@ -929,6 +936,7 @@ VhostShadowVirtqueue *vhost_svq_new(const VhostShadowVirtqueueOps *ops,
     event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
     svq->ops = ops;
     svq->ops_opaque = ops_opaque;
+    svq->base_addr = NULL;
     return svq;
 }
 
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
index ccfeee36d7..39f69e6455 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -148,6 +148,9 @@ typedef struct VhostShadowVirtqueue {
 
     /* Size of SVQ vring free descriptors */
     uint16_t num_free;
+
+    /* Location assigned to vrings if not in default anon memory map*/
+    hwaddr *base_addr;
 } VhostShadowVirtqueue;
 
 bool vhost_svq_valid_features(uint64_t features, Error **errp);

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 10/15] hw/virtio/vhost-shadow-virtqueue: range boundary in translation
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (8 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 09/15] hw/virtio/vhost-shadow-virtqueue: specified vring placement Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 11/15] hw/virtio/vhost-user: create isolation region Connor Kite
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

iova-tree expects inclusive range sizing when maps are allocated or searched.
Currently, svqs use exclusive sizing when searching their
vhost-iova-tree for a match to the region to be translated.  This could
lead to errors if the region to be translated is at the edge of an iova
region.

Fix this by reducing `needle.size` by 1 in
vhost_svq_translate_addr to bring then it line with DMAMap and iova-tree
convention.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-shadow-virtqueue.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 9e3c359f50..20e5c7d2f1 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -104,14 +104,14 @@ static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq,
             /* Search the GPA->IOVA tree */
             needle = (DMAMap) {
                 .translated_addr = gpas[i],
-                .size = iovec[i].iov_len,
+                .size = iovec[i].iov_len - 1,  /* Inclusive */
             };
             map = vhost_iova_tree_find_gpa(svq->iova_tree, &needle);
         } else {
             /* Search the IOVA->HVA tree */
             needle = (DMAMap) {
                 .translated_addr = (hwaddr)(uintptr_t)iovec[i].iov_base,
-                .size = iovec[i].iov_len,
+                .size = iovec[i].iov_len - 1, /* Inclusive */
             };
             map = vhost_iova_tree_find_iova(svq->iova_tree, &needle);
         }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 11/15] hw/virtio/vhost-user: create isolation region
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (9 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 10/15] hw/virtio/vhost-shadow-virtqueue: range boundary in translation Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 12/15] hw/virtio/vhost-user: send isolation regions to device Connor Kite
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

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 | 129 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index f296b63fb9..710cf966f8 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,13 @@ static VhostUserMsg m __attribute__ ((unused));
 /* The version of the protocol we support */
 #define VHOST_USER_VERSION    (0x1)
 
+typedef struct IsolationRegion {
+    uint64_t base_addr;
+    uint64_t vring_base_addr;
+    uint64_t size;
+    int iso_fd;
+} IsolationRegion;
+
 struct vhost_user {
     struct vhost_dev *dev;
     /* Shared between vhost devs of the same virtio device */
@@ -353,6 +362,10 @@ struct vhost_user {
      * by the backend (see @features).
      */
     uint64_t protocol_features;
+
+    /* Isolated memory data*/
+    struct IsolationRegion iso_memory;
+    VhostIOVATree *iso_iova_tree;
 };
 
 struct scrub_regions {
@@ -1109,6 +1122,121 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
     return 0;
 }
 
+/* TODO: Is there any notifier cleanup required here?*/
+static void cleanup_isolation_regions(struct vhost_dev *dev)
+{
+    struct vhost_user *u = dev->opaque;
+    if (u->iso_memory.base_addr) {
+        vhost_iova_tree_delete(u->iso_iova_tree);
+        u->iso_iova_tree = NULL;
+        memset(&u->iso_memory, 0, sizeof(IsolationRegion));
+        qemu_memfd_free((gpointer) u->iso_memory.base_addr, u->iso_memory.size,
+                         u->iso_memory.iso_fd);
+        u->iso_memory.base_addr = 0;
+    }
+}
+
+__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;
+    uint64_t buffer_reg_size = 0;
+    DMAMap newEntry = {
+        .perm = IOMMU_RW
+    };
+    g_autoptr(GArray) buffer_regions =
+        g_array_new(FALSE, TRUE, sizeof(DMAMap));
+
+    msg->hdr.request = VHOST_USER_SET_MEM_TABLE;
+
+    /* In case of reset, clear old regions*/
+    if (u->iso_memory.base_addr != 0) {
+        cleanup_isolation_regions(dev);
+        vhost_iova_tree_delete(u->iso_iova_tree);
+    }
+
+    /* Gather information for bounce buffers to be mapped */
+    for (int i = 0; i < nregions; i++) {
+        struct vhost_memory_region *dev_region = &dev->mem->regions[i];
+        hwaddr size = ROUND_UP(dev_region->memory_size,
+                      qemu_real_host_page_size());
+        newEntry.translated_addr = dev_region->guest_phys_addr;
+        newEntry.size = size - 1;
+        buffer_reg_size += size;
+        g_array_append_val(buffer_regions, newEntry);
+    }
+
+    int num;
+    size_t desc_size;
+    size_t avail_size;
+    size_t driver_area_size;
+    size_t device_area_size;
+    size_t total_vring_size = 0;
+    size_t total_mmap_size;
+
+    /* Get space required for all vrings */
+    for (int j = 0; j < dev->nvqs; j++) {
+        num = virtio_queue_get_num(dev->vdev, dev->vq_index + j);
+        desc_size = sizeof(vring_desc_t) * num;
+        avail_size = offsetof(vring_avail_t, ring[num]) +
+                        sizeof(uint16_t);
+        driver_area_size = ROUND_UP(desc_size + avail_size,
+                            qemu_real_host_page_size());
+        device_area_size = ROUND_UP(offsetof(vring_used_t, ring[num]) +
+                                    sizeof(uint16_t),
+                                    qemu_real_host_page_size());
+        total_vring_size += driver_area_size + device_area_size;
+    }
+
+    total_mmap_size = buffer_reg_size + total_vring_size;
+
+    /* Allocate and map an anonymous file to hold the isolation region */
+    u->iso_memory.base_addr = (uint64_t) qemu_memfd_alloc("iso_r",
+                              total_mmap_size,
+                              F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+                              &u->iso_memory.iso_fd, &err);
+    u->iso_memory.size = total_mmap_size;
+
+    if (err) {
+        error_report_err(err);
+        cleanup_isolation_regions(dev);
+        return -1;
+    }
+
+    uint64_t last_addr = int128_get64(int128_add(u->iso_memory.base_addr,
+                                                 total_mmap_size - 1));
+
+    /*
+     * Instantiates iova tree sized to map bounce buffers and vrings to the
+     * isolation region in host va.
+     */
+    u->iso_iova_tree = vhost_iova_tree_new(u->iso_memory.base_addr, last_addr);
+
+    assert(&u->iso_memory.iso_fd >= 0);
+    DMAMap *map;
+    DMAMap vring_map = {
+        .perm = IOMMU_RW,
+        .size = total_vring_size - 1,
+        /*vrings are allocated on tree first, so will be assigned base addr*/
+        .translated_addr = u->iso_memory.base_addr
+    };
+
+    vhost_iova_tree_map_alloc(u->iso_iova_tree, &vring_map,
+                              vring_map.translated_addr);
+    u->iso_memory.vring_base_addr = vring_map.iova;
+    for (int i = 0; i < buffer_regions->len; i++) {
+        map = &g_array_index(buffer_regions, DMAMap, i);
+        vhost_iova_tree_map_alloc_gpa(u->iso_iova_tree, map,
+                                      map->translated_addr);
+    }
+
+    return 0;
+}
+
 static int vhost_user_set_mem_table(struct vhost_dev *dev,
                                     struct vhost_memory *mem)
 {
@@ -2681,6 +2809,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;
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 12/15] hw/virtio/vhost-user: send isolation regions to device
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (10 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 11/15] hw/virtio/vhost-user: create isolation region Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 13/15] hw/virtio/vhost-user: add shadow virtqueues and eventfd intercepts Connor Kite
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Adds features to fill a vhost_user_set_mem_table message with the
addresses of isolation memory regions corresponding to bounce buffers
and vrings.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-user.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 710cf966f8..acabfb7f1c 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -625,6 +625,21 @@ static void vhost_user_fill_msg_region(struct vhost_dev *dev,
     dst->mmap_offset = mmap_offset;
 }
 
+static void vhost_user_fill_msg_region_iso(VhostUserMemoryRegion *dst,
+                                           const struct vhost_user *u,
+                                           const struct vhost_memory_region
+                                           *iova_reg)
+{
+    assert(u != NULL && dst != NULL && iova_reg != NULL);
+    uint64_t offset;
+
+    offset = iova_reg->userspace_addr - u->iso_memory.base_addr;
+    dst->userspace_addr = iova_reg->userspace_addr;
+    dst->memory_size = iova_reg->memory_size;
+    dst->guest_phys_addr = iova_reg->userspace_addr;
+    dst->mmap_offset = offset;
+}
+
 static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u,
                                              struct vhost_dev *dev,
                                              VhostUserMsg *msg,
@@ -1136,7 +1151,33 @@ static void cleanup_isolation_regions(struct vhost_dev *dev)
     }
 }
 
-__attribute__((unused))
+struct iova_tree_traversal_args {
+    VhostUserMsg *msg;
+    struct vhost_user *u;
+    int *fds;
+    size_t *fd_num;
+};
+
+static gboolean vhost_user_iova_tree_traverse_funct(gpointer key,
+                                                    gpointer value,
+                                                    gpointer data)
+{
+    struct iova_tree_traversal_args *args = data;
+    struct vhost_memory_region msg_region;
+    VhostUserMemoryRegion region_buffer;
+    DMAMap *map = key;
+    args->fds[*args->fd_num] = args->u->iso_memory.iso_fd;
+
+    msg_region.guest_phys_addr = map->iova;
+    msg_region.memory_size = map->size + 1;
+    msg_region.userspace_addr = map->iova;
+    vhost_user_fill_msg_region_iso(&region_buffer, args->u, &msg_region);
+    args->msg->payload.memory.regions[*args->fd_num] = region_buffer;
+    (*args->fd_num)++;
+
+    return false;
+}
+
 static int init_isolation_regions(struct vhost_dev *dev,
                                   VhostUserMsg *msg,
                                   int *fds, size_t *fd_num)
@@ -1234,6 +1275,24 @@ static int init_isolation_regions(struct vhost_dev *dev,
                                       map->translated_addr);
     }
 
+    struct iova_tree_traversal_args args = {
+        .fd_num = fd_num,
+        .fds = fds,
+        .msg = msg,
+        .u = u
+    };
+
+    vhost_iova_tree_foreach(u->iso_iova_tree,
+                            vhost_user_iova_tree_traverse_funct, &args);
+
+    msg->payload.memory.nregions = *fd_num;
+
+    assert(*fd_num != 0);
+
+    msg->hdr.size = sizeof(msg->payload.memory.nregions);
+    msg->hdr.size += sizeof(msg->payload.memory.padding);
+    msg->hdr.size += *fd_num * sizeof(VhostUserMemoryRegion);
+
     return 0;
 }
 
@@ -1241,6 +1300,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
                                     struct vhost_memory *mem)
 {
     struct vhost_user *u = dev->opaque;
+    bool memory_isolation = u->user->memory_isolation;
     int fds[VHOST_MEMORY_BASELINE_NREGIONS];
     size_t fd_num = 0;
     bool do_postcopy = u->postcopy_listen && u->postcopy_fd.handler;
@@ -1268,6 +1328,24 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
         msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
     }
 
+    if (memory_isolation) {
+        ret = init_isolation_regions(dev, &msg, fds, &fd_num);
+        if (ret < 0) {
+            return ret;
+        }
+
+        ret = vhost_user_write(dev, &msg, fds, fd_num);
+        if (ret < 0) {
+            return ret;
+        }
+
+        if (reply_supported) {
+            return process_message_reply(dev, &msg);
+        }
+
+        return 0;
+    }
+
     if (config_mem_slots) {
         ret = vhost_user_add_remove_regions(dev, &msg, reply_supported, false);
         if (ret < 0) {

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 13/15] hw/virtio/vhost-user: add shadow virtqueues and eventfd intercepts
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (11 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 12/15] hw/virtio/vhost-user: send isolation regions to device Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 14/15] hw/virtio/vhost-user: handle data movement with shadow vqs Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 15/15] hw/virtio/vhost-user: shadow vq cleanup Connor Kite
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Adds shadow virtqueues that will eventually be used to transfer data
between device and host via bounce buffers when isolation mode is
active.  The svqs are initalized, and eventfd assignments are
intercepted so that notifications come to svqs first before
the guest or backend receive them.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-user.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index acabfb7f1c..75858289a2 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-shadow-virtqueue.h"
 #include "hw/virtio/vhost-iova-tree.h"
 #include "chardev/char-fe.h"
 #include "io/channel-socket.h"
@@ -365,7 +366,9 @@ struct vhost_user {
 
     /* Isolated memory data*/
     struct IsolationRegion iso_memory;
+    GPtrArray *shadow_vqs;
     VhostIOVATree *iso_iova_tree;
+    bool svqs_allocated;
 };
 
 struct scrub_regions {
@@ -1693,6 +1696,24 @@ static int vhost_set_vring_file(struct vhost_dev *dev,
 static int vhost_user_set_vring_kick(struct vhost_dev *dev,
                                      struct vhost_vring_file *file)
 {
+    struct vhost_user *u = dev->opaque;
+    int svq_idx = file->index - dev->vq_index;
+    if (u->user->memory_isolation) {
+        VhostShadowVirtqueue *svq = g_ptr_array_index(u->shadow_vqs,
+                                                      svq_idx);
+        vhost_svq_set_svq_kick_fd(svq, file->fd);
+
+        if (svq->hdev_kick.initialized == false) {
+            int r = event_notifier_init(&svq->hdev_kick, 0);
+            if (r) {
+                error_report("Failed to create kick event notifier");
+                return r;
+            }
+        }
+
+        file->fd = event_notifier_get_fd(&svq->hdev_kick);
+    }
+
     int ret = vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
     if (ret < 0) {
         return ret;
@@ -1721,6 +1742,24 @@ static int vhost_user_set_vring_kick(struct vhost_dev *dev,
 static int vhost_user_set_vring_call(struct vhost_dev *dev,
                                      struct vhost_vring_file *file)
 {
+    struct vhost_user *u = dev->opaque;
+    int svq_idx = file->index - dev->vq_index;
+    if (u->user->memory_isolation) {
+        VhostShadowVirtqueue *svq = g_ptr_array_index(u->shadow_vqs,
+                                                      svq_idx);
+        vhost_svq_set_svq_call_fd(svq, file->fd);
+
+        if (svq->hdev_call.initialized == false) {
+            int r = event_notifier_init(&svq->hdev_call, 0);
+            if (r) {
+                error_report("Failed to create call event notifier");
+                return r;
+            }
+        }
+
+        file->fd = event_notifier_get_fd(&svq->hdev_call);
+    }
+
     return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
 }
 
@@ -2715,6 +2754,17 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
     return 0;
 }
 
+static void vhost_user_init_svq(struct vhost_dev *dev, struct vhost_user *u)
+{
+    /*Modified from vhost-vdpa*/
+    u->shadow_vqs = g_ptr_array_new_full(dev->nvqs, vhost_svq_free);
+    for (int i = 0; i < dev->nvqs; i++) {
+        VhostShadowVirtqueue *svq;
+        svq = vhost_svq_new(NULL, NULL);
+        g_ptr_array_add(u->shadow_vqs, svq);
+    }
+}
+
 static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
                                    Error **errp)
 {
@@ -2859,6 +2909,10 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
     u->postcopy_notifier.notify = vhost_user_postcopy_notifier;
     postcopy_add_notifier(&u->postcopy_notifier);
 
+    if (vus->memory_isolation) {
+        vhost_user_init_svq(dev, u);
+    }
+
     return 0;
 }
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 14/15] hw/virtio/vhost-user: handle data movement with shadow vqs
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (12 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 13/15] hw/virtio/vhost-user: add shadow virtqueues and eventfd intercepts Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  2026-07-23 22:30 ` [PATCH RFC 15/15] hw/virtio/vhost-user: shadow vq cleanup Connor Kite
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

- Add start logic for shadow virtqueues, which sets vring addresses.
- Update logic for sending vring addresses to backend to point
  to the shadow vrings when isolation mode is active.
- Implement handlers for intercepted avail and used descriptors. These
  handlers copy buffer contents between bounce buffers in the isolation
  region and the buffers made available by the guest
- Implement logic to stop svqs

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-user.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 166 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 75858289a2..e65f877f9a 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1299,6 +1299,97 @@ static int init_isolation_regions(struct vhost_dev *dev,
     return 0;
 }
 
+static int vhost_user_memory_lookup(struct vhost_dev *dev, hwaddr gpa,
+                                    hwaddr *hva)
+{
+    int i;
+    hwaddr offset;
+
+    for (i = 0; i < dev->mem->nregions; i++) {
+        struct vhost_memory_region *reg = dev->mem->regions + i;
+
+        if (gpa >= reg->guest_phys_addr &&
+            reg->guest_phys_addr + reg->memory_size > gpa) {
+            offset = gpa - reg->guest_phys_addr;
+            *hva = reg->userspace_addr + offset;
+            return 0;
+        }
+    }
+
+    return -EFAULT;
+}
+
+static int vhost_user_svq_handle_used(VhostShadowVirtqueue *svq,
+                                      VirtQueueElement *elem,
+                                      void *opaque)
+{
+    hwaddr hva;
+    int r;
+    struct vhost_dev *dev = opaque;
+
+    for (int i = 0; i < elem->in_num; i++) {
+        r = vhost_user_memory_lookup(dev, elem->in_addr[i], &hva);
+        if (r < 0) {
+            return r;
+        }
+
+        memcpy((void *) hva, elem->in_sg[i].iov_base, elem->in_sg[i].iov_len);
+        elem->in_sg[i].iov_base = (void *) hva;
+    }
+
+    for (int i = 0; i < elem->out_num; i++) {
+        r = vhost_user_memory_lookup(dev, elem->out_addr[i], &hva);
+        if (r < 0) {
+            return r;
+        }
+
+        memcpy((void *) hva, elem->out_sg[i].iov_base, elem->out_sg[i].iov_len);
+        elem->out_sg[i].iov_base = (void *) hva;
+    }
+
+    return 0;
+}
+
+static int vhost_user_svq_handle_avail(VhostShadowVirtqueue *svq,
+                                       VirtQueueElement *elem,
+                                       void *opaque)
+{
+    hwaddr offset;
+    const DMAMap *map;
+    DMAMap needle;
+    hwaddr *iova_base;
+
+    for (int i = 0; i < elem->out_num; i++) {
+        needle.translated_addr = elem->out_addr[i];
+        needle.size = elem->out_sg[i].iov_len - 1;
+        map = vhost_iova_tree_find_gpa(svq->iova_tree, &needle);
+        offset = needle.translated_addr - map->translated_addr;
+        iova_base = (void *)(map->iova + offset);
+
+        elem->out_sg[i].iov_base = iova_base;
+        memcpy(iova_base, elem->out_sg[i].iov_base, needle.size + 1);
+    }
+
+    for (int i = 0; i < elem->in_num; i++) {
+        needle.translated_addr = elem->in_addr[i];
+        needle.size = elem->in_sg[i].iov_len - 1;
+        map = vhost_iova_tree_find_gpa(svq->iova_tree, &needle);
+        offset = needle.translated_addr - map->translated_addr;
+        iova_base = (void *)(map->iova + offset);
+
+        elem->in_sg[i].iov_base = iova_base;
+        memcpy(iova_base, elem->in_sg[i].iov_base, needle.size + 1);
+    }
+
+    vhost_svq_add(svq, elem->out_sg, elem->out_num, elem->out_addr,
+                  elem->in_sg, elem->in_num, elem->in_addr, elem);
+
+    return 0;
+}
+
+
+
+
 static int vhost_user_set_mem_table(struct vhost_dev *dev,
                                     struct vhost_memory *mem)
 {
@@ -1772,6 +1863,8 @@ static int vhost_user_set_vring_err(struct vhost_dev *dev,
 static int vhost_user_set_vring_addr(struct vhost_dev *dev,
                                      struct vhost_vring_addr *addr)
 {
+    struct vhost_user *u = dev->opaque;
+
     VhostUserMsg msg = {
         .hdr.request = VHOST_USER_SET_VRING_ADDR,
         .hdr.flags = VHOST_USER_VERSION,
@@ -1779,6 +1872,25 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev,
         .hdr.size = sizeof(msg.payload.addr),
     };
 
+    if (u->user->memory_isolation) {
+        if (!u->svqs_allocated) {
+            return 0;
+        }
+
+        int svq_idx = addr->index - dev->vq_index;
+        VhostShadowVirtqueue *svq = g_ptr_array_index(u->shadow_vqs,
+                                                      svq_idx);
+
+        struct vhost_vring_addr svq_addr = {
+            .avail_user_addr = (uint64_t)(uintptr_t)svq->vring.avail,
+            .desc_user_addr = (uint64_t)(uintptr_t)svq->vring.desc,
+            .used_user_addr = (uint64_t)(uintptr_t)svq->vring.used,
+            .index = addr->index,
+        };
+
+        msg.payload.addr = svq_addr;
+    }
+
     /*
      * wait for a reply if logging is enabled to make sure
      * backend is actually logging changes
@@ -2754,13 +2866,18 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
     return 0;
 }
 
+static const VhostShadowVirtqueueOps vhost_user_svq_ops = {
+    .avail_handler = vhost_user_svq_handle_avail,
+    .used_handler = vhost_user_svq_handle_used
+};
+
 static void vhost_user_init_svq(struct vhost_dev *dev, struct vhost_user *u)
 {
     /*Modified from vhost-vdpa*/
     u->shadow_vqs = g_ptr_array_new_full(dev->nvqs, vhost_svq_free);
     for (int i = 0; i < dev->nvqs; i++) {
         VhostShadowVirtqueue *svq;
-        svq = vhost_svq_new(NULL, NULL);
+        svq = vhost_svq_new(&vhost_user_svq_ops, dev);
         g_ptr_array_add(u->shadow_vqs, svq);
     }
 }
@@ -3466,8 +3583,56 @@ void vhost_user_async_close(DeviceState *d,
     }
 }
 
+static bool vhost_user_svqs_start(struct vhost_dev *dev)
+{
+    struct vhost_user *u = dev->opaque;
+    uint64_t vring_base = u->iso_memory.vring_base_addr;
+    u->svqs_allocated = true;
+
+    for (int i = 0; i < u->shadow_vqs->len; i++) {
+        VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
+        VhostShadowVirtqueue *svq = g_ptr_array_index(u->shadow_vqs, i);
+        svq->base_addr = (hwaddr *) vring_base;
+        vhost_svq_start(svq, dev->vdev, vq, u->iso_iova_tree);
+
+        struct vhost_vring_addr addr = {
+            .index = dev->vq_index + i,
+            .desc_user_addr = vring_base,
+            .avail_user_addr = vring_base + sizeof(vring_desc_t) *
+                svq->vring.num,
+            .used_user_addr = vring_base + vhost_svq_driver_area_size(svq)
+        };
+
+        vhost_user_set_vring_addr(dev, &addr);
+
+        vring_base += vhost_svq_device_area_size(svq) +
+                      vhost_svq_driver_area_size(svq);
+    }
+
+    return false;
+}
+
+static void vhost_user_svqs_stop(struct vhost_dev *dev)
+{
+    struct vhost_user *u = dev->opaque;
+
+    for (int i = 0; i < u->shadow_vqs->len; i++) {
+        vhost_svq_stop(g_ptr_array_index(u->shadow_vqs, i));
+    }
+}
+
+
 static int vhost_user_dev_start(struct vhost_dev *dev, bool started)
 {
+    struct vhost_user *u = dev->opaque;
+    if (u->user->memory_isolation) {
+        if (started) {
+            vhost_user_svqs_start(dev);
+        } else {
+            vhost_user_svqs_stop(dev);
+        }
+    }
+
     if (!vhost_user_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_STATUS)) {
         return 0;
     }

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC 15/15] hw/virtio/vhost-user: shadow vq cleanup
  2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
                   ` (13 preceding siblings ...)
  2026-07-23 22:30 ` [PATCH RFC 14/15] hw/virtio/vhost-user: handle data movement with shadow vqs Connor Kite
@ 2026-07-23 22:30 ` Connor Kite
  14 siblings, 0 replies; 23+ messages in thread
From: Connor Kite @ 2026-07-23 22:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Akihiko Odaki, Dmitry Osipenko, qemu-block,
	virtio-fs, Gonglei (Arei), zhenwei pi, Daniel P. Berrangé,
	Eric Blake, Markus Armbruster, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour, Connor Kite

Implements functionality to cleanup svqs on cleanup of isolation
regions.

Signed-off-by: Connor Kite <connorkite@gmail.com>
---
 hw/virtio/vhost-user.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index e65f877f9a..bb4de78b95 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1140,6 +1140,15 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
     return 0;
 }
 
+static void vhost_user_svq_cleanup(struct vhost_user *u)
+{
+    for (int i = 0; i < u->shadow_vqs->len; i++) {
+        vhost_svq_stop(g_ptr_array_index(u->shadow_vqs, i));
+    }
+
+    g_ptr_array_free(u->shadow_vqs, true);
+}
+
 /* TODO: Is there any notifier cleanup required here?*/
 static void cleanup_isolation_regions(struct vhost_dev *dev)
 {
@@ -1147,6 +1156,7 @@ static void cleanup_isolation_regions(struct vhost_dev *dev)
     if (u->iso_memory.base_addr) {
         vhost_iova_tree_delete(u->iso_iova_tree);
         u->iso_iova_tree = NULL;
+        vhost_user_svq_cleanup(u);
         memset(&u->iso_memory, 0, sizeof(IsolationRegion));
         qemu_memfd_free((gpointer) u->iso_memory.base_addr, u->iso_memory.size,
                          u->iso_memory.iso_fd);

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool
  2026-07-23 22:30 ` [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool Connor Kite
@ 2026-07-24  6:06   ` Markus Armbruster
  2026-07-24 11:03   ` Akihiko Odaki
  1 sibling, 0 replies; 23+ messages in thread
From: Markus Armbruster @ 2026-07-24  6:06 UTC (permalink / raw)
  To: Connor Kite
  Cc: qemu-devel, Michael S. Tsirkin, Stefano Garzarella,
	Alex Bennée, Viresh Kumar, Gerd Hoffmann, Mathieu Poirier,
	Manos Pitsidianakis, Haixu Cui, Raphael Norwitz, Kevin Wolf,
	Hanna Reitz, Marc-André Lureau, Paolo Bonzini, Fam Zheng,
	Stefan Hajnoczi, Milan Zamazal, Akihiko Odaki, Dmitry Osipenko,
	qemu-block, virtio-fs, Gonglei (Arei), zhenwei pi,
	Daniel P. Berrangé, Eric Blake, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour

Connor Kite <connorkite@gmail.com> writes:

> Add a memory_isolation property to CryptoDevBackendVhostUser and
> add add it as an optional member of CryptodevVhostUserProperties
> in qapi.
>
> This is needed to be able to specify memory isolation for
> cryptodev-vhost-user objects, and the bool will eventually be
> passed to vhost_user_init() in a future patch.
>
> Signed-off-by: Connor Kite <connorkite@gmail.com>

[...]

> diff --git a/qapi/qom.json b/qapi/qom.json
> index c55776af7d..d7ca1b4203 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -350,11 +350,15 @@
>  # @chardev: the name of a Unix domain socket character device that
>  #     connects to the vhost-user server
>  #
> +# @memory-isolation: disables access from cryptodev to guest memory.
> +#     (default: false)

Want imperative mood and need "since", like this:

   # @memory-isolation: disable access from cryptodev to guest memory.
   #     (default: false) (since 11.2)

Pardon my ignorance...  What exactly is "cryptodev" here?  Is it code
running in another process?

Should the description answer my question?  Perhaps like this:

  # @memory-isolation: isolate guest memory.  Isolated guest memory
  #     cannot be accessed from uh, what exactly?

Fill in the blank.

> +#
>  # Since: 2.12
>  ##
>  { 'struct': 'CryptodevVhostUserProperties',
>    'base': 'CryptodevBackendProperties',
> -  'data': { 'chardev': 'str' },
> +  'data': { 'chardev': 'str',
> +            '*memory-isolation': 'bool' },
>    'if': 'CONFIG_VHOST_CRYPTO' }
>  
>  ##


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions
  2026-07-23 22:30 ` [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions ConKite
@ 2026-07-24  6:09   ` Markus Armbruster
  0 siblings, 0 replies; 23+ messages in thread
From: Markus Armbruster @ 2026-07-24  6:09 UTC (permalink / raw)
  To: ConKite
  Cc: qemu-devel, Michael S. Tsirkin, Stefano Garzarella,
	Alex Bennée, Viresh Kumar, Gerd Hoffmann, Mathieu Poirier,
	Manos Pitsidianakis, Haixu Cui, Raphael Norwitz, Kevin Wolf,
	Hanna Reitz, Marc-André Lureau, Paolo Bonzini, Fam Zheng,
	Stefan Hajnoczi, Milan Zamazal, Akihiko Odaki, Dmitry Osipenko,
	qemu-block, virtio-fs, Gonglei (Arei), zhenwei pi,
	Daniel P. Berrangé, Eric Blake, Jason Wang, Peter Xu,
	Eugenio Pérez, Alyssa Ross, Demi Marie Obenour

This patch and the next one are From: ConKite, whereas the remainder are
From: Connor Kite, which is nicer.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 02/15] vhost-user: Add memory-isolation qdev property to vhost-user devices
  2026-07-23 22:30 ` [PATCH RFC 02/15] vhost-user: Add memory-isolation qdev property to vhost-user devices ConKite
@ 2026-07-24 10:56   ` Akihiko Odaki
  0 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2026-07-24 10:56 UTC (permalink / raw)
  To: ConKite, qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Dmitry Osipenko, qemu-block, virtio-fs,
	Gonglei (Arei), zhenwei pi, Daniel P. Berrangé, Eric Blake,
	Markus Armbruster, Jason Wang, Peter Xu, Eugenio Pérez,
	Alyssa Ross, Demi Marie Obenour

On 2026/07/24 7:30, ConKite wrote:
> In support of future work to add a memory isolation mode to vhost-user devices, a
> qdev property, "memory-isolation", is added to all vhost-user devices. This is
> simply a bool representing whether the mode is active or not.
> 
> Signed-off-by: Connor Kite <connorkite@gmail.com>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

This and the next patch add interfaces before implementation. Perhaps 
it's better reversed.

Regards,
Akihiko Odaki

> ---
>   hw/block/vhost-user-blk.c            | 1 +
>   hw/display/vhost-user-gpu.c          | 1 +
>   hw/scsi/vhost-user-scsi.c            | 1 +
>   hw/virtio/vhost-user-base.c          | 3 ++-
>   hw/virtio/vhost-user-fs.c            | 1 +
>   hw/virtio/vhost-user-scmi.c          | 1 +
>   hw/virtio/vhost-user-vsock.c         | 1 +
>   include/hw/virtio/vhost-user-base.h  | 1 +
>   include/hw/virtio/vhost-user-blk.h   | 1 +
>   include/hw/virtio/vhost-user-fs.h    | 1 +
>   include/hw/virtio/vhost-user-scmi.h  | 1 +
>   include/hw/virtio/vhost-user-vsock.h | 1 +
>   include/hw/virtio/virtio-gpu.h       | 1 +
>   include/hw/virtio/virtio-scsi.h      | 1 +
>   14 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index 2e5b3ae1b1..9830dc6c35 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -631,6 +631,7 @@ static const VMStateDescription vmstate_vhost_user_blk = {
>   
>   static const Property vhost_user_blk_properties[] = {
>       DEFINE_PROP_CHR("chardev", VHostUserBlk, chardev),
> +    DEFINE_PROP_BOOL("memory-isolation", VHostUserBlk, memory_isolation, false),
>       DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues,
>                          VHOST_USER_BLK_AUTO_NUM_QUEUES),
>       DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
> diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
> index 57360898ca..6d0ede672a 100644
> --- a/hw/display/vhost-user-gpu.c
> +++ b/hw/display/vhost-user-gpu.c
> @@ -659,6 +659,7 @@ static struct vhost_dev *vhost_user_gpu_get_vhost(VirtIODevice *vdev)
>   
>   static const Property vhost_user_gpu_properties[] = {
>       VIRTIO_GPU_BASE_PROPERTIES(VhostUserGPU, parent_obj.conf),
> +    DEFINE_PROP_BOOL("memory-isolation", VhostUserGPU, memory_isolation, false),
>   };
>   
>   static void
> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> index 5070178dc2..c1a0393220 100644
> --- a/hw/scsi/vhost-user-scsi.c
> +++ b/hw/scsi/vhost-user-scsi.c
> @@ -346,6 +346,7 @@ static void vhost_user_scsi_unrealize(DeviceState *dev)
>   
>   static const Property vhost_user_scsi_properties[] = {
>       DEFINE_PROP_CHR("chardev", VirtIOSCSICommon, conf.chardev),
> +    DEFINE_PROP_BOOL("memory-isolation", VirtIOSCSICommon, conf.memory_isolation, false),
>       DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
>       DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
>                          VIRTIO_SCSI_AUTO_NUM_QUEUES),
> diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
> index 90bd2903db..d2a74a2860 100644
> --- a/hw/virtio/vhost-user-base.c
> +++ b/hw/virtio/vhost-user-base.c
> @@ -409,7 +409,8 @@ static void vub_device_unrealize(DeviceState *dev)
>   
>   /*Define common qdev properties.  Inherited by all children*/
>   static const Property vub_properties[] = {
> -    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev)
> +    DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
> +    DEFINE_PROP_BOOL("memory-isolation", VHostUserBase, memory_isolation, false)
>   };
>   
>   
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> index 209993918a..3d980d814b 100644
> --- a/hw/virtio/vhost-user-fs.c
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -410,6 +410,7 @@ static const VMStateDescription vuf_backend_vmstate = {
>   
>   static const Property vuf_properties[] = {
>       DEFINE_PROP_CHR("chardev", VHostUserFS, conf.chardev),
> +    DEFINE_PROP_BOOL("memory-isolation", VHostUserFS, conf.memory_isolation, false),
>       DEFINE_PROP_STRING("tag", VHostUserFS, conf.tag),
>       DEFINE_PROP_UINT16("num-request-queues", VHostUserFS,
>                          conf.num_request_queues, 1),
> diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c
> index 02dc088ea9..d514d89392 100644
> --- a/hw/virtio/vhost-user-scmi.c
> +++ b/hw/virtio/vhost-user-scmi.c
> @@ -287,6 +287,7 @@ static const VMStateDescription vu_scmi_vmstate = {
>   
>   static const Property vu_scmi_properties[] = {
>       DEFINE_PROP_CHR("chardev", VHostUserSCMI, chardev),
> +    DEFINE_PROP_BOOL("memory-isolation", VHostUserSCMI, memory_isolation, false),
>   };
>   
>   static void vu_scmi_class_init(ObjectClass *klass, const void *data)
> diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
> index c2cd376e73..89aa789e22 100644
> --- a/hw/virtio/vhost-user-vsock.c
> +++ b/hw/virtio/vhost-user-vsock.c
> @@ -154,6 +154,7 @@ static void vuv_device_unrealize(DeviceState *dev)
>   
>   static const Property vuv_properties[] = {
>       DEFINE_PROP_CHR("chardev", VHostUserVSock, conf.chardev),
> +    DEFINE_PROP_BOOL("memory-isolation", VHostUserVSock, conf.memory_isolation, false),
>   };
>   
>   static void vuv_class_init(ObjectClass *klass, const void *data)
> diff --git a/include/hw/virtio/vhost-user-base.h b/include/hw/virtio/vhost-user-base.h
> index d5d2f081ae..29bc40736c 100644
> --- a/include/hw/virtio/vhost-user-base.h
> +++ b/include/hw/virtio/vhost-user-base.h
> @@ -25,6 +25,7 @@ struct VHostUserBase {
>       uint32_t num_vqs;
>       uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
>       uint32_t config_size;
> +    bool memory_isolation;
>       /* State tracking */
>       VhostUserState vhost_user;
>       struct vhost_virtqueue *vhost_vq;
> diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
> index dee848cfd8..8126447a86 100644
> --- a/include/hw/virtio/vhost-user-blk.h
> +++ b/include/hw/virtio/vhost-user-blk.h
> @@ -30,6 +30,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserBlk, VHOST_USER_BLK)
>   struct VHostUserBlk {
>       VirtIODevice parent_obj;
>       CharFrontend chardev;
> +    bool memory_isolation;
>       int32_t bootindex;
>       struct virtio_blk_config blkcfg;
>       uint16_t num_queues;
> diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h
> index 5699ea03a1..bf71990b9c 100644
> --- a/include/hw/virtio/vhost-user-fs.h
> +++ b/include/hw/virtio/vhost-user-fs.h
> @@ -28,6 +28,7 @@ typedef struct {
>       char *tag;
>       uint16_t num_request_queues;
>       uint16_t queue_size;
> +    bool memory_isolation;
>   } VHostUserFSConf;
>   
>   struct VHostUserFS {
> diff --git a/include/hw/virtio/vhost-user-scmi.h b/include/hw/virtio/vhost-user-scmi.h
> index 30ab0d7ab7..d346b42ed8 100644
> --- a/include/hw/virtio/vhost-user-scmi.h
> +++ b/include/hw/virtio/vhost-user-scmi.h
> @@ -19,6 +19,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSCMI, VHOST_USER_SCMI);
>   struct VHostUserSCMI {
>       VirtIODevice parent;
>       CharFrontend chardev;
> +    bool memory_isolation;
>       struct vhost_virtqueue *vhost_vqs;
>       struct vhost_dev vhost_dev;
>       VhostUserState vhost_user;
> diff --git a/include/hw/virtio/vhost-user-vsock.h b/include/hw/virtio/vhost-user-vsock.h
> index 5db6938b8b..6288b26fa4 100644
> --- a/include/hw/virtio/vhost-user-vsock.h
> +++ b/include/hw/virtio/vhost-user-vsock.h
> @@ -21,6 +21,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserVSock, VHOST_USER_VSOCK)
>   
>   typedef struct {
>       CharFrontend chardev;
> +    bool memory_isolation;
>   } VHostUserVSockConf;
>   
>   struct VHostUserVSock {
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index b9bad27c97..707612c3a4 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -277,6 +277,7 @@ struct VhostUserGPU {
>       CharFrontend vhost_chr;
>       QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
>       bool backend_blocked;
> +    bool memory_isolation;
>   };
>   
>   #define MAX_SLOTS 4096
> diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
> index b6028bb5cd..47fdc3785c 100644
> --- a/include/hw/virtio/virtio-scsi.h
> +++ b/include/hw/virtio/virtio-scsi.h
> @@ -59,6 +59,7 @@ struct VirtIOSCSIConf {
>       char *vhostfd;
>       char *wwpn;
>       CharFrontend chardev;
> +    bool memory_isolation;
>       uint32_t boot_tpgt;
>       IOThread *iothread;
>       IOThreadVirtQueueMappingList *iothread_vq_mapping_list;
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool
  2026-07-23 22:30 ` [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool Connor Kite
  2026-07-24  6:06   ` Markus Armbruster
@ 2026-07-24 11:03   ` Akihiko Odaki
  1 sibling, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2026-07-24 11:03 UTC (permalink / raw)
  To: Connor Kite, qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Dmitry Osipenko, qemu-block, virtio-fs,
	Gonglei (Arei), zhenwei pi, Daniel P. Berrangé, Eric Blake,
	Markus Armbruster, Jason Wang, Peter Xu, Eugenio Pérez,
	Alyssa Ross, Demi Marie Obenour

On 2026/07/24 7:30, Connor Kite wrote:
> Add a memory_isolation property to CryptoDevBackendVhostUser and
> add add it as an optional member of CryptodevVhostUserProperties
> in qapi.
> 
> This is needed to be able to specify memory isolation for
> cryptodev-vhost-user objects, and the bool will eventually be
> passed to vhost_user_init() in a future patch.
> 
> Signed-off-by: Connor Kite <connorkite@gmail.com>
> ---
>   backends/cryptodev-vhost-user.c | 22 ++++++++++++++++++++++
>   qapi/qom.json                   |  6 +++++-
>   2 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
> index cc478d9902..e0547c5d40 100644
> --- a/backends/cryptodev-vhost-user.c
> +++ b/backends/cryptodev-vhost-user.c
> @@ -49,6 +49,7 @@ struct CryptoDevBackendVhostUser {
>       CharFrontend chr;
>       char *chr_name;
>       bool opened;
> +    bool memory_isolation;
>       CryptoDevBackendVhost *vhost_crypto[MAX_CRYPTO_QUEUE_NUM];
>   };
>   
> @@ -392,6 +393,23 @@ static void cryptodev_vhost_user_finalize(Object *obj)
>       g_free(s->chr_name);
>   }
>   
> +static void cryptodev_vhost_user_set_mem_isolation(Object *obj, bool value,
> +                                                   Error **errp)
> +{
> +    CryptoDevBackendVhostUser *s =
> +                      CRYPTODEV_BACKEND_VHOST_USER(obj);
> +
> +    s->memory_isolation = value;

This setter should forbid setting once initialization finishes as done 
in cryptodev_vhost_user_set_chardev() since the value is copied into 
VhostUserState during initialization and setting this afterwards is 
ineffective.

Regards,
Akihiko Odaki

> +}
> +
> +static bool cryptodev_vhost_user_get_mem_isolation(Object *obj, Error **errp)
> +{
> +    CryptoDevBackendVhostUser *s =
> +                      CRYPTODEV_BACKEND_VHOST_USER(obj);
> +
> +    return s->memory_isolation;
> +}
> +
>   static void
>   cryptodev_vhost_user_class_init(ObjectClass *oc, const void *data)
>   {
> @@ -407,6 +425,10 @@ cryptodev_vhost_user_class_init(ObjectClass *oc, const void *data)
>                                     cryptodev_vhost_user_get_chardev,
>                                     cryptodev_vhost_user_set_chardev);
>   
> +    object_class_property_add_bool(oc, "memory-isolation",
> +                                   cryptodev_vhost_user_get_mem_isolation,
> +                                   cryptodev_vhost_user_set_mem_isolation);
> +
>   }
>   
>   static const TypeInfo cryptodev_vhost_user_info = {
> diff --git a/qapi/qom.json b/qapi/qom.json
> index c55776af7d..d7ca1b4203 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -350,11 +350,15 @@
>   # @chardev: the name of a Unix domain socket character device that
>   #     connects to the vhost-user server
>   #
> +# @memory-isolation: disables access from cryptodev to guest memory.
> +#     (default: false)
> +#
>   # Since: 2.12
>   ##
>   { 'struct': 'CryptodevVhostUserProperties',
>     'base': 'CryptodevBackendProperties',
> -  'data': { 'chardev': 'str' },
> +  'data': { 'chardev': 'str',
> +            '*memory-isolation': 'bool' },
>     'if': 'CONFIG_VHOST_CRYPTO' }
>   
>   ##
> 


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 05/15] vhost-user: add memory_isolation to VhostUserState
  2026-07-23 22:30 ` [PATCH RFC 05/15] vhost-user: add memory_isolation to VhostUserState Connor Kite
@ 2026-07-24 11:09   ` Akihiko Odaki
  0 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2026-07-24 11:09 UTC (permalink / raw)
  To: Connor Kite, qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Dmitry Osipenko, qemu-block, virtio-fs,
	Gonglei (Arei), zhenwei pi, Daniel P. Berrangé, Eric Blake,
	Markus Armbruster, Jason Wang, Peter Xu, Eugenio Pérez,
	Alyssa Ross, Demi Marie Obenour

On 2026/07/24 7:30, Connor Kite wrote:
> Add a memory_isolation bool to the VhostUserState struct. This
> bool is set within vhost_user_init(), which takes a
> memory_isolation bool as an argument.
> 
> Refactor all call locations of vhost_user_init to include the new
> argument.
> 
> Signed-off-by: Connor Kite <connorkite@gmail.com>
> ---
>   backends/cryptodev-vhost-user.c     |  2 +-
>   backends/vhost-user.c               |  4 ++--
>   hw/block/vhost-user-blk.c           |  3 ++-
>   hw/display/vhost-user-gpu.c         |  3 ++-
>   hw/scsi/vhost-user-scsi.c           |  3 ++-
>   hw/virtio/vhost-stub.c              |  3 ++-
>   hw/virtio/vhost-user-base.c         |  3 ++-
>   hw/virtio/vhost-user-fs.c           |  3 ++-
>   hw/virtio/vhost-user-scmi.c         |  3 ++-
>   hw/virtio/vhost-user-vsock.c        |  3 ++-
>   hw/virtio/vhost-user.c              |  5 ++++-
>   include/hw/virtio/vhost-user.h      |  6 +++++-
>   include/system/vhost-user-backend.h |  3 ++-
>   net/passt.c                         | 13 ++++++++-----
>   net/vhost-user.c                    |  9 +++++----
>   15 files changed, 43 insertions(+), 23 deletions(-)
> 
> diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
> index e0547c5d40..328d7fbdfe 100644
> --- a/backends/cryptodev-vhost-user.c
> +++ b/backends/cryptodev-vhost-user.c
> @@ -214,7 +214,7 @@ static void cryptodev_vhost_user_init(
>           }
>       }
>   
> -    if (!vhost_user_init(&s->vhost_user, &s->chr, errp)) {
> +    if (!vhost_user_init(&s->vhost_user, &s->chr, s->memory_isolation, errp)) {
>           return;
>       }
>   
> diff --git a/backends/vhost-user.c b/backends/vhost-user.c
> index 380d825023..470eba1775 100644
> --- a/backends/vhost-user.c
> +++ b/backends/vhost-user.c
> @@ -22,13 +22,13 @@
>   
>   int
>   vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
> -                            unsigned nvqs, Error **errp)
> +                            unsigned nvqs, bool memory_isolation, Error **errp)
>   {
>       int ret;
>   
>       assert(!b->vdev && vdev);
>   
> -    if (!vhost_user_init(&b->vhost_user, &b->chr, errp)) {
> +    if (!vhost_user_init(&b->vhost_user, &b->chr, memory_isolation, errp)) {
>           return -1;
>       }
>   
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index 9830dc6c35..5c1a19eb50 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -505,7 +505,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    if (!vhost_user_init(&s->vhost_user, &s->chardev, errp)) {
> +    if (!vhost_user_init(&s->vhost_user, &s->chardev,
> +                         s->memory_isolation, errp)) {
>           return;
>       }
>   
> diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
> index 6d0ede672a..b44c989f58 100644
> --- a/hw/display/vhost-user-gpu.c
> +++ b/hw/display/vhost-user-gpu.c
> @@ -625,7 +625,8 @@ vhost_user_gpu_device_realize(DeviceState *qdev, Error **errp)
>       VirtIODevice *vdev = VIRTIO_DEVICE(g);
>   
>       vhost_dev_set_config_notifier(&g->vhost->dev, &config_ops);
> -    if (vhost_user_backend_dev_init(g->vhost, vdev, 2, errp) < 0) {
> +    if (vhost_user_backend_dev_init(g->vhost, vdev, 2, g->memory_isolation,
> +                                    errp) < 0) {
>           return;
>       }
>   
> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> index c1a0393220..5a19182f2b 100644
> --- a/hw/scsi/vhost-user-scsi.c
> +++ b/hw/scsi/vhost-user-scsi.c
> @@ -276,7 +276,8 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev, errp)) {
> +    if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev,
> +                         vs->conf.memory_isolation, errp)) {
>           goto free_virtio;
>       }
>   
> diff --git a/hw/virtio/vhost-stub.c b/hw/virtio/vhost-stub.c
> index 7321dc9210..d1e1075a31 100644
> --- a/hw/virtio/vhost-stub.c
> +++ b/hw/virtio/vhost-stub.c
> @@ -12,7 +12,8 @@ unsigned int vhost_get_free_memslots(void)
>       return UINT_MAX;
>   }
>   
> -bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp)
> +bool vhost_user_init(VhostUserState *user, CharFrontend *chr,
> +                     bool memory_isolation, Error **errp)
>   {
>       return false;
>   }
> diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
> index d2a74a2860..11864a3f08 100644
> --- a/hw/virtio/vhost-user-base.c
> +++ b/hw/virtio/vhost-user-base.c
> @@ -317,7 +317,8 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
>           vub->vhost_user.supports_config = true;
>       }
>   
> -    if (!vhost_user_init(&vub->vhost_user, &vub->chardev, errp)) {
> +    if (!vhost_user_init(&vub->vhost_user, &vub->chardev,
> +                         vub->memory_isolation, errp)) {
>           return;
>       }
>   
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> index 3d980d814b..07ff2a35e0 100644
> --- a/hw/virtio/vhost-user-fs.c
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -238,7 +238,8 @@ static void vuf_device_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev, errp)) {
> +    if (!vhost_user_init(&fs->vhost_user, &fs->conf.chardev,
> +                         fs->conf.memory_isolation, errp)) {
>           return;
>       }
>   
> diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c
> index d514d89392..2c1dbb723e 100644
> --- a/hw/virtio/vhost-user-scmi.c
> +++ b/hw/virtio/vhost-user-scmi.c
> @@ -244,7 +244,8 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
>   
>       vdev->host_features |= (1ULL << VIRTIO_SCMI_F_P2A_CHANNELS);
>   
> -    if (!vhost_user_init(&scmi->vhost_user, &scmi->chardev, errp)) {
> +    if (!vhost_user_init(&scmi->vhost_user, &scmi->chardev,
> +                         scmi->memory_isolation, errp)) {
>           return;
>       }
>   
> diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
> index 89aa789e22..33ab3b69e6 100644
> --- a/hw/virtio/vhost-user-vsock.c
> +++ b/hw/virtio/vhost-user-vsock.c
> @@ -106,7 +106,8 @@ static void vuv_device_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    if (!vhost_user_init(&vsock->vhost_user, &vsock->conf.chardev, errp)) {
> +    if (!vhost_user_init(&vsock->vhost_user, &vsock->conf.chardev,
> +                         vsock->conf.memory_isolation, errp)) {
>           return;
>       }
>   
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 517cc4ca71..f296b63fb9 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -3118,13 +3118,16 @@ static void vhost_user_state_destroy(gpointer data)
>       vhost_user_host_notifier_remove(n, NULL, true);
>   }
>   
> -bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp)
> +bool vhost_user_init(VhostUserState *user, CharFrontend *chr,
> +                     bool memory_isolation,
> +                     Error **errp)
>   {
>       if (user->chr) {
>           error_setg(errp, "Cannot initialize vhost-user state");
>           return false;
>       }
>       user->chr = chr;
> +    user->memory_isolation = memory_isolation;
>       user->memory_slots = 0;
>       user->notifiers = g_ptr_array_new_full(VIRTIO_QUEUE_MAX / 4,
>                                              &vhost_user_state_destroy);
> diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
> index 06c360af18..72b5787efe 100644
> --- a/include/hw/virtio/vhost-user.h
> +++ b/include/hw/virtio/vhost-user.h
> @@ -66,6 +66,7 @@ typedef struct VhostUserHostNotifier {
>    * @chr: the character backend for the socket
>    * @notifiers: GPtrArray of @VhostUserHostnotifier
>    * @memory_slots:
> + * @memory_isolation: determines whether data is shared or copied
>    */
>   typedef struct VhostUserState {
>       CharFrontend *chr;
> @@ -73,12 +74,14 @@ typedef struct VhostUserState {
>       int memory_slots;
>       bool supports_config;
>       bool supports_inflight_migration;
> +    bool memory_isolation;
>   } VhostUserState;
>   
>   /**
>    * vhost_user_init() - initialise shared vhost_user state
>    * @user: allocated area for storing shared state
>    * @chr: the chardev for the vhost socket
> + * @memory_isolation: disables device access to guest memory
>    * @errp: error handle
>    *
>    * User can either directly g_new() space for the state or embed
> @@ -87,7 +90,8 @@ typedef struct VhostUserState {
>    *
>    * Return: true on success, false on error while setting errp.
>    */
> -bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp);
> +bool vhost_user_init(VhostUserState *user, CharFrontend *chr,
> +                     bool memory_isolation, Error **errp);

The signature of the stub for !defined(CONFIG_VHOST_USER) is not 
updated, breaking builds.

Regards,
Akihiko Odaki

>   
>   /**
>    * vhost_user_cleanup() - cleanup state
> diff --git a/include/system/vhost-user-backend.h b/include/system/vhost-user-backend.h
> index 3184c8e799..c23f689182 100644
> --- a/include/system/vhost-user-backend.h
> +++ b/include/system/vhost-user-backend.h
> @@ -41,7 +41,8 @@ struct VhostUserBackend {
>   };
>   
>   int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
> -                                unsigned nvqs, Error **errp);
> +                                unsigned nvqs, bool memory_isolation,
> +                                Error **errp);
>   void vhost_user_backend_start(VhostUserBackend *b);
>   int vhost_user_backend_stop(VhostUserBackend *b);
>   
> diff --git a/net/passt.c b/net/passt.c
> index ce80186883..a3021f37ef 100644
> --- a/net/passt.c
> +++ b/net/passt.c
> @@ -433,7 +433,9 @@ static void passt_vhost_user_event(void *opaque, QEMUChrEvent event)
>       }
>   }
>   
> -static int net_passt_vhost_user_init(NetPasstState *s, Error **errp)
> +static int net_passt_vhost_user_init(NetPasstState *s,
> +                                     bool memory_isolation,
> +                                     Error **errp)
>   {
>       Chardev *chr;
>       int sv[2];
> @@ -457,7 +459,8 @@ static int net_passt_vhost_user_init(NetPasstState *s, Error **errp)
>   
>       s->vhost_user = g_new0(struct VhostUserState, 1);
>       if (!qemu_chr_fe_init(&s->vhost_chr, chr, errp) ||
> -        !vhost_user_init(s->vhost_user, &s->vhost_chr, errp)) {
> +        !vhost_user_init(s->vhost_user, &s->vhost_chr, memory_isolation,
> +                         errp)) {
>           goto err;
>       }
>   
> @@ -735,14 +738,14 @@ int net_init_passt(const Netdev *netdev, const char *name,
>       s->pidfile = pidfile;
>   
>       if (netdev->u.passt.has_vhost_user && netdev->u.passt.vhost_user) {
> -        bool memory_isolation G_GNUC_UNUSED = false;
> +        bool memory_isolation = false;
>   
>           if (netdev->u.passt.has_memory_isolation &&
> -           netdev->u.passt.memory_isolation) {
> +            netdev->u.passt.memory_isolation) {
>               memory_isolation = true;
>           }
>   
> -        if (net_passt_vhost_user_init(s, errp) == -1) {
> +        if (net_passt_vhost_user_init(s, memory_isolation, errp) == -1) {
>               qemu_del_net_client(nc);
>               return -1;
>           }
> diff --git a/net/vhost-user.c b/net/vhost-user.c
> index 8fa303f901..722ab20228 100644
> --- a/net/vhost-user.c
> +++ b/net/vhost-user.c
> @@ -370,7 +370,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event)
>   
>   static int net_vhost_user_init(NetClientState *peer, const char *device,
>                                  const char *name, Chardev *chr,
> -                               int queues)
> +                               int queues, bool memory_isolation)
>   {
>       Error *err = NULL;
>       NetClientState *nc, *nc0 = NULL;
> @@ -390,7 +390,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
>               nc0 = nc;
>               s = DO_UPCAST(NetVhostUserState, nc, nc);
>               if (!qemu_chr_fe_init(&s->chr, chr, &err) ||
> -                !vhost_user_init(user, &s->chr, &err)) {
> +                !vhost_user_init(user, &s->chr, memory_isolation, &err)) {
>                   error_report_err(err);
>                   goto err;
>               }
> @@ -459,7 +459,7 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
>       int queues;
>       const NetdevVhostUserOptions *vhost_user_opts;
>       Chardev *chr;
> -    bool memory_isolation G_GNUC_UNUSED;
> +    bool memory_isolation;
>   
>       assert(netdev->type == NET_CLIENT_DRIVER_VHOST_USER);
>       vhost_user_opts = &netdev->u.vhost_user;
> @@ -480,5 +480,6 @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
>       memory_isolation = vhost_user_opts->has_memory_isolation ?
>                          vhost_user_opts->memory_isolation : false;
>   
> -    return net_vhost_user_init(peer, "vhost_user", name, chr, queues);
> +    return net_vhost_user_init(peer, "vhost_user", name, chr, queues,
> +                               memory_isolation);
>   }
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 07/15] hw/virtio: iova_tree_foreach wrapper
  2026-07-23 22:30 ` [PATCH RFC 07/15] hw/virtio: iova_tree_foreach wrapper Connor Kite
@ 2026-07-24 11:14   ` Akihiko Odaki
  0 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2026-07-24 11:14 UTC (permalink / raw)
  To: Connor Kite, qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Dmitry Osipenko, qemu-block, virtio-fs,
	Gonglei (Arei), zhenwei pi, Daniel P. Berrangé, Eric Blake,
	Markus Armbruster, Jason Wang, Peter Xu, Eugenio Pérez,
	Alyssa Ross, Demi Marie Obenour

On 2026/07/24 7:30, Connor Kite wrote:
> Add a wrapper to vhost-iova-tree that calls iova_tree_foreach on the
> underlying iova_map.  This provides a means to execute some function on
> each node of the tree.
> 
> Signed-off-by: Connor Kite <connorkite@gmail.com>
> ---
>   hw/virtio/vhost-iova-tree.c | 15 +++++++++++++++
>   hw/virtio/vhost-iova-tree.h |  3 +++
>   2 files changed, 18 insertions(+)
> 
> diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c
> index fa4147b773..d8206379bf 100644
> --- a/hw/virtio/vhost-iova-tree.c
> +++ b/hw/virtio/vhost-iova-tree.c
> @@ -189,3 +189,18 @@ void vhost_iova_tree_remove_gpa(VhostIOVATree *iova_tree, DMAMap map)
>       iova_tree_remove(iova_tree->gpa_iova_map, map);
>       iova_tree_remove(iova_tree->iova_map, map);
>   }
> +
> +
> +/**
> + * Traverse through the iova tree in sorted order
> + *
> + * @tree: The VhostIOVATree
> + * @func: Function called at every node.  A false return value ends traversal

GTraverseFunc stops traversal on true, but this says false ends traversal.

> + * @data: An argument passed to func
> + */
> +void vhost_iova_tree_foreach(VhostIOVATree *tree,
> +                             GTraverseFunc func,
> +                             gpointer data)
> +{
> +    iova_tree_foreach(tree->iova_map, func, data);
> +}
> diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h
> index 08f63b61cd..f3b7c48cb9 100644
> --- a/hw/virtio/vhost-iova-tree.h
> +++ b/hw/virtio/vhost-iova-tree.h
> @@ -29,5 +29,8 @@ const DMAMap *vhost_iova_tree_find_gpa(const VhostIOVATree *iova_tree,
>   int vhost_iova_tree_map_alloc_gpa(VhostIOVATree *iova_tree, DMAMap *map,
>                                     hwaddr taddr);
>   void vhost_iova_tree_remove_gpa(VhostIOVATree *iova_tree, DMAMap map);
> +void vhost_iova_tree_foreach(VhostIOVATree *tree, GTraverseFunc func,
> +                               gpointer data);
> +

Here is an extra blank line.

Regards,
Akihiko Odaki

>   
>   #endif
> 


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC 08/15] hw/virtio/vhost-shadow-virtqueue: used handler
  2026-07-23 22:30 ` [PATCH RFC 08/15] hw/virtio/vhost-shadow-virtqueue: used handler Connor Kite
@ 2026-07-24 11:29   ` Akihiko Odaki
  0 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2026-07-24 11:29 UTC (permalink / raw)
  To: Connor Kite, qemu-devel
  Cc: Michael S. Tsirkin, Stefano Garzarella, Alex Bennée,
	Viresh Kumar, Gerd Hoffmann, Mathieu Poirier, Manos Pitsidianakis,
	Haixu Cui, Raphael Norwitz, Kevin Wolf, Hanna Reitz,
	Marc-André Lureau, Paolo Bonzini, Fam Zheng, Stefan Hajnoczi,
	Milan Zamazal, Dmitry Osipenko, qemu-block, virtio-fs,
	Gonglei (Arei), zhenwei pi, Daniel P. Berrangé, Eric Blake,
	Markus Armbruster, Jason Wang, Peter Xu, Eugenio Pérez,
	Alyssa Ross, Demi Marie Obenour

On 2026/07/24 7:30, Connor Kite wrote:
> Adds a handler callback to shadow virtqueues in order to enable
> non-default processing of used vring elements from the device.
> 
> Signed-off-by: Connor Kite <connorkite@gmail.com>
> ---
>   hw/virtio/vhost-shadow-virtqueue.c |  4 ++++
>   hw/virtio/vhost-shadow-virtqueue.h | 14 ++++++++++++++
>   2 files changed, 18 insertions(+)
> 
> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
> index bcb7f2ffc7..eb86c1ee37 100644
> --- a/hw/virtio/vhost-shadow-virtqueue.c
> +++ b/hw/virtio/vhost-shadow-virtqueue.c
> @@ -669,6 +669,10 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
>                   break;
>               }
>   
> +            if (svq->ops && svq->ops->used_handler) {
> +                svq->ops->used_handler(svq, elem, svq->ops_opaque);

The error of the handler that may have left elem stale is ignored here.

Regards,
Akihiko Odaki

> +            }
> +
>               if (unlikely(i >= svq->vring.num)) {
>                   qemu_log_mask(LOG_GUEST_ERROR,
>                            "More than %u used buffers obtained in a %u size SVQ",
> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
> index ec16a1e838..ccfeee36d7 100644
> --- a/hw/virtio/vhost-shadow-virtqueue.h
> +++ b/hw/virtio/vhost-shadow-virtqueue.h
> @@ -56,8 +56,22 @@ typedef int (*VirtQueueAvailCallback)(VhostShadowVirtqueue *svq,
>                                         VirtQueueElement *elem,
>                                         void *vq_callback_opaque);
>   
> +/**
> + * Callback to handle a used buffer
> + *
> + * @svq: Shadow virtqueue
> + * @elem: Element placed in the queue by the device
> + * @vq_callback_opaque: Used to pass arguments to callback
> + *
> + * Returns 0 if the vq is running as expected
> + */
> +typedef int (*VirtQueueUsedCallback)(VhostShadowVirtqueue *svq,
> +                                      VirtQueueElement *elem,
> +                                      void *vq_callback_opaque);
> +
>   typedef struct VhostShadowVirtqueueOps {
>       VirtQueueAvailCallback avail_handler;
> +    VirtQueueUsedCallback used_handler;
>   } VhostShadowVirtqueueOps;
>   
>   /* Shadow virtqueue to relay notifications */
> 


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2026-07-24 11:53 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-23 22:29 [PATCH RFC 00/15] vhost-user: isolated memory ConKite
2026-07-23 22:30 ` [PATCH RFC 01/15] vhost-user: Consolidate chardev property definitions ConKite
2026-07-24  6:09   ` Markus Armbruster
2026-07-23 22:30 ` [PATCH RFC 02/15] vhost-user: Add memory-isolation qdev property to vhost-user devices ConKite
2026-07-24 10:56   ` Akihiko Odaki
2026-07-23 22:30 ` [PATCH RFC 03/15] backends/cryptodev-vhost-user: add memory isolation bool Connor Kite
2026-07-24  6:06   ` Markus Armbruster
2026-07-24 11:03   ` Akihiko Odaki
2026-07-23 22:30 ` [PATCH RFC 04/15] net/vhost-user: add memory isolation Connor Kite
2026-07-23 22:30 ` [PATCH RFC 05/15] vhost-user: add memory_isolation to VhostUserState Connor Kite
2026-07-24 11:09   ` Akihiko Odaki
2026-07-23 22:30 ` [PATCH RFC 06/15] util/iova-tree: g_tree_foreach wrapper Connor Kite
2026-07-23 22:30 ` [PATCH RFC 07/15] hw/virtio: iova_tree_foreach wrapper Connor Kite
2026-07-24 11:14   ` Akihiko Odaki
2026-07-23 22:30 ` [PATCH RFC 08/15] hw/virtio/vhost-shadow-virtqueue: used handler Connor Kite
2026-07-24 11:29   ` Akihiko Odaki
2026-07-23 22:30 ` [PATCH RFC 09/15] hw/virtio/vhost-shadow-virtqueue: specified vring placement Connor Kite
2026-07-23 22:30 ` [PATCH RFC 10/15] hw/virtio/vhost-shadow-virtqueue: range boundary in translation Connor Kite
2026-07-23 22:30 ` [PATCH RFC 11/15] hw/virtio/vhost-user: create isolation region Connor Kite
2026-07-23 22:30 ` [PATCH RFC 12/15] hw/virtio/vhost-user: send isolation regions to device Connor Kite
2026-07-23 22:30 ` [PATCH RFC 13/15] hw/virtio/vhost-user: add shadow virtqueues and eventfd intercepts Connor Kite
2026-07-23 22:30 ` [PATCH RFC 14/15] hw/virtio/vhost-user: handle data movement with shadow vqs Connor Kite
2026-07-23 22:30 ` [PATCH RFC 15/15] hw/virtio/vhost-user: shadow vq cleanup Connor Kite

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.