From nobody Tue Feb 10 01:31:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D976279DC2; Sat, 24 Jan 2026 19:14:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769282085; cv=none; b=dB4of6cMQ/uU1clorqQ9+u20qP9gfmQuZdGd1GQvG70Us1dcV/dmvJlwkvEXC8O/adKS0iPHKb6G3ynTDslDOWvRrQhzA1xceOaoCXFpN1pdjsU2P0mO+NELxM4e04nlY2AioHc9joJ1ylW8Kb/Atpa6MF0eBbS1wcQhI28DZnE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769282085; c=relaxed/simple; bh=CetJhzK/dmJBLMz+bJ3CPsyRZ1nlFNOkolpObmDVtz0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BDRIxteXioG/olMe6bHdCTPaFe+J1MOAl3YITvfjJiqme9lnL/4LrYRHHA8tG0NfiHrQmJNIpKFJfwd+9C7mWHgPuWJvMXliXcUekG3YGfSDHUKb+mlqSTH+rqdQ6iwohQhVyN4+KydxzaOt9bcxgeujjyihOhFpSqKMn2OPJ98= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E+qed9+U; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="E+qed9+U" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4919EC116D0; Sat, 24 Jan 2026 19:14:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1769282085; bh=CetJhzK/dmJBLMz+bJ3CPsyRZ1nlFNOkolpObmDVtz0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E+qed9+Um7iVv80TsYOZWcZP/rGetC2sBL0P71rj7wOgBsepUTx+mQdMIs2O/EZks 0kAOtfqtoLQOIBfakbep3vrzY0fCcXQtPi3z+6BArClW8bea2cOmrO23I9/bdYLNbU kDzk5WO5rqbVTAc7dvGF9WBPw9+Er8VHQp43qL6xnXNQqT7xLFYZSTuhUV6KsfKktO NipQR3kxjznWtTOeH2N9WZ8YRNAvhkFxqqMh85dhpKXlQoD71qMVuS3yPZqJOQJHop iqRFDRQ6q4yCHx2JhCaclV2D6e7InQZdTWQoAyo54iojwnNaZxeCC76LKq3ZFC7cYu g8cy/twabgHaQ== From: Leon Romanovsky To: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Alex Deucher , David Airlie , Simona Vetter , Gerd Hoffmann , Dmitry Osipenko , Gurchetan Singh , Chia-I Wu , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Lucas De Marchi , =?utf-8?q?Thomas_Hellstr=C3=B6m?= , Rodrigo Vivi , Jason Gunthorpe , Leon Romanovsky , Kevin Tian , Joerg Roedel , Will Deacon , Robin Murphy , Felix Kuehling , Alex Williamson , Ankit Agrawal , Vivek Kasireddy Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, amd-gfx@lists.freedesktop.org, virtualization@lists.linux.dev, intel-xe@lists.freedesktop.org, linux-rdma@vger.kernel.org, iommu@lists.linux.dev, kvm@vger.kernel.org Subject: [PATCH v5 4/8] vfio: Wait for dma-buf invalidation to complete Date: Sat, 24 Jan 2026 21:14:16 +0200 Message-ID: <20260124-dmabuf-revoke-v5-4-f98fca917e96@nvidia.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260124-dmabuf-revoke-v5-0-f98fca917e96@nvidia.com> References: <20260124-dmabuf-revoke-v5-0-f98fca917e96@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.15-dev-47773 Content-Transfer-Encoding: quoted-printable From: Leon Romanovsky dma-buf invalidation is handled asynchronously by the hardware, so VFIO must wait until all affected objects have been fully invalidated. In addition, the dma-buf exporter is expecting that all importers unmap any buffers they previously mapped. Fixes: 5d74781ebc86 ("vfio/pci: Add dma-buf export support for MMIO regions= ") Signed-off-by: Leon Romanovsky Reviewed-by: Alex Williamson Reviewed-by: Kevin Tian --- drivers/vfio/pci/vfio_pci_dmabuf.c | 71 ++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci= _dmabuf.c index d8ceafabef48..485515629fe4 100644 --- a/drivers/vfio/pci/vfio_pci_dmabuf.c +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c @@ -17,6 +17,8 @@ struct vfio_pci_dma_buf { struct dma_buf_phys_vec *phys_vec; struct p2pdma_provider *provider; u32 nr_ranges; + struct kref kref; + struct completion comp; u8 revoked : 1; }; =20 @@ -44,27 +46,46 @@ static int vfio_pci_dma_buf_attach(struct dma_buf *dmab= uf, return 0; } =20 +static void vfio_pci_dma_buf_done(struct kref *kref) +{ + struct vfio_pci_dma_buf *priv =3D + container_of(kref, struct vfio_pci_dma_buf, kref); + + complete(&priv->comp); +} + static struct sg_table * vfio_pci_dma_buf_map(struct dma_buf_attachment *attachment, enum dma_data_direction dir) { struct vfio_pci_dma_buf *priv =3D attachment->dmabuf->priv; + struct sg_table *ret; =20 dma_resv_assert_held(priv->dmabuf->resv); =20 if (priv->revoked) return ERR_PTR(-ENODEV); =20 - return dma_buf_phys_vec_to_sgt(attachment, priv->provider, - priv->phys_vec, priv->nr_ranges, - priv->size, dir); + ret =3D dma_buf_phys_vec_to_sgt(attachment, priv->provider, + priv->phys_vec, priv->nr_ranges, + priv->size, dir); + if (IS_ERR(ret)) + return ret; + + kref_get(&priv->kref); + return ret; } =20 static void vfio_pci_dma_buf_unmap(struct dma_buf_attachment *attachment, struct sg_table *sgt, enum dma_data_direction dir) { + struct vfio_pci_dma_buf *priv =3D attachment->dmabuf->priv; + + dma_resv_assert_held(priv->dmabuf->resv); + dma_buf_free_sgt(attachment, sgt, dir); + kref_put(&priv->kref, vfio_pci_dma_buf_done); } =20 static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf) @@ -287,6 +308,9 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_= device *vdev, u32 flags, goto err_dev_put; } =20 + kref_init(&priv->kref); + init_completion(&priv->comp); + /* dma_buf_put() now frees priv */ INIT_LIST_HEAD(&priv->dmabufs_elm); down_write(&vdev->memory_lock); @@ -326,6 +350,8 @@ void vfio_pci_dma_buf_move(struct vfio_pci_core_device = *vdev, bool revoked) lockdep_assert_held_write(&vdev->memory_lock); =20 list_for_each_entry_safe(priv, tmp, &vdev->dmabufs, dmabufs_elm) { + unsigned long wait; + if (!get_file_active(&priv->dmabuf->file)) continue; =20 @@ -333,7 +359,37 @@ void vfio_pci_dma_buf_move(struct vfio_pci_core_device= *vdev, bool revoked) dma_resv_lock(priv->dmabuf->resv, NULL); priv->revoked =3D revoked; dma_buf_invalidate_mappings(priv->dmabuf); + dma_resv_wait_timeout(priv->dmabuf->resv, + DMA_RESV_USAGE_BOOKKEEP, false, + MAX_SCHEDULE_TIMEOUT); dma_resv_unlock(priv->dmabuf->resv); + if (revoked) { + kref_put(&priv->kref, vfio_pci_dma_buf_done); + /* Let's wait till all DMA unmap are completed. */ + wait =3D wait_for_completion_timeout( + &priv->comp, secs_to_jiffies(1)); + /* + * If you see this WARN_ON, it means that + * importer didn't call unmap in response to + * dma_buf_invalidate_mappings() which is not + * allowed. + */ + WARN(!wait, + "Timed out waiting for DMABUF unmap, importer has a broken invali= date_mapping()"); + } else { + /* + * Kref is initialize again, because when revoke + * was performed the reference counter was decreased + * to zero to trigger completion. + */ + kref_init(&priv->kref); + /* + * There is no need to wait as no mapping was + * performed when the previous status was + * priv->revoked =3D=3D true. + */ + reinit_completion(&priv->comp); + } } fput(priv->dmabuf->file); } @@ -346,6 +402,8 @@ void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_devi= ce *vdev) =20 down_write(&vdev->memory_lock); list_for_each_entry_safe(priv, tmp, &vdev->dmabufs, dmabufs_elm) { + unsigned long wait; + if (!get_file_active(&priv->dmabuf->file)) continue; =20 @@ -354,7 +412,14 @@ void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_dev= ice *vdev) priv->vdev =3D NULL; priv->revoked =3D true; dma_buf_invalidate_mappings(priv->dmabuf); + dma_resv_wait_timeout(priv->dmabuf->resv, + DMA_RESV_USAGE_BOOKKEEP, false, + MAX_SCHEDULE_TIMEOUT); dma_resv_unlock(priv->dmabuf->resv); + kref_put(&priv->kref, vfio_pci_dma_buf_done); + wait =3D wait_for_completion_timeout(&priv->comp, + secs_to_jiffies(1)); + WARN_ON(!wait); vfio_device_put_registration(&vdev->vdev); fput(priv->dmabuf->file); } --=20 2.52.0