From nobody Tue Feb 10 23:59:06 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=1770706969; cv=none; d=zohomail.com; s=zohoarc; b=ho5yrFEA9BV/qotGvRlX3eKWvhXWNTl2nIibhzjmLbfXB4YtYUDvU8hmdu3RvzvbUyFfkUYNpHj8amjIX7TxPRAa1kCMQ9+GJquQTjqdyAaHwbjPpps0NYKGJU9LOcE0/wOonCUpz79UeJJflwz+k8jAs+GRyQ2Pc/f1rVHPHpk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770706969; 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=616TtSv/P4MB6kSQgTz7wqW1yzN8ko0967ixdUdDQCM=; b=SDSgr8yr5Q+1RSfMk4MDRKvMgZw9ZJc4hfqtmv2tMp4Dlak5EBW4UK7epu0fFxhzkpkoHr0ray66ShiRG+TtCEAY8lWNXo6HbjsbUeNGjmjN240MV/i7F4Pz6khg/1yqeTOG2CjHMbr1+eUz4wJaDfEYumXxmdJHv7798PiM8/k= 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 1770706969712824.5830890685538; Mon, 9 Feb 2026 23:02:49 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vphlW-00053I-SQ; Tue, 10 Feb 2026 02:02:30 -0500 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 1vphlT-0004zy-UO for qemu-devel@nongnu.org; Tue, 10 Feb 2026 02:02:27 -0500 Received: from mgamail.intel.com ([198.175.65.16]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vphlS-0004oY-6m for qemu-devel@nongnu.org; Tue, 10 Feb 2026 02:02:27 -0500 Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa108.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Feb 2026 23:02:14 -0800 Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by orviesa006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Feb 2026 23:02:14 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1770706946; x=1802242946; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=V4N+nlGdAKKVvTdy20qKXzkyk59AwwC7IM9qRYhfmGE=; b=UZ+Q1Nt0J8WPk0f0RXzoxg+Eo8VR4lmmv/S1pXkfGGw+3ilVCm4SELoi VjU8jkxl5yZC+eSawgSU/rgtBe6JL9A/kHSzmdf1c8XF4zrnKJRdSu1Fe 34e0DZ8DOwSjZX9rq+kW0XHFtKZdxueug0ge10pPPT2LzhWcKMstE6KvH 5Q7o7ymISK+vI1b7PJfPqibMar3Fx0ZQUYbHAjig/P+OZsNYWsQLQWpkp bSYsxy33z1aftpy1dMPAX0Kw33ioubPCkjt2AIDnvU4gFQCRAdvm/cmqN gHBk29alwzpGseLcz5XBAlyuH8Yzg+W6UQMtFXci8Fki8fkZd3uCRk58f g==; X-CSE-ConnectionGUID: q7YniHrkT/KRsEq4pj45ag== X-CSE-MsgGUID: K8+1jhLiSe+eilwBzDs6GQ== X-IronPort-AV: E=McAfee;i="6800,10657,11696"; a="72012182" X-IronPort-AV: E=Sophos;i="6.21,283,1763452800"; d="scan'208";a="72012182" X-CSE-ConnectionGUID: 8RiwMPZKRdSghMwASjEjQQ== X-CSE-MsgGUID: wAkmRUkJQkqpreTP+rpNuw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,283,1763452800"; d="scan'208";a="210920556" From: Vivek Kasireddy To: qemu-devel@nongnu.org Cc: Vivek Kasireddy , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Subject: [PATCH v6 09/11] vfio/device: Add support for creating dmabuf from multiple ranges Date: Mon, 9 Feb 2026 22:59:49 -0800 Message-ID: <20260210070155.1176081-10-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260210070155.1176081-1-vivek.kasireddy@intel.com> References: <20260210070155.1176081-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=198.175.65.16; envelope-from=vivek.kasireddy@intel.com; helo=mgamail.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 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.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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: 1770706972136158500 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. Cc: Alex Williamson Cc: C=C3=A9dric Le Goater Signed-off-by: Vivek Kasireddy --- hw/vfio/device.c | 81 +++++++++++++++++++++++++++++++++++ include/hw/vfio/vfio-device.h | 14 ++++++ 2 files changed, 95 insertions(+) diff --git a/hw/vfio/device.c b/hw/vfio/device.c index 973fc35b59..a7603600f3 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; +} + +bool vfio_device_create_dmabuf(struct iovec *iov, unsigned int iov_cnt, + int *fd, 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; + 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 false; + } + + 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 false; + } + + 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 false; + } + + 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; + + *fd =3D vfio_device_get_feature(vbasedev, feature); + if (*fd < 0) { + error_setg_errno(errp, -(*fd), + "Could not create dmabuf fd via VFIO device"); + return false; + } + return true; +} diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h index 596c7f5a10..003bac10b5 100644 --- a/include/hw/vfio/vfio-device.h +++ b/include/hw/vfio/vfio-device.h @@ -318,6 +318,20 @@ 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 + * @fd: pointer to store the resulting dmabuf fd + * + * Returns true on success and false in case of an error. + */ +bool vfio_device_create_dmabuf(struct iovec *iov, unsigned int iov_cnt, + int *fd, Error **errp); #endif =20 /* Returns 0 on success, or a negative errno. */ --=20 2.50.1