From nobody Mon Nov 25 07:39:57 2024 Delivered-To: importer@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+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=movementarian.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1716999957505951.2413404264139; Wed, 29 May 2024 09:25:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sCM72-0001HG-Kh; Wed, 29 May 2024 12:25:16 -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 1sCM6x-00019t-QR for qemu-devel@nongnu.org; Wed, 29 May 2024 12:25:11 -0400 Received: from ssh.movementarian.org ([139.162.205.133] helo=movementarian.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sCM6v-0006Ki-C9 for qemu-devel@nongnu.org; Wed, 29 May 2024 12:25:11 -0400 Received: from movement by movementarian.org with local (Exim 4.95) (envelope-from ) id 1sCM6i-006COe-St; Wed, 29 May 2024 17:24:56 +0100 From: John Levon To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, jag.raman@oracle.com, thanos.makatos@nutanix.com, John Levon , John Johnson , Elena Ufimtseva Subject: [PATCH 03/26] vfio/container: support VFIO_DMA_UNMAP_FLAG_ALL Date: Wed, 29 May 2024 17:22:56 +0100 Message-Id: <20240529162319.1476680-4-levon@movementarian.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240529162319.1476680-1-levon@movementarian.org> References: <20240529162319.1476680-1-levon@movementarian.org> 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=139.162.205.133; envelope-from=movement@movementarian.org; helo=movementarian.org X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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-ZM-MESSAGEID: 1716999958464100008 Content-Type: text/plain; charset="utf-8" From: John Levon Some containers can directly implement unmapping all regions; add a new flag to support this. Originally-by: John Johnson Signed-off-by: Elena Ufimtseva Signed-off-by: Jagannathan Raman Signed-off-by: John Levon --- hw/vfio/common.c | 24 +++++++---------- hw/vfio/container-base.c | 4 +-- hw/vfio/container.c | 38 +++++++++++++++++++++++++-- hw/vfio/iommufd.c | 19 +++++++++++++- include/hw/vfio/vfio-common.h | 1 + include/hw/vfio/vfio-container-base.h | 4 +-- 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index a18af7a94f..ac89bc4b02 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -330,7 +330,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOM= MUTLBEntry *iotlb) } } else { ret =3D vfio_container_dma_unmap(bcontainer, iova, - iotlb->addr_mask + 1, iotlb); + iotlb->addr_mask + 1, iotlb, 0); if (ret) { error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx") =3D %d (%s)", @@ -354,7 +354,7 @@ static void vfio_ram_discard_notify_discard(RamDiscardL= istener *rdl, int ret; =20 /* Unmap with a single call. */ - ret =3D vfio_container_dma_unmap(bcontainer, iova, size , NULL); + ret =3D vfio_container_dma_unmap(bcontainer, iova, size, NULL, 0); if (ret) { error_report("%s: vfio_container_dma_unmap() failed: %s", __func__, strerror(-ret)); @@ -806,21 +806,15 @@ static void vfio_listener_region_del(MemoryListener *= listener, } =20 if (try_unmap) { + int flags =3D 0; + if (int128_eq(llsize, int128_2_64())) { - /* The unmap ioctl doesn't accept a full 64-bit span. */ - llsize =3D int128_rshift(llsize, 1); - ret =3D vfio_container_dma_unmap(bcontainer, iova, - int128_get64(llsize), NULL); - if (ret) { - error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx= ", " - "0x%"HWADDR_PRIx") =3D %d (%s)", - bcontainer, iova, int128_get64(llsize), ret, - strerror(-ret)); - } - iova +=3D int128_get64(llsize); + flags =3D VFIO_DMA_UNMAP_FLAG_ALL; } - ret =3D vfio_container_dma_unmap(bcontainer, iova, - int128_get64(llsize), NULL); + + ret =3D vfio_container_dma_unmap(bcontainer, iova, int128_get64(ll= size), + NULL, flags); + if (ret) { error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx") =3D %d (%s)", diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c index f16766f490..3b2d3f38d5 100644 --- a/hw/vfio/container-base.c +++ b/hw/vfio/container-base.c @@ -26,10 +26,10 @@ int vfio_container_dma_map(VFIOContainerBase *bcontaine= r, =20 int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) + IOMMUTLBEntry *iotlb, int flags) { g_assert(bcontainer->ops->dma_unmap); - return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb); + return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb, flags= ); } =20 bool vfio_container_add_section_window(VFIOContainerBase *bcontainer, diff --git a/hw/vfio/container.c b/hw/vfio/container.c index 6e6308382f..27ddb894e9 100644 --- a/hw/vfio/container.c +++ b/hw/vfio/container.c @@ -118,7 +118,7 @@ unmap_exit: */ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) + IOMMUTLBEntry *iotlb, int flags) { const VFIOContainer *container =3D container_of(bcontainer, VFIOContai= ner, bcontainer); @@ -141,6 +141,34 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBa= se *bcontainer, need_dirty_sync =3D true; } =20 + /* use unmap all if supported */ + if (flags & VFIO_DMA_UNMAP_FLAG_ALL) { + unmap.iova =3D 0; + unmap.size =3D 0; + if (container->unmap_all_supported) { + ret =3D ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, unmap); + } else { + /* unmap in halves */ + Int128 llsize =3D int128_rshift(int128_2_64(), 1); + + unmap.size =3D int128_get64(llsize); + + ret =3D ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, unmap); + + if (ret =3D=3D 0) { + unmap.iova +=3D int128_get64(llsize); + + ret =3D ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, unmap); + } + } + + if (ret !=3D 0) { + return -errno; + } + + goto out; + } + while (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) { /* * The type1 backend has an off-by-one bug in the kernel (71a7d3d7= 8e3c @@ -164,6 +192,7 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBas= e *bcontainer, return -errno; } =20 +out: if (need_dirty_sync) { ret =3D vfio_get_dirty_bitmap(bcontainer, iova, size, iotlb->translated_addr, &local_err); @@ -201,7 +230,7 @@ static int vfio_legacy_dma_map(const VFIOContainerBase = *bcontainer, hwaddr iova, */ if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) =3D=3D 0 || (errno =3D=3D EBUSY && - vfio_legacy_dma_unmap(bcontainer, iova, size, NULL) =3D=3D 0 && + vfio_legacy_dma_unmap(bcontainer, iova, size, NULL, 0) =3D=3D 0 && ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) =3D=3D 0)) { return 0; } @@ -533,6 +562,11 @@ static bool vfio_legacy_setup(VFIOContainerBase *bcont= ainer, Error **errp) vfio_get_info_iova_range(info, bcontainer); =20 vfio_get_iommu_info_migration(container, info); + + ret =3D ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UNMAP_ALL); + + container->unmap_all_supported =3D (ret !=3D 0); + return true; } =20 diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index 3d08a4f2dc..7bcadacd0b 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -40,11 +40,28 @@ static int iommufd_cdev_map(const VFIOContainerBase *bc= ontainer, hwaddr iova, =20 static int iommufd_cdev_unmap(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) + IOMMUTLBEntry *iotlb, int flags) { const VFIOIOMMUFDContainer *container =3D container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); =20 + /* unmap in halves */ + if (flags & VFIO_DMA_UNMAP_FLAG_ALL) { + Int128 llsize =3D int128_rshift(int128_2_64(), 1); + int ret; + + ret =3D iommufd_backend_unmap_dma(container->be, container->ioas_i= d, + iova, int128_get64(llsize)); + iova +=3D int128_get64(llsize); + + if (ret =3D=3D 0) { + ret =3D iommufd_backend_unmap_dma(container->be, container->io= as_id, + iova, int128_get64(llsize)); + } + + return ret; + } + /* TODO: Handle dma_unmap_bitmap with iotlb args (migration) */ return iommufd_backend_unmap_dma(container->be, container->ioas_id, iova, size); diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 4cb1ab8645..d112c9b72f 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -79,6 +79,7 @@ typedef struct VFIOContainer { VFIOContainerBase bcontainer; int fd; /* /dev/vfio/vfio, empowered by the attached groups */ unsigned iommu_type; + bool unmap_all_supported; QLIST_HEAD(, VFIOGroup) group_list; } VFIOContainer; =20 diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-c= ontainer-base.h index e9b59c179e..c2c1af70ac 100644 --- a/include/hw/vfio/vfio-container-base.h +++ b/include/hw/vfio/vfio-container-base.h @@ -75,7 +75,7 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer, void *vaddr, bool readonly, MemoryRegion *mrp); int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); + IOMMUTLBEntry *iotlb, int flags); bool vfio_container_add_section_window(VFIOContainerBase *bcontainer, MemoryRegionSection *section, Error **errp); @@ -118,7 +118,7 @@ struct VFIOIOMMUClass { void *vaddr, bool readonly, MemoryRegion *mrp); int (*dma_unmap)(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); + IOMMUTLBEntry *iotlb, int flags); bool (*attach_device)(const char *name, VFIODevice *vbasedev, AddressSpace *as, Error **errp); void (*detach_device)(VFIODevice *vbasedev); --=20 2.34.1