From nobody Fri Nov 14 23:29:44 2025 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=1762666835; cv=none; d=zohomail.com; s=zohoarc; b=hottz18/L1rXTbY0rEpJWgtjXLQZ8ZU80Z3bEPTrQKLy6hwellHjaPxGy/2mkIakDPJUIVd222uNsmhjU0A/LE9nqrgfj7eX2A4+y8Pw6MsoE+JcfNY/2xCChK8soUmA5Fvg7FzI8GtUND8fZ/sFiH1P3zbnllhRlLcHeFkRTyA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1762666835; 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=5i+TG5RLMQCRoo9p4clchc+pLXvltGHAqRWyBaAJKEE=; b=KJJcqCIRK/Yad4wSzIO/xu81l2oF3s3XyK24mirUsYviPBkJw24ucTZTmsRR0ul1oALngroqP/IF0iiQgxEEDvTbWJ1h4/79KoK5UZgjwKgPbgqfKXzf/pm1UTmWGxkttlo45lvrQb4ZHbm51RIjCNwLn6XqCoFC8/AWUaSGlg8= 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 1762666835398729.9430968090052; Sat, 8 Nov 2025 21:40:35 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vHy8l-0005ZM-L0; Sun, 09 Nov 2025 00:39:03 -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 1vHy8W-0005VB-Pt for qemu-devel@nongnu.org; Sun, 09 Nov 2025 00:38:48 -0500 Received: from mgamail.intel.com ([198.175.65.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vHy8T-0007ZY-Bk for qemu-devel@nongnu.org; Sun, 09 Nov 2025 00:38:47 -0500 Received: from orviesa009.jf.intel.com ([10.64.159.149]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Nov 2025 21:38:42 -0800 Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by orviesa009-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Nov 2025 21:38:41 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1762666726; x=1794202726; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mqTCB0KZ3ENIGuzfE9e3tp7irG2sX0EMI9SKzQd7QWY=; b=Vp04mzjnyXnvX8EuqRMOKN+3j0s54SYqdqdLk1Wn8E0VP8+fxDoJbmSE QLDkA/VAz3aeQCXLMwbMzTzYUIsqd4aHxCWHufa0/ibGl+dkQSf4KpNv0 KfyRAsioj1FU2HprGgax3pYeDXJFxWamImbxfZ9IVQ3jE42/dh8tiPz8F VdmNF43/J6nLxIn7Ey50fwShVCA4kClWtndS9krZrVIQbhlu75bWgu2OO AznUOliNJxWHjQfm9yl40gsNEe7KOGl9mIwg/6xO77KkmbPsRQf0b5qpz zqvhj5/gkfKDEJIzQQo/kqZ4D1Exkgj8AU3tluR5rMubcfaJaDXoQ6jmK w==; X-CSE-ConnectionGUID: HI8DONHAT8ug9vlL4UfvLw== X-CSE-MsgGUID: 0oBpFQYuSH69JeiHxfcc7Q== X-IronPort-AV: E=McAfee;i="6800,10657,11531"; a="64685220" X-IronPort-AV: E=Sophos;i="6.17,312,1747724400"; d="scan'208";a="64685220" X-CSE-ConnectionGUID: XZx8DzGFRh2fe1CHggSopg== X-CSE-MsgGUID: QiS2WZVYTE2T0oLT5uugrw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,291,1754982000"; d="scan'208";a="188129072" From: Vivek Kasireddy To: qemu-devel@nongnu.org Cc: Vivek Kasireddy , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Akihiko Odaki , Dmitry Osipenko , Alex Williamson , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Subject: [PATCH v2 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Date: Sat, 8 Nov 2025 21:33:53 -0800 Message-ID: <20251109053801.2267149-11-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251109053801.2267149-1-vivek.kasireddy@intel.com> References: <20251109053801.2267149-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.17; 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_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_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: 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: 1762666836440158500 In addition to memfd, a blob resource can also have its backing storage in a VFIO device region. Therefore, we first need to figure out if the blob is backed by a VFIO device region or a memfd before we can call the right API to get a dmabuf fd created. So, once we have the ramblock and the associated mr, we rely on memory_region_is_ram_device() to tell us where the backing storage is located. If the blob resource is VFIO backed, we try to find the right VFIO device that contains the blob and then invoke the API vfio_device_create_dmabuf(). Note that in virtio_gpu_remap_udmabuf(), we first try to test if the VFIO dmabuf exporter supports mmap or not. If it doesn't, we use the VFIO device fd directly to create the CPU mapping. Cc: Marc-Andr=C3=A9 Lureau Cc: Alex Benn=C3=A9e Cc: Akihiko Odaki Cc: Dmitry Osipenko Cc: Alex Williamson Cc: C=C3=A9dric Le Goater Signed-off-by: Vivek Kasireddy --- hw/display/Kconfig | 5 ++ hw/display/virtio-gpu-dmabuf.c | 114 +++++++++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 7 deletions(-) diff --git a/hw/display/Kconfig b/hw/display/Kconfig index 1e95ab28ef..0d090f25f5 100644 --- a/hw/display/Kconfig +++ b/hw/display/Kconfig @@ -106,6 +106,11 @@ config VIRTIO_VGA depends on VIRTIO_PCI select VGA =20 +config VIRTIO_GPU_VFIO_BLOB + bool + default y + depends on VFIO + config VHOST_USER_GPU bool default y diff --git a/hw/display/virtio-gpu-dmabuf.c b/hw/display/virtio-gpu-dmabuf.c index 80143034d4..940b0e0411 100644 --- a/hw/display/virtio-gpu-dmabuf.c +++ b/hw/display/virtio-gpu-dmabuf.c @@ -18,6 +18,7 @@ #include "ui/console.h" #include "hw/virtio/virtio-gpu.h" #include "hw/virtio/virtio-gpu-pixman.h" +#include "hw/vfio/vfio-device.h" #include "trace.h" #include "system/ramblock.h" #include "system/hostmem.h" @@ -52,6 +53,19 @@ static bool qemu_iovec_same_memory_regions(const struct = iovec *iov, int iov_cnt) return true; } =20 +static void vfio_create_dmabuf(VFIODevice *vdev, + struct virtio_gpu_simple_resource *res) +{ +#if defined(VIRTIO_GPU_VFIO_BLOB) + res->dmabuf_fd =3D vfio_device_create_dmabuf_fd(vdev, res->iov, res->i= ov_cnt); + if (res->dmabuf_fd < 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: VFIO_DEVICE_FEATURE_DMA_BUF: %s\n", + __func__, strerror(errno)); + } +#endif +} + static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *r= es) { struct udmabuf_create_list *list; @@ -93,11 +107,69 @@ static void virtio_gpu_create_udmabuf(struct virtio_gp= u_simple_resource *res) g_free(list); } =20 -static void virtio_gpu_remap_dmabuf(struct virtio_gpu_simple_resource *res) +static void *vfio_dmabuf_mmap(struct virtio_gpu_simple_resource *res, + VFIODevice *vdev) +{ + struct vfio_region_info *info =3D NULL; + ram_addr_t offset, len =3D 0; + void *map, *submap; + int i, ret =3D -1; + RAMBlock *rb; + + /* + * We first reserve a contiguous chunk of address space for the entire + * dmabuf, then replace it with smaller mappings that correspond to the + * individual segments of the dmabuf. + */ + map =3D mmap(NULL, res->blob_size, PROT_READ, MAP_SHARED, vdev->fd, 0); + if (map =3D=3D MAP_FAILED) { + return map; + } + + for (i =3D 0; i < res->iov_cnt; i++) { + rb =3D qemu_ram_block_from_host(res->iov[i].iov_base, false, &offs= et); + if (!rb) { + goto err; + } +#if defined(VIRTIO_GPU_VFIO_BLOB) + ret =3D vfio_get_region_index_from_mr(rb->mr); + if (ret < 0) { + goto err; + } + + ret =3D vfio_device_get_region_info(vdev, ret, &info); +#endif + if (ret < 0 || !info) { + goto err; + } + + submap =3D mmap(map + len, res->iov[i].iov_len, PROT_READ, + MAP_SHARED | MAP_FIXED, vdev->fd, + info->offset + offset); + if (submap =3D=3D MAP_FAILED) { + goto err; + } + + len +=3D res->iov[i].iov_len; + } + return map; +err: + munmap(map, res->blob_size); + return MAP_FAILED; +} + +static void virtio_gpu_remap_dmabuf(struct virtio_gpu_simple_resource *res, + VFIODevice *vdev) { res->remapped =3D mmap(NULL, res->blob_size, PROT_READ, MAP_SHARED, res->dmabuf_fd, 0); if (res->remapped =3D=3D MAP_FAILED) { + if (vdev) { + res->remapped =3D vfio_dmabuf_mmap(res, vdev); + if (res->remapped !=3D MAP_FAILED) { + return; + } + } warn_report("%s: dmabuf mmap failed: %s", __func__, strerror(errno)); res->remapped =3D NULL; @@ -155,7 +227,10 @@ bool virtio_gpu_have_udmabuf(void) =20 void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res) { + VFIODevice *vdev =3D NULL; void *pdata =3D NULL; + ram_addr_t offset; + RAMBlock *rb; =20 res->dmabuf_fd =3D -1; if (res->iov_cnt =3D=3D 1 && @@ -166,11 +241,38 @@ void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_= resource *res) return; } =20 - virtio_gpu_create_udmabuf(res); - if (res->dmabuf_fd < 0) { + rb =3D qemu_ram_block_from_host(res->iov[0].iov_base, false, &offs= et); + if (memory_region_is_ram_device(rb->mr)) { + vdev =3D vfio_device_lookup(rb->mr); + if (!vdev) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Could not find device to create dmabuf\= n", + __func__); + return; + } + + vfio_create_dmabuf(vdev, res); + if (res->dmabuf_fd < 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Could not create dmabuf from vfio devic= e\n", + __func__); + return; + } + } else if (memory_region_is_ram(rb->mr)) { + virtio_gpu_create_udmabuf(res); + if (res->dmabuf_fd < 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Could not create dmabuf from memfd\n", + __func__); + return; + } + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: memory region cannot be used to create dmab= uf\n", + __func__); return; } - virtio_gpu_remap_dmabuf(res); + virtio_gpu_remap_dmabuf(res, vdev); if (!res->remapped) { return; } @@ -182,9 +284,7 @@ void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_re= source *res) =20 void virtio_gpu_fini_dmabuf(struct virtio_gpu_simple_resource *res) { - if (res->remapped) { - virtio_gpu_destroy_dmabuf(res); - } + virtio_gpu_destroy_dmabuf(res); } =20 static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf) --=20 2.50.1