All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akihiko Odaki <akihiko.odaki@gmail.com>
To: Vivek Kasireddy <vivek.kasireddy@intel.com>, qemu-devel@nongnu.org
Cc: "Alex Williamson" <alex@shazbot.org>,
	"Cédric Le Goater" <clg@redhat.com>
Subject: Re: [PATCH v13 6/9] vfio/device: Add support for creating dmabuf from multiple ranges
Date: Thu, 8 Oct 2026 18:08:39 +0900	[thread overview]
Message-ID: <f8c86fc0-9c29-4fd5-a7af-e20289da9f4b@gmail.com> (raw)
In-Reply-To: <20261007201222.648687-7-vivek.kasireddy@intel.com>

On 2026/10/08 5:09, Vivek Kasireddy wrote:
> In order to create a dmabuf associated with a buffer that spans
> multiple ranges, we first need to identify the VFIO region and
> index the buffer (represented by iovec) belongs to and then
> translate its addresses to offsets within that region.
> 
> The qemu_ram_block_from_host() API gives us both the region and
> the offset info we need to populate the dma ranges so that we can
> invoke the VFIO_DEVICE_FEATURE_DMA_BUF feature to create the dmabuf.
> 
> Also, instead of iterating over all QOM devices to find the
> VFIODevice associated with a memory region, introduce a helper
> to just use the vfio_device_list to lookup the VFIODevice.
> And, introduce another helper to lookup the VFIO region given an
> address.
> 
> Lastly, introduce an enum to return the type of error encountered
> while creating the dmabuf fd.
> 
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> ---
>   include/hw/vfio/vfio-device.h |  22 +++++++
>   hw/vfio/device.c              | 109 ++++++++++++++++++++++++++++++++++
>   hw/vfio/dmabuf-stubs.c        |  17 ++++++
>   hw/vfio/meson.build           |   1 +
>   4 files changed, 149 insertions(+)
>   create mode 100644 hw/vfio/dmabuf-stubs.c
> 
> diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
> index 8472420d3f..c05430be8a 100644
> --- a/include/hw/vfio/vfio-device.h
> +++ b/include/hw/vfio/vfio-device.h
> @@ -41,6 +41,13 @@ enum {
>       VFIO_DEVICE_TYPE_AP = 3,
>   };
>   
> +enum {
> +    /* The Guest passed addresses stored in IOV are invalid */
> +    VFIO_DMABUF_CREATE_ERR_INVALID_IOV = -1,
> +    /* Guest or Host may be at fault for this type of error */
> +    VFIO_DMABUF_CREATE_ERR_UNSPEC = -2,
> +};
> +
>   typedef struct VFIODeviceOps VFIODeviceOps;
>   typedef struct VFIODeviceIOOps VFIODeviceIOOps;
>   typedef struct VFIOMigration VFIOMigration;
> @@ -323,6 +330,21 @@ bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_t
>   
>   int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
>                                   struct vfio_irq_info *info);
> +
> +/**
> + * Create a dmabuf fd by first translating the addresses in the
> + * iovec array into VFIO region offsets and then invoking the
> + * VFIO_DEVICE_FEATURE_DMA_BUF feature.
> + *
> + * @iov: array of iovec entries associated with a buffer
> + * @iov_cnt: number of entries in the iovec array
> + * @errp: pointer to Error*, to store an error if it happens.
> + *
> + * Returns the created dmabuf fd or either VFIO_DMABUF_CREATE_ERR_UNSPEC
> + * or VFIO_DMABUF_CREATE_ERR_INVALID_IOV on error.
> + */
> +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
> +                                 Error **errp);
>   #endif
>   
>   /* Returns 0 on success, or a negative errno. */
> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> index 4f11959633..d95503a5f1 100644
> --- a/hw/vfio/device.c
> +++ b/hw/vfio/device.c
> @@ -21,7 +21,9 @@
>   #include "qemu/osdep.h"
>   #include <sys/ioctl.h>
>   
> +#include "system/ramblock.h"
>   #include "hw/vfio/vfio-device.h"
> +#include "hw/vfio/vfio-region.h"
>   #include "hw/vfio/pci.h"
>   #include "hw/core/iommu.h"
>   #include "trace.h"
> @@ -667,3 +669,110 @@ static VFIODeviceIOOps vfio_device_io_ops_ioctl = {
>       .region_read = vfio_device_io_region_read,
>       .region_write = vfio_device_io_region_write,
>   };
> +
> +/*
> + * This helper looks up the VFIODevice corresponding to the given iov. It
> + * can be useful to determinine if a buffer (represented by the iov) belongs
> + * to a VFIO device or not. This is mainly invoked when external components
> + * such as virtio-gpu request creation of dmabuf fds for buffers that may
> + * belong to a VFIO device.
> + */
> +static bool vfio_device_lookup(struct iovec *iov, VFIODevice **vbasedevp,
> +                               RAMBlock **first_rbp, Error **errp)
> +{
> +    VFIODevice *vbasedev;
> +    RAMBlock *first_rb;
> +    ram_addr_t offset;
> +
> +    first_rb = qemu_ram_block_from_host(iov[0].iov_base, false, &offset);
> +    if (!first_rb) {
> +        error_setg(errp, "Could not find first ramblock\n");
> +        return false;
> +    }
> +
> +    *first_rbp = first_rb;
> +    QLIST_FOREACH(vbasedev, &vfio_device_list, next) {

This traverses vfio_device_list using next. next belongs to the legacy 
IOMMU-group list. With devices in separate groups, or multiple devices 
using iommufd, buffers belonging to devices beyond the global head are 
missed and DMA-BUF creation fails. Please use global_next.

> +        if (vbasedev->dev == first_rb->mr->dev) {
> +            *vbasedevp = vbasedev;
> +            return true;
> +        }
> +    }
> +    error_setg(errp, "No VFIO device found to create dmabuf from\n");
> +    return false;
> +}
> +
> +/*
> + * This helper looks up the VFIORegion corresponding to the given address.
> + * It also verifies that the RAMBlock associated with the address is the
> + * same as the first_rb passed in. This is to ensure that all addresses
> + * in the iov belong to the same region.
> + */
> +static bool vfio_region_lookup(void *addr, VFIORegion **regionp,
> +                               RAMBlock *first_rb, ram_addr_t *offsetp,
> +                               Error **errp)
> +{
> +    VFIORegion *region;
> +    RAMBlock *rb;
> +
> +    rb = qemu_ram_block_from_host(addr, false, offsetp);
> +    if (!rb || rb != first_rb) {
> +        error_setg(errp, "Dmabuf segments must belong to the same region\n");
> +        return false;
> +    }
> +
> +    region = vfio_get_region_from_mr(rb->mr);
> +    if (region) {
> +        *regionp = region;
> +        return true;
> +    }
> +    error_setg(errp, "Could not find valid region for dmabuf segment\n");
> +    return false;
> +}
> +
> +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
> +                                 Error **errp)
> +{
> +    g_autofree struct vfio_device_feature *feature = NULL;
> +    struct vfio_device_feature_dma_buf *dma_buf;
> +    RAMBlock *first_rb = NULL;
> +    VFIODevice *vbasedev;
> +    VFIORegion *region;
> +    ram_addr_t offset;
> +    size_t argsz;
> +    int i, ret;
> +
> +    if (!vfio_device_lookup(iov, &vbasedev, &first_rb, errp)) {
> +        return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> +    }
> +
> +    argsz = sizeof(*feature) + sizeof (*dma_buf) +
> +            sizeof(struct vfio_region_dma_range) * iov_cnt;
> +    feature = g_malloc0(argsz);
> +    *feature = (struct vfio_device_feature) {
> +        .argsz = argsz,
> +        .flags = VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_DMA_BUF,
> +    };
> +    dma_buf = (struct vfio_device_feature_dma_buf *)feature->data;
> +
> +    for (i = 0; i < iov_cnt; i++) {
> +        if (!vfio_region_lookup(iov[i].iov_base, &region,
> +                                first_rb, &offset, errp)) {
> +            return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> +        }
> +
> +        dma_buf->region_index = region->nr;
> +        dma_buf->dma_ranges[i].offset = offset;
> +        dma_buf->dma_ranges[i].length = iov[i].iov_len;
> +    }
> +
> +    dma_buf->nr_ranges = iov_cnt;
> +    dma_buf->open_flags = O_RDONLY | O_CLOEXEC;
> +
> +    ret = vfio_device_get_feature(vbasedev, feature);
> +    if (ret < 0) {
> +        error_setg_errno(errp, -ret,
> +                         "Could not create dmabuf fd via VFIO device");
> +        return VFIO_DMABUF_CREATE_ERR_UNSPEC;
> +    }
> +    return ret;
> +}
> diff --git a/hw/vfio/dmabuf-stubs.c b/hw/vfio/dmabuf-stubs.c
> new file mode 100644
> index 0000000000..fb5318e929
> --- /dev/null
> +++ b/hw/vfio/dmabuf-stubs.c
> @@ -0,0 +1,17 @@
> +/*
> + * Copyright (c) 2026 Intel and/or its affiliates.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/iov.h"
> +#include "hw/vfio/vfio-device.h"
> +
> +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
> +                                 Error **errp)
> +{
> +    error_setg(errp, "VFIO dmabuf support is not enabled");
> +    return VFIO_DMABUF_CREATE_ERR_UNSPEC;
> +}

The new stub builds when VFIO is disabled, but its declaration is inside 
#ifdef CONFIG_LINUX. Consequently, -Wmissing-prototypes fails builds 
such as macOS CI.

Regards,
Akihiko Odaki

> diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
> index c7c31b78f6..aa6f4bc1b4 100644
> --- a/hw/vfio/meson.build
> +++ b/hw/vfio/meson.build
> @@ -38,3 +38,4 @@ stub_ss.add(files('iommufd-stubs.c'))
>   system_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
>     'display.c',
>   ))
> +system_ss.add(when: 'CONFIG_VFIO', if_false: files('dmabuf-stubs.c'))



  reply	other threads:[~2026-10-08  9:09 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-07 20:09 [PATCH v13 0/9] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 1/9] virtio-gpu: Find hva for Guest's DMA addr associated with a ram device Vivek Kasireddy
2026-10-08  9:02   ` Akihiko Odaki
2026-10-09  4:32     ` Kasireddy, Vivek
2026-10-09  9:26       ` Akihiko Odaki
2026-10-12  6:10         ` Kasireddy, Vivek
2026-10-07 20:09 ` [PATCH v13 2/9] virtio-gpu: Rename udmabuf files and helpers to dmabuf Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 3/9] virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from virtio_gpu_create_udmabuf() Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 4/9] virtio-gpu-dmabuf: Use g_autofree for the list pointer Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 5/9] vfio/region: Add a helper to get VFIO region from memory region Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 6/9] vfio/device: Add support for creating dmabuf from multiple ranges Vivek Kasireddy
2026-10-08  9:08   ` Akihiko Odaki [this message]
2026-10-09  4:24     ` Kasireddy, Vivek
2026-10-09  8:13   ` Cédric Le Goater
2026-10-12  6:27     ` Kasireddy, Vivek
2026-10-12 14:01       ` Akihiko Odaki
2026-10-13  4:06         ` Kasireddy, Vivek
2026-10-13 16:20           ` Cédric Le Goater
2026-10-14  2:17             ` Akihiko Odaki
2026-10-14  7:41               ` Cédric Le Goater
2026-10-14 16:40                 ` Cédric Le Goater
2026-10-14  7:03             ` Markus Armbruster
2026-10-14 13:07               ` Akihiko Odaki
2026-10-14 16:29                 ` Cédric Le Goater
2026-10-13 16:40       ` Cédric Le Goater
2026-10-07 20:09 ` [PATCH v13 7/9] vfio/device: Add a helper to mmap a dmabuf Vivek Kasireddy
2026-10-09  8:13   ` Cédric Le Goater
2026-10-07 20:09 ` [PATCH v13 8/9] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum Vivek Kasireddy
2026-10-09  8:17   ` Cédric Le Goater
2026-10-07 20:09 ` [PATCH v13 9/9] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Vivek Kasireddy
2026-10-08  9:11   ` Akihiko Odaki
2026-10-09  4:26     ` Kasireddy, Vivek
2026-10-09  9:51       ` Akihiko Odaki
2026-10-12  6:14         ` Kasireddy, Vivek
2026-10-12 14:00           ` Akihiko Odaki
2026-10-13  3:57             ` Kasireddy, Vivek

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=f8c86fc0-9c29-4fd5-a7af-e20289da9f4b@gmail.com \
    --to=akihiko.odaki@gmail.com \
    --cc=alex@shazbot.org \
    --cc=clg@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=vivek.kasireddy@intel.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.