From nobody Wed Apr 8 02:51:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1773197900; cv=none; d=zohomail.com; s=zohoarc; b=OiVR+C2lDt1t0S7Etru59+rjiVMUWG0DSGQvAOqg34Q49A6AmJ4Vdn90qiNijdr3lmcUrsKBmgcgLf9bQbUwvE11hW6lpSJRLr8WjqRbxQ85k/sh0teW33OMtm08paDb95heLMKBVINQ6J7rNX4zg221b+ohPQl0IKaOrk+RXCM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773197900; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VOnbMoLWDMvkA0U8mrp+cB/Yeuu0x8irWI5zenbfzWA=; b=EGCirUmZW1+CD3cE0xWGrxnm1YnF/2EdzhSKyvZcG8j5FCDUA5GcVLG2KbKUVY2kQbaGXWrn/pBfrZdWpV/omopgzZpP4HW53NWJslavlzBMVk/Uin9vik9BdWUAvL0No8vtyzqhbkYbIDVu4/rwGOTbm8ZD7030r9ns8ufXlR4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1773197900405564.0167919738883; Tue, 10 Mar 2026 19:58:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w09kg-0000Uu-Lt; Tue, 10 Mar 2026 22:56:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w09ke-0000UF-T9 for qemu-devel@nongnu.org; Tue, 10 Mar 2026 22:56:48 -0400 Received: from mgamail.intel.com ([192.198.163.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w09kc-000630-WE for qemu-devel@nongnu.org; Tue, 10 Mar 2026 22:56:48 -0400 Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2026 19:56:29 -0700 Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by fmviesa009-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2026 19:56:29 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1773197807; x=1804733807; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UItcbupB/uwZcfp4UNEcPNYUFQcpUcNo+S9Ep6gGUiM=; b=b9nH2EASCTauIu9aB3l0txPFf7gYWZ6pko+f7wj0VM2C//b2S16dfxB6 Gviclf6UFPhXXm5CNdIlL2kSnWkHojH1/zagI0jn3eS1gwlpcZ0SYXcDz tcBx0Rj4i3lmWD4erc8ObK1A74YqCUXI6X3BMGsHL4yzpgF+dBJCvofjX /AVfULi1bt1bh/oy5x+ZbM0CQR/KOhnHqTN13W1/Zl8u7yB2inhQC8jG8 eN7y4ACha/tcJpF6FBa46NO+XvC4dXRar3ecitgUnkqfQeV9glws7V2pY wLfv5y1ldlBzUcUvhZr5ELNfOlEF4Ep/3NnMfK0LiAu6hVb7x4CcivLR8 w==; X-CSE-ConnectionGUID: YL7mBS1XSp694DyWVnLvdQ== X-CSE-MsgGUID: 48vJdS23ROy6Kv5hgl0Rtg== X-IronPort-AV: E=McAfee;i="6800,10657,11725"; a="76867923" X-IronPort-AV: E=Sophos;i="6.23,113,1770624000"; d="scan'208";a="76867923" X-CSE-ConnectionGUID: KlrCb56WR8G3spQ/ZhR10A== X-CSE-MsgGUID: HP/6y4EbRky2XmyHgvQu4g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,113,1770624000"; d="scan'208";a="215611450" From: Vivek Kasireddy To: qemu-devel@nongnu.org Cc: Vivek Kasireddy , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Subject: [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges Date: Tue, 10 Mar 2026 19:50:49 -0700 Message-ID: <20260311025340.1335673-8-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260311025340.1335673-1-vivek.kasireddy@intel.com> References: <20260311025340.1335673-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.198.163.13; envelope-from=vivek.kasireddy@intel.com; helo=mgamail.intel.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1773197900697158500 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. Lastly, introduce an enum to return the type of error encountered while creating the dmabuf fd. Cc: Alex Williamson Cc: C=C3=A9dric Le Goater Signed-off-by: Vivek Kasireddy --- hw/vfio/device.c | 81 +++++++++++++++++++++++++++++++++++ hw/vfio/dmabuf-stubs.c | 17 ++++++++ hw/vfio/meson.build | 1 + include/hw/vfio/vfio-device.h | 22 ++++++++++ 4 files changed, 121 insertions(+) create mode 100644 hw/vfio/dmabuf-stubs.c diff --git a/hw/vfio/device.c b/hw/vfio/device.c index 973fc35b59..2d01059be0 100644 --- a/hw/vfio/device.c +++ b/hw/vfio/device.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include =20 +#include "system/ramblock.h" #include "hw/vfio/vfio-device.h" #include "hw/vfio/pci.h" #include "hw/core/iommu.h" @@ -644,3 +645,83 @@ static VFIODeviceIOOps vfio_device_io_ops_ioctl =3D { .region_read =3D vfio_device_io_region_read, .region_write =3D vfio_device_io_region_write, }; + +static bool vfio_device_lookup(struct iovec *iov, VFIODevice **vbasedevp, + Error **errp) +{ + VFIODevice *vbasedev; + RAMBlock *first_rb; + ram_addr_t offset; + + first_rb =3D 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; + } + + QLIST_FOREACH(vbasedev, &vfio_device_list, next) { + if (vbasedev->dev =3D=3D first_rb->mr->dev) { + *vbasedevp =3D vbasedev; + return true; + } + } + error_setg(errp, "No VFIO device found to create dmabuf from\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 =3D NULL; + struct vfio_device_feature_dma_buf *dma_buf; + RAMBlock *rb, *first_rb; + VFIODevice *vbasedev; + ram_addr_t offset; + int i, index, ret; + size_t argsz; + + argsz =3D sizeof(*feature) + sizeof (*dma_buf) + + sizeof(struct vfio_region_dma_range) * iov_cnt; + feature =3D g_malloc0(argsz); + *feature =3D (struct vfio_device_feature) { + .argsz =3D argsz, + .flags =3D VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_DMA_BUF, + }; + dma_buf =3D (struct vfio_device_feature_dma_buf *)feature->data; + + if (!vfio_device_lookup(iov, &vbasedev, errp)) { + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV; + } + + for (i =3D 0; i < iov_cnt; i++) { + rb =3D qemu_ram_block_from_host(iov[i].iov_base, false, &offset); + if (i =3D=3D 0) { + first_rb =3D rb; + } + if (!rb || rb !=3D first_rb) { + error_setg(errp, "Cannot create dmabuf with different regions\= n"); + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV; + } + + index =3D vfio_get_region_index_from_mr(rb->mr); + if (index < 0) { + error_setg(errp, "Cannot find region index for dmabuf segment\= n"); + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV; + } + + dma_buf->region_index =3D index; + dma_buf->dma_ranges[i].offset =3D offset; + dma_buf->dma_ranges[i].length =3D iov[i].iov_len; + } + + dma_buf->nr_ranges =3D iov_cnt; + dma_buf->open_flags =3D O_RDONLY | O_CLOEXEC; + + ret =3D 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..e71e2b68dd --- /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_HOST_ERROR; +} diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build index 82f68698fb..ac899d30a8 100644 --- a/hw/vfio/meson.build +++ b/hw/vfio/meson.build @@ -34,3 +34,4 @@ system_ss.add(when: 'CONFIG_IOMMUFD', if_false: files('io= mmufd-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')) diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h index 596c7f5a10..566e5d8bc0 100644 --- a/include/hw/vfio/vfio-device.h +++ b/include/hw/vfio/vfio-device.h @@ -41,6 +41,13 @@ enum { VFIO_DEVICE_TYPE_AP =3D 3, }; =20 +enum { + /* The Guest passed addresses stored in IOV are invalid */ + VFIO_DMABUF_CREATE_ERR_INVALID_IOV =3D -1, + /* Guest or Host may be at fault for this type of error */ + VFIO_DMABUF_CREATE_ERR_UNSPEC =3D -2, +}; + typedef struct VFIODeviceOps VFIODeviceOps; typedef struct VFIODeviceIOOps VFIODeviceIOOps; typedef struct VFIOMigration VFIOMigration; @@ -318,6 +325,21 @@ int vfio_device_get_irq_info(VFIODevice *vbasedev, int= index, * Returns the region index or -1 on error. */ int vfio_get_region_index_from_mr(MemoryRegion *mr); + +/** + * 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 =20 /* Returns 0 on success, or a negative errno. */ --=20 2.53.0