From nobody Thu Jul 3 15:44:11 2025 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1621896323; cv=none; d=zohomail.com; s=zohoarc; b=R9rFTx0YEdh3T0hhx9N/iYF7HShk2+CM8jD9ItoVKtLrH+CNH2MmAWpZ7eVuo6d62aIdtmY6lczrK8uxIuEPGKV0YsV6787DKtL3f0q8sOOjlCCozQ/h65i21K4lX5A1Io2hU5LPlYi20/RNx5zr9z3X0odOm3zw7Ei1R1vUdiQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621896323; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=HgIriUPU94igG6UFhq9AMlZOTG5HqG5EF2ufo5Oa6Kw=; b=lxJzrZId4J//HfDViS6cmY18jcKU4l+hh7NKNLxSkRR+nISKiIDDRhlu3qzYAcbW9TKZbql8M6/FA1lB8rIf3qtaJcb1GTa0mt3zRUVZb6l3mdsDvKI9467LyW6T837ZjQtebCVMJY0mgJTJvve3jy6sMbIDjA859qz73suGCxI= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621896323157276.26784858373014; Mon, 24 May 2021 15:45:23 -0700 (PDT) Received: from localhost ([::1]:59486 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llJK6-0000wA-52 for importer2@patchew.org; Mon, 24 May 2021 18:45:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33438) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llJIK-0006rm-UV for qemu-devel@nongnu.org; Mon, 24 May 2021 18:43:32 -0400 Received: from mga05.intel.com ([192.55.52.43]:11755) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llJII-0006he-Oa for qemu-devel@nongnu.org; Mon, 24 May 2021 18:43:32 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 May 2021 15:43:17 -0700 Received: from vkasired-desk2.fm.intel.com ([10.105.128.127]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 May 2021 15:43:17 -0700 IronPort-SDR: r+jJrwFgqNBqDTUDGri6seHvhV1L65k3R/YvKv64eewJkFD9IjOSGvcOuMjQwacCiXTlmte78D IqGlwLmLJwkg== X-IronPort-AV: E=McAfee;i="6200,9189,9994"; a="287620900" X-IronPort-AV: E=Sophos;i="5.82,327,1613462400"; d="scan'208";a="287620900" IronPort-SDR: bLR8AAw4fP+ac+d52Mpr1XPWZmnFZd13qg/2TZsJCQ7kdo9YjKu06VuK5EhsujkqeXUG2o6Nkw 5CTsYEB9fQ1w== X-IronPort-AV: E=Sophos;i="5.82,327,1613462400"; d="scan'208";a="546246747" From: Vivek Kasireddy To: qemu-devel@nongnu.org Subject: [PATCH v6 03/13] virtio-gpu: Add udmabuf helpers Date: Mon, 24 May 2021 15:30:53 -0700 Message-Id: <20210524223103.922910-4-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210524223103.922910-1-vivek.kasireddy@intel.com> References: <20210524223103.922910-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 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+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.55.52.43; envelope-from=vivek.kasireddy@intel.com; helo=mga05.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, 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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vivek Kasireddy , Gerd Hoffmann Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add helper functions to create a dmabuf for a resource and mmap it. Also, introduce the fields blob and blob_size so that these helpers can start to use them but the full picture will emerge only after adding create_blob API in patch 8 of this series. To be able to create a dmabuf using the udmabuf driver, Qemu needs to be lauched with the memfd memory backend like this: qemu-system-x86_64 -m 8192m -object memory-backend-memfd,id=3Dmem1,size=3D8= 192M -machine memory-backend=3Dmem1 Based-on-patch-by: Gerd Hoffmann Cc: Gerd Hoffmann Signed-off-by: Vivek Kasireddy --- hw/display/meson.build | 2 +- hw/display/virtio-gpu-udmabuf.c | 180 ++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-gpu.h | 11 ++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 hw/display/virtio-gpu-udmabuf.c diff --git a/hw/display/meson.build b/hw/display/meson.build index aaf797c5e9..224b33f2bb 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -55,7 +55,7 @@ softmmu_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true:= files('ati.c', 'ati_2d if config_all_devices.has_key('CONFIG_VIRTIO_GPU') virtio_gpu_ss =3D ss.source_set() virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU', - if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c'), = pixman]) + if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c', '= virtio-gpu-udmabuf.c'), pixman]) virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: files('vhost-u= ser-gpu.c')) hw_display_modules +=3D {'virtio-gpu': virtio_gpu_ss} =20 diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabu= f.c new file mode 100644 index 0000000000..1d5f3e3db2 --- /dev/null +++ b/hw/display/virtio-gpu-udmabuf.c @@ -0,0 +1,180 @@ +/* + * Virtio GPU Device + * + * Copyright Red Hat, Inc. 2013-2014 + * + * Authors: + * Dave Airlie + * Gerd Hoffmann + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qemu-common.h" +#include "qemu/iov.h" +#include "ui/console.h" +#include "hw/virtio/virtio-gpu.h" +#include "hw/virtio/virtio-gpu-pixman.h" +#include "trace.h" + +#ifdef CONFIG_LINUX + +#include "exec/ramblock.h" +#include "sysemu/hostmem.h" +#include +#include +#include +#include "standard-headers/linux/udmabuf.h" + +static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *r= es) +{ + struct udmabuf_create_list *list; + RAMBlock *rb; + ram_addr_t offset; + int udmabuf, i; + + udmabuf =3D udmabuf_fd(); + if (udmabuf < 0) { + return; + } + + list =3D g_malloc0(sizeof(struct udmabuf_create_list) + + sizeof(struct udmabuf_create_item) * res->iov_cnt); + + for (i =3D 0; i < res->iov_cnt; i++) { + rcu_read_lock(); + rb =3D qemu_ram_block_from_host(res->iov[i].iov_base, false, &offs= et); + rcu_read_unlock(); + + if (!rb || rb->fd < 0) { + g_free(list); + return; + } + + list->list[i].memfd =3D rb->fd; + list->list[i].offset =3D offset; + list->list[i].size =3D res->iov[i].iov_len; + } + + list->count =3D res->iov_cnt; + list->flags =3D UDMABUF_FLAGS_CLOEXEC; + + res->dmabuf_fd =3D ioctl(udmabuf, UDMABUF_CREATE_LIST, list); + if (res->dmabuf_fd < 0) { + warn_report("%s: UDMABUF_CREATE_LIST: %s", __func__, + strerror(errno)); + } + g_free(list); +} + +static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *re= s) +{ + res->remapped =3D mmap(NULL, res->blob_size, PROT_READ, + MAP_SHARED, res->dmabuf_fd, 0); + if (res->remapped =3D=3D MAP_FAILED) { + warn_report("%s: dmabuf mmap failed: %s", __func__, + strerror(errno)); + res->remapped =3D NULL; + } +} + +static void virtio_gpu_destroy_udmabuf(struct virtio_gpu_simple_resource *= res) +{ + if (res->remapped) { + munmap(res->remapped, res->blob_size); + res->remapped =3D NULL; + } + if (res->dmabuf_fd >=3D 0) { + close(res->dmabuf_fd); + res->dmabuf_fd =3D -1; + } +} + +static int find_memory_backend_type(Object *obj, void *opaque) +{ + bool *memfd_backend =3D opaque; + int ret; + + if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { + HostMemoryBackend *backend =3D MEMORY_BACKEND(obj); + RAMBlock *rb =3D backend->mr.ram_block; + + if (rb && rb->fd > 0) { + ret =3D fcntl(rb->fd, F_GET_SEALS); + if (ret > 0) { + *memfd_backend =3D true; + } + } + } + + return 0; +} + +bool virtio_gpu_have_udmabuf(void) +{ + Object *memdev_root; + int udmabuf; + bool memfd_backend =3D false; + + udmabuf =3D udmabuf_fd(); + if (udmabuf < 0) { + return false; + } + + memdev_root =3D object_resolve_path("/objects", NULL); + object_child_foreach(memdev_root, find_memory_backend_type, &memfd_bac= kend); + + return memfd_backend; +} + +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res) +{ + void *pdata =3D NULL; + + res->dmabuf_fd =3D -1; + if (res->iov_cnt =3D=3D 1) { + pdata =3D res->iov[0].iov_base; + } else { + virtio_gpu_create_udmabuf(res); + if (res->dmabuf_fd < 0) { + return; + } + virtio_gpu_remap_udmabuf(res); + if (!res->remapped) { + return; + } + pdata =3D res->remapped; + } + + res->blob =3D pdata; +} + +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res) +{ + if (res->remapped) { + virtio_gpu_destroy_udmabuf(res); + } +} + +#else + +bool virtio_gpu_have_udmabuf(void) +{ + /* nothing (stub) */ + return false; +} + +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res) +{ + /* nothing (stub) */ +} + +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res) +{ + /* nothing (stub) */ +} + +#endif diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 8ca2c55d9a..265b1c516c 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -50,6 +50,12 @@ struct virtio_gpu_simple_resource { uint32_t scanout_bitmask; pixman_image_t *image; uint64_t hostmem; + + uint64_t blob_size; + void *blob; + int dmabuf_fd; + uint8_t *remapped; + QTAILQ_ENTRY(virtio_gpu_simple_resource) next; }; =20 @@ -238,6 +244,11 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g, struct virtio_gpu_scanout *s, uint32_t resource_id); =20 +/* virtio-gpu-udmabuf.c */ +bool virtio_gpu_have_udmabuf(void); +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res); +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res); + /* virtio-gpu-3d.c */ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); --=20 2.30.2