Changelog: v5: * Documented the DMA-BUF expectations around DMA unmap. * Added wait support in VFIO for DMA unmap. * Reordered patches. * Improved commit messages to document even more. v4: https://lore.kernel.org/all/[email protected] * Changed DMA_RESV_USAGE_KERNEL to DMA_RESV_USAGE_BOOKKEEP. * Made .invalidate_mapping() truly optional. * Added patch which renames dma_buf_move_notify() to be dma_buf_invalidate_mappings(). * Restored dma_buf_attachment_is_dynamic() function. v3: https://lore.kernel.org/all/[email protected]/ * Used Jason's wordings for commits and cover letter. * Removed IOMMUFD patch. * Renamed dma_buf_attachment_is_revoke() to be dma_buf_attach_revocable(). * Added patch to remove CONFIG_DMABUF_MOVE_NOTIFY. * Added Reviewed-by tags. * Called to dma_resv_wait_timeout() after dma_buf_move_notify() in VFIO. * Added dma_buf_attach_revocable() check to VFIO DMABUF attach function. * Slightly changed commit messages. v2: https://patch.msgid.link/[email protected] * Changed series to document the revoke semantics instead of implementing it. v1: https://patch.msgid.link/[email protected]
------------------------------------------------------------------------- This series is based on latest VFIO fix, which will be sent to Linus very soon. https://lore.kernel.org/all/[email protected]/ Thanks ------------------------------------------------------------------------- This series documents a dma-buf “revoke” mechanism: to allow a dma-buf exporter to explicitly invalidate (“kill”) a shared buffer after it has been distributed to importers, so that further CPU and device access is prevented and importers reliably observe failure. The change in this series is to properly document and use existing core “revoked” state on the dma-buf object and a corresponding exporter-triggered revoke operation. dma-buf has quietly allowed calling move_notify on pinned dma-bufs, even though legacy importers using dma_buf_attach() would simply ignore these calls. The intention was that move_notify() would tell the importer to expedite it's unmapping process and once the importer is fully finished with DMA it would unmap the dma-buf which finally signals that the importer is no longer ever going to touch the memory again. Importers that touch past their unmap() call can trigger IOMMU errors, AER and beyond, however read-and-discard access between move_notify() and unmap is allowed. Thus, we can define the exporter's revoke sequence for pinned dma-buf as: dma_resv_lock(dmabuf->resv, NULL); // Prevent new mappings from being established priv->revoked = true; // Tell all importers to eventually unmap dma_buf_invalidate_mappings(dmabuf); // Wait for any inprogress fences on the old mapping dma_resv_wait_timeout(dmabuf->resv, DMA_RESV_USAGE_BOOKKEEP, false, MAX_SCHEDULE_TIMEOUT); dma_resv_unlock(dmabuf->resv, NULL); // Wait for all importers to complete unmap wait_for_completion(&priv->unmapp_comp); However, dma-buf also supports importers that don't do anything on move_notify(), and will not unmap the buffer in bounded time. Since such importers would cause the above sequence to hang, a new mechanism is needed to detect incompatible importers. Introduce dma_buf_attach_revocable() which if true indicates the above sequence is safe to use and will complete in kernel-only bounded time for this attachment. Unfortunately dma_buf_attach_revocable() is going to fail for the popular RDMA pinned importer, which means we cannot introduce it to existing places using pinned move_notify() without potentially breaking existing userspace flows. Existing exporters that only trigger this flow for RAS errors should not call dma_buf_attach_revocable() and will suffer an unbounded block on the final completion, hoping that the userspace will notice the RAS and clean things up. Without revoke support on the RDMA pinned importers it doesn't seem like any other non-breaking option is currently possible. For new exporters, like VFIO and RDMA, that have userspace triggered revoke events, the unbouned sleep would not be acceptable. They can call dma_buf_attach_revocable() and will not work with the RDMA pinned importer from day 0, preventing regressions. In the process add documentation explaining the above details. Thanks Signed-off-by: Leon Romanovsky <[email protected]> --- Leon Romanovsky (8): dma-buf: Rename .move_notify() callback to a clearer identifier dma-buf: Rename dma_buf_move_notify() to dma_buf_invalidate_mappings() dma-buf: Always build with DMABUF_MOVE_NOTIFY vfio: Wait for dma-buf invalidation to complete dma-buf: Make .invalidate_mapping() truly optional dma-buf: Add dma_buf_attach_revocable() vfio: Permit VFIO to work with pinned importers iommufd: Add dma_buf_pin() drivers/dma-buf/Kconfig | 12 ---- drivers/dma-buf/dma-buf.c | 69 +++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 14 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- drivers/gpu/drm/amd/amdkfd/Kconfig | 2 +- drivers/gpu/drm/virtio/virtgpu_prime.c | 2 +- drivers/gpu/drm/xe/tests/xe_dma_buf.c | 7 +-- drivers/gpu/drm/xe/xe_bo.c | 2 +- drivers/gpu/drm/xe/xe_dma_buf.c | 14 ++--- drivers/infiniband/core/umem_dmabuf.c | 13 ----- drivers/infiniband/hw/mlx5/mr.c | 2 +- drivers/iommu/iommufd/pages.c | 11 +++- drivers/iommu/iommufd/selftest.c | 2 +- drivers/vfio/pci/vfio_pci_dmabuf.c | 90 +++++++++++++++++++++++------ include/linux/dma-buf.h | 17 +++--- 15 files changed, 164 insertions(+), 95 deletions(-) --- base-commit: 61ceaf236115f20f4fdd7cf60f883ada1063349a change-id: 20251221-dmabuf-revoke-b90ef16e4236 Best regards, -- Leon Romanovsky <[email protected]>
