From nobody Tue Feb 10 03:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=yandex-team.com ARC-Seal: i=1; a=rsa-sha256; t=1666005188; cv=none; d=zohomail.com; s=zohoarc; b=AZQYmvSBIxGJxLEQh1Pepc74XCj9Zxo5ZTIfm8wQVAR7WOta5wQhaRNIPT6IAKp46R4LXgpJ8VCxiA+NAoR+r7ja/yoytaYqJ3G8ZmO9zd2QUXwJRPqPoyofLUcpm6qQWOhWa+c1UCeo4vMu1gc166YjXTYaMMmBHvkGLnkw0rY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1666005188; 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=kMM+N5Dh3Fi28eWzt4V2B1pW2mzLtqj1Y0XpSfOP7mY=; b=RRnVZyW4gBetgsHE4dqn3edEKqXqXabNCUNYiQYgiXnJ+hY0TqClnn9zQlg2G+vdGtU/DjWym3xPFjgKja2I7tRZ0iK/yADK89i7FpKpkxL5iQx8WsIT9clPx03u1+wDhKigVEIUAmr0B7dV21VR2yxXN21577T87/5A5pygjjg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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 16660051882052.4644673580338576; Mon, 17 Oct 2022 04:13:08 -0700 (PDT) Received: from localhost ([::1]:51304 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1okO3P-00005Z-5J for importer@patchew.org; Mon, 17 Oct 2022 07:13:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33292) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1okNvy-0001Ry-8i for qemu-devel@nongnu.org; Mon, 17 Oct 2022 07:05:27 -0400 Received: from forwardcorp1b.mail.yandex.net ([178.154.239.136]:54280) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1okNvq-0001IJ-LW for qemu-devel@nongnu.org; Mon, 17 Oct 2022 07:05:22 -0400 Received: from sas1-7470331623bb.qloud-c.yandex.net (sas1-7470331623bb.qloud-c.yandex.net [IPv6:2a02:6b8:c08:bd1e:0:640:7470:3316]) by forwardcorp1b.mail.yandex.net (Yandex) with ESMTP id 65AD160E94; Mon, 17 Oct 2022 13:54:24 +0300 (MSK) Received: from dellarbn.yandex.net (unknown [2a02:6b8:0:107:3e85:844d:5b1d:60a]) by sas1-7470331623bb.qloud-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id PrI3KDUSQF-sM7KnEEA; Mon, 17 Oct 2022 13:54:23 +0300 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client certificate not present) Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.com; s=default; t=1666004063; bh=kMM+N5Dh3Fi28eWzt4V2B1pW2mzLtqj1Y0XpSfOP7mY=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=WlvErUzyA6X7SkoW/j5092EcTPJ5b2+cqD6rjdLR8+8EnpJ8LfpQbxpnHlsv7b75N hClnNVq6ArnZimO6ihku9LFAAnyEhMgN4+H8bLXHEP+JYDzVnJwgoJEIpWB7crqzvk dgQMRDi/7PaH460MBGJEF4Ah5l8rdyXTpAE2V18s= Authentication-Results: sas1-7470331623bb.qloud-c.yandex.net; dkim=pass header.i=@yandex-team.com From: Andrey Ryabinin To: qemu-devel@nongnu.org Cc: Steve Sistare , yc-core@yandex-team.ru, Andrey Ryabinin , Cornelia Huck , Thomas Huth , Alex Williamson , Tony Krowiak , Halil Pasic , Jason Herne , Eric Farman , Matthew Rosato , Paolo Bonzini , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Eduardo Habkost , Eric Blake , Markus Armbruster , Cleber Rosa , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Wainer dos Santos Moschetta , Beraldo Leal Subject: [PATCH 1/4] vfio: add vfio-container user createable object Date: Mon, 17 Oct 2022 13:54:04 +0300 Message-Id: <20221017105407.3858-2-arbn@yandex-team.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221017105407.3858-1-arbn@yandex-team.com> References: <20221017105407.3858-1-arbn@yandex-team.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+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=178.154.239.136; envelope-from=arbn@yandex-team.com; helo=forwardcorp1b.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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 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" X-ZohoMail-DKIM: pass (identity @yandex-team.com) X-ZM-MESSAGEID: 1666005190450100001 Content-Type: text/plain; charset="utf-8" Add vfio-container type and allow user to create vfio-container object via '-object' command line argument or 'object-add' qmp command. Add 'fd' parameter to this type to allow user provide file descriptor of a vfio-container. E.g. -object vfio-container,id=3Dct,fd=3D5 Signed-off-by: Andrey Ryabinin --- hw/vfio/common.c | 183 ++++++++++++++++++++++------------ hw/vfio/trace-events | 2 +- include/hw/vfio/vfio-common.h | 4 + qapi/qom.json | 14 +++ 4 files changed, 137 insertions(+), 66 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 6b5d8c0bf69..392057d3025 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -31,9 +31,11 @@ #include "exec/memory.h" #include "exec/ram_addr.h" #include "hw/hw.h" +#include "monitor/monitor.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/range.h" +#include "qom/object_interfaces.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" @@ -2013,7 +2015,7 @@ static int vfio_connect_container(VFIOGroup *group, A= ddressSpace *as, Error **errp) { VFIOContainer *container; - int ret, fd; + int ret; VFIOAddressSpace *space; =20 space =3D vfio_get_address_space(as); @@ -2069,31 +2071,15 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as, } } =20 - fd =3D qemu_open_old("/dev/vfio/vfio", O_RDWR); - if (fd < 0) { - error_setg_errno(errp, errno, "failed to open /dev/vfio/vfio"); - ret =3D -errno; - goto put_space_exit; - } + container =3D VFIO_CONTAINER(object_new(TYPE_VFIO_CONTAINER)); + container->space =3D space; =20 - ret =3D ioctl(fd, VFIO_GET_API_VERSION); - if (ret !=3D VFIO_API_VERSION) { - error_setg(errp, "supported vfio version: %d, " - "reported version: %d", VFIO_API_VERSION, ret); - ret =3D -EINVAL; - goto close_fd_exit; + user_creatable_complete(USER_CREATABLE(container), errp); + if (*errp) { + ret =3D -1; + goto free_container_exit; } =20 - container =3D g_malloc0(sizeof(*container)); - container->space =3D space; - container->fd =3D fd; - container->error =3D NULL; - container->dirty_pages_supported =3D false; - container->dma_max_mappings =3D 0; - QLIST_INIT(&container->giommu_list); - QLIST_INIT(&container->hostwin_list); - QLIST_INIT(&container->vrdl_list); - ret =3D vfio_init_container(container, group->fd, errp); if (ret) { goto free_container_exit; @@ -2150,7 +2136,7 @@ static int vfio_connect_container(VFIOGroup *group, A= ddressSpace *as, * in this file. */ if (!v2) { - ret =3D ioctl(fd, VFIO_IOMMU_ENABLE); + ret =3D ioctl(container->fd, VFIO_IOMMU_ENABLE); if (ret) { error_setg_errno(errp, errno, "failed to enable container"= ); ret =3D -errno; @@ -2171,7 +2157,7 @@ static int vfio_connect_container(VFIOGroup *group, A= ddressSpace *as, } =20 info.argsz =3D sizeof(info); - ret =3D ioctl(fd, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &info); + ret =3D ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &info); if (ret) { error_setg_errno(errp, errno, "VFIO_IOMMU_SPAPR_TCE_GET_INFO failed"); @@ -2209,7 +2195,6 @@ static int vfio_connect_container(VFIOGroup *group, A= ddressSpace *as, =20 vfio_kvm_device_add_group(group); =20 - QLIST_INIT(&container->group_list); QLIST_INSERT_HEAD(&space->containers, container, next); =20 group->container =3D container; @@ -2223,29 +2208,18 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as, ret =3D -1; error_propagate_prepend(errp, container->error, "memory listener initialization failed: "); - goto listener_release_exit; + goto free_container_exit; } =20 container->initialized =3D true; =20 return 0; -listener_release_exit: - QLIST_REMOVE(group, container_next); - QLIST_REMOVE(container, next); - vfio_kvm_device_del_group(group); - vfio_listener_release(container); =20 enable_discards_exit: vfio_ram_block_discard_disable(container, false); =20 free_container_exit: - g_free(container); - -close_fd_exit: - close(fd); - -put_space_exit: - vfio_put_address_space(space); + object_unref(OBJECT(container)); =20 return ret; } @@ -2271,32 +2245,7 @@ static void vfio_disconnect_container(VFIOGroup *gro= up) group->groupid); } =20 - if (QLIST_EMPTY(&container->group_list)) { - VFIOAddressSpace *space =3D container->space; - VFIOGuestIOMMU *giommu, *tmp; - VFIOHostDMAWindow *hostwin, *next; - - QLIST_REMOVE(container, next); - - QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, t= mp) { - memory_region_unregister_iommu_notifier( - MEMORY_REGION(giommu->iommu_mr), &giommu->n); - QLIST_REMOVE(giommu, giommu_next); - g_free(giommu); - } - - QLIST_FOREACH_SAFE(hostwin, &container->hostwin_list, hostwin_next, - next) { - QLIST_REMOVE(hostwin, hostwin_next); - g_free(hostwin); - } - - trace_vfio_disconnect_container(container->fd); - close(container->fd); - g_free(container); - - vfio_put_address_space(space); - } + object_unref(OBJECT(container)); } =20 VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) @@ -2628,3 +2577,107 @@ int vfio_eeh_as_op(AddressSpace *as, uint32_t op) } return vfio_eeh_container_op(container, op); } + +static void vfio_container_set_fd(Object *obj, const char *value, + Error **errp) +{ + VFIOContainer *ct =3D VFIO_CONTAINER(obj); + + ct->fd =3D monitor_fd_param(monitor_cur(), value, errp); +} + +static void vfio_container_complete(UserCreatable *uc, Error **errp) +{ + VFIOContainer *container =3D VFIO_CONTAINER(uc); + int ret; + + if (container->fd < 0) { + int fd; + + fd =3D qemu_open_old("/dev/vfio/vfio", O_RDWR); + if (fd < 0) { + error_setg_errno(errp, errno, "failed to open /dev/vfio/vfio"); + return; + } + container->fd =3D fd; + } + + ret =3D ioctl(container->fd, VFIO_GET_API_VERSION); + if (ret !=3D VFIO_API_VERSION) { + error_setg(errp, "supported vfio version: %d, " + "reported version: %d", VFIO_API_VERSION, ret); + return; + } +} + +static void vfio_container_class_init(ObjectClass *class, void *data) +{ + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(class); + ucc->complete =3D vfio_container_complete; + + object_class_property_add_str(class, "fd", NULL, vfio_container_set_fd= ); +} + +static void vfio_container_instance_init(Object *obj) +{ + VFIOContainer *ct =3D VFIO_CONTAINER(obj); + + ct->dirty_pages_supported =3D false; + ct->dma_max_mappings =3D 0; + ct->fd =3D -1; + QLIST_INIT(&ct->giommu_list); + QLIST_INIT(&ct->hostwin_list); + QLIST_INIT(&ct->group_list); + QLIST_INIT(&ct->vrdl_list); +} + +static void +vfio_container_instance_finalize(Object *obj) +{ + VFIOContainer *container =3D VFIO_CONTAINER(obj); + VFIOAddressSpace *space =3D container->space; + VFIOGuestIOMMU *giommu, *tmp; + VFIOHostDMAWindow *hostwin, *next; + + QLIST_REMOVE(container, next); + + QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) { + memory_region_unregister_iommu_notifier( + MEMORY_REGION(giommu->iommu_mr), &giommu->n); + QLIST_REMOVE(giommu, giommu_next); + g_free(giommu); + } + QLIST_FOREACH_SAFE(hostwin, &container->hostwin_list, hostwin_next, + next) { + QLIST_REMOVE(hostwin, hostwin_next); + g_free(hostwin); + } + + + trace_vfio_container_instance_finalize(container->fd); + if (container->fd > 0) { + close(container->fd); + } + if (space) { + vfio_put_address_space(space); + } +} + +static const TypeInfo vfio_container_info =3D { + .name =3D TYPE_VFIO_CONTAINER, + .parent =3D TYPE_OBJECT, + .class_init =3D vfio_container_class_init, + .instance_size =3D sizeof(VFIOContainer), + .instance_init =3D vfio_container_instance_init, + .instance_finalize =3D vfio_container_instance_finalize, + .interfaces =3D (InterfaceInfo[]) { + {TYPE_USER_CREATABLE}, + {} + }, +}; + +static void register_vfio_types(void) +{ + type_register_static(&vfio_container_info); +} +type_init(register_vfio_types) diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events index 73dffe9e00d..8b79cf33a33 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -104,7 +104,7 @@ vfio_known_safe_misalignment(const char *name, uint64_t= iova, uint64_t offset_wi vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint6= 4_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=3D0x%"PRIx64"= is not aligned to 0x%"PRIx64" and cannot be mapped for DMA" vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING regi= on_del 0x%"PRIx64" - 0x%"PRIx64 vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRI= x64" - 0x%"PRIx64 -vfio_disconnect_container(int fd) "close container->fd=3D%d" +vfio_container_instance_finalize(int fd) "close container->fd=3D%d" vfio_put_group(int fd) "close group->fd=3D%d" vfio_get_device(const char * name, unsigned int flags, unsigned int num_re= gions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u" vfio_put_base_device(int fd) "close vdev->fd=3D%d" diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index e573f5a9f19..0ab99060e44 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -77,6 +77,7 @@ typedef struct VFIOAddressSpace { struct VFIOGroup; =20 typedef struct VFIOContainer { + Object parent; VFIOAddressSpace *space; int fd; /* /dev/vfio/vfio, empowered by the attached groups */ MemoryListener listener; @@ -190,6 +191,9 @@ typedef struct VFIODisplay { } dmabuf; } VFIODisplay; =20 +#define TYPE_VFIO_CONTAINER "vfio-container" +OBJECT_DECLARE_SIMPLE_TYPE(VFIOContainer, VFIO_CONTAINER) + void vfio_put_base_device(VFIODevice *vbasedev); void vfio_disable_irqindex(VFIODevice *vbasedev, int index); void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); diff --git a/qapi/qom.json b/qapi/qom.json index 80dd419b392..d1a88e10b52 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -734,6 +734,18 @@ { 'struct': 'RemoteObjectProperties', 'data': { 'fd': 'str', 'devid': 'str' } } =20 +## +# @VFIOContainerProperties: +# +# Properties for vfio-container objects. +# +# @fd: file descriptor of vfio container +# +# Since: 7.2 +## +{ 'struct': 'VFIOContainerProperties', + 'data': { 'fd': 'str' } } + ## # @VfioUserServerProperties: # @@ -888,6 +900,7 @@ 'tls-creds-psk', 'tls-creds-x509', 'tls-cipher-suites', + 'vfio-container', { 'name': 'x-remote-object', 'features': [ 'unstable' ] }, { 'name': 'x-vfio-user-server', 'features': [ 'unstable' ] } ] } @@ -953,6 +966,7 @@ 'tls-creds-psk': 'TlsCredsPskProperties', 'tls-creds-x509': 'TlsCredsX509Properties', 'tls-cipher-suites': 'TlsCredsProperties', + 'vfio-container': 'VFIOContainerProperties', 'x-remote-object': 'RemoteObjectProperties', 'x-vfio-user-server': 'VfioUserServerProperties' } } --=20 2.37.3