All of lore.kernel.org
 help / color / mirror / Atom feed
From: Naman Gulati <namangulati@google.com>
To: qemu-devel@nongnu.org
Cc: "John Levon" <john.levon@nutanix.com>,
	"Thanos Makatos" <thanos.makatos@nutanix.com>,
	"Cédric Le Goater" <clg@redhat.com>,
	"Alex Williamson" <alex@shazbot.org>,
	"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
	"Matt Evans" <matt@ozlabs.org>,
	"Naman Gulati" <namangulati@google.com>
Subject: [RFC PATCH 3/3] vfio-user: implement client support for multi-fd region mmap
Date: Tue, 11 Aug 2026 23:39:30 +0000	[thread overview]
Message-ID: <20260811233930.401797-4-namangulati@google.com> (raw)
In-Reply-To: <20260811233930.401797-1-namangulati@google.com>

Add client support for capability VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS
(capability ID 16) in vfio-user.

Update vfio_user_device_io_get_region_info() to receive multiple file
descriptors passed in SCM_RIGHTS ancillary data for a region, and
implement setup_sparse_mmaps in vfio_user_device_io_ops_sock to parse
per-area file descriptor indices and fd_offset values.

Signed-off-by: Naman Gulati <namangulati@google.com>
---
 hw/vfio-user/device.c   | 63 ++++++++++++++++++++++++++++++++++++-----
 hw/vfio-user/protocol.h | 20 +++++++++++++
 2 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c
index 9c4e10c1fd..48b1cd8f1e 100644
--- a/hw/vfio-user/device.c
+++ b/hw/vfio-user/device.c
@@ -14,6 +14,9 @@
 
 #include "hw/vfio-user/device.h"
 #include "hw/vfio-user/trace.h"
+#include "hw/vfio/vfio-region.h"
+#include "hw/vfio/vfio-helpers.h"
+#include "hw/vfio/trace.h"
 
 /*
  * These are to defend against a malign server trying
@@ -171,23 +174,26 @@ static int vfio_user_get_region_info(VFIOUserProxy *proxy,
 static int vfio_user_device_io_get_region_info(VFIODevice *vbasedev,
                                                struct vfio_region_info *info)
 {
-    int fd = -1;
-    VFIOUserFDs fds = { 0, 1, &fd };
+    int fds[VFIO_USER_MAX_MAX_FDS];
+    int num_fds = VFIO_USER_MAX_MAX_FDS;
+    VFIOUserFDs user_fds = { 0, num_fds, fds };
     int ret;
 
     if (info->index > vbasedev->num_initial_regions) {
         return -EINVAL;
     }
 
-    ret = vfio_user_get_region_info(vbasedev->proxy, info, &fds);
+    ret = vfio_user_get_region_info(vbasedev->proxy, info, &user_fds);
     if (ret) {
         return ret;
     }
 
-    if (fds.recv_fds > 0 && info->index < vbasedev->num_initial_regions) {
-        vbasedev->region_fds[info->index].fds = g_new0(int, 1);
-        vbasedev->region_fds[info->index].nr_fds = 1;
-        vbasedev->region_fds[info->index].fds[0] = fd;
+    if (user_fds.recv_fds > 0 && info->index < vbasedev->num_initial_regions) {
+        vbasedev->region_fds[info->index].fds = g_new0(int, user_fds.recv_fds);
+        vbasedev->region_fds[info->index].nr_fds = user_fds.recv_fds;
+        for (int i = 0; i < user_fds.recv_fds; i++) {
+            vbasedev->region_fds[info->index].fds[i] = fds[i];
+        }
     }
 
     /* cap_offset in valid area */
@@ -478,9 +484,52 @@ static int vfio_user_device_io_region_write(VFIODevice *vbasedev, uint8_t index,
 /*
  * Socket-based io_ops
  */
+static int vfio_user_device_io_setup_sparse_mmaps(VFIORegion *region,
+                                                  struct vfio_region_info *info,
+                                                  Error **errp)
+{
+    struct vfio_info_cap_header *hdr;
+    int i, j = 0;
+
+    hdr = vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS);
+    if (hdr) {
+        struct vfio_region_info_cap_sparse_mmap_fds *sparse_fds =
+            container_of(hdr, struct vfio_region_info_cap_sparse_mmap_fds,
+                         header);
+
+        trace_vfio_region_sparse_mmap_header(region->vbasedev->name,
+                                             region->nr, sparse_fds->nr_areas);
+
+        region->mmaps = g_new0(VFIOMmap, sparse_fds->nr_areas);
+
+        for (i = 0; i < sparse_fds->nr_areas; i++) {
+            if (sparse_fds->areas[i].size) {
+                uint64_t end = sparse_fds->areas[i].offset +
+                               sparse_fds->areas[i].size - 1;
+
+                trace_vfio_region_sparse_mmap_entry(i,
+                                                    sparse_fds->areas[i].offset,
+                                                    end);
+                region->mmaps[j].offset = sparse_fds->areas[i].offset;
+                region->mmaps[j].fd_offset = sparse_fds->areas[i].fd_offset;
+                region->mmaps[j].size = sparse_fds->areas[i].size;
+                region->mmaps[j].fd_index = sparse_fds->areas[i].fd_index;
+                j++;
+            }
+        }
+
+        region->nr_mmaps = j;
+        region->mmaps = g_realloc(region->mmaps, j * sizeof(VFIOMmap));
+        return 0;
+    }
+
+    return vfio_default_setup_sparse_mmaps(region, info, errp);
+}
+
 VFIODeviceIOOps vfio_user_device_io_ops_sock = {
     .device_feature = vfio_user_device_io_device_feature,
     .get_region_info = vfio_user_device_io_get_region_info,
+    .setup_sparse_mmaps = vfio_user_device_io_setup_sparse_mmaps,
     .get_irq_info = vfio_user_device_io_get_irq_info,
     .set_irqs = vfio_user_device_io_set_irqs,
     .region_read = vfio_user_device_io_region_read,
diff --git a/hw/vfio-user/protocol.h b/hw/vfio-user/protocol.h
index c478d1353f..135b965d99 100644
--- a/hw/vfio-user/protocol.h
+++ b/hw/vfio-user/protocol.h
@@ -166,6 +166,26 @@ typedef struct {
     uint64_t offset;
 } VFIOUserRegionInfo;
 
+/*
+ * VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS
+ */
+#define VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS 16
+
+struct vfio_region_sparse_mmap_fd_area {
+    uint64_t offset;
+    uint64_t fd_offset;
+    uint64_t size;
+    uint32_t fd_index;
+    uint32_t pad;
+};
+
+struct vfio_region_info_cap_sparse_mmap_fds {
+    struct vfio_info_cap_header header;
+    uint32_t nr_areas;
+    uint32_t reserved;
+    struct vfio_region_sparse_mmap_fd_area areas[];
+};
+
 /*
  * VFIO_USER_DEVICE_GET_IRQ_INFO
  * imported from struct vfio_irq_info
-- 
2.55.0.679.g6767b8d81c-goog



      parent reply	other threads:[~2026-08-11 23:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-11 23:39 [RFC PATCH 0/3] vfio-user: support multiple FDs backing region mmaps Naman Gulati
2026-08-11 23:39 ` [RFC PATCH 1/3] vfio-user: add multi-fd region mmap capability Naman Gulati
2026-08-11 23:39 ` [RFC PATCH 2/3] vfio: mmap sparse regions backed by multiple FDs Naman Gulati
2026-08-14  8:52   ` John Levon
2026-08-14 19:48     ` Naman Gulati
2026-08-14 19:53       ` John Levon
2026-08-11 23:39 ` Naman Gulati [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260811233930.401797-4-namangulati@google.com \
    --to=namangulati@google.com \
    --cc=alex@shazbot.org \
    --cc=clg@redhat.com \
    --cc=john.levon@nutanix.com \
    --cc=matt@ozlabs.org \
    --cc=pierrick.bouvier@oss.qualcomm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thanos.makatos@nutanix.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.