Re: [RFC PATCH 4/7] dma-buf: uapi: Mechanism to revoke DMABUFs via ioctl()

From: Christian König

Date: Fri Feb 27 2026 - 05:11:28 EST


On 2/26/26 21:22, Matt Evans wrote:
> Add a new dma-buf ioctl() op, DMA_BUF_IOCTL_REVOKE, connected to a new
> (optional) dma_buf_ops callback, revoke(). An exporter receiving this
> will _permanently_ revoke the DMABUF, meaning it can no longer be
> mapped/attached/mmap()ed. It also guarantees that existing
> importers have been detached (e.g. via move_notify) and all mappings
> made inaccessible.
>
> This is useful for lifecycle management in scenarios where a process
> has created a DMABUF representing a resource, then delegated it to
> a client process; access to the resource is revoked when the client is
> deemed "done", and the resource can be safely re-used elsewhere.

Well that means revoking from the importer side. That absolutely doesn't make sense to me.

Why would you do that?

Regards,
Christian.

>
> Signed-off-by: Matt Evans <mattev@xxxxxxxx>
> ---
> drivers/dma-buf/dma-buf.c | 5 +++++
> include/linux/dma-buf.h | 22 ++++++++++++++++++++++
> include/uapi/linux/dma-buf.h | 1 +
> 3 files changed, 28 insertions(+)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index edaa9e4ee4ae..b9b315317f2d 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -561,6 +561,11 @@ static long dma_buf_ioctl(struct file *file,
> case DMA_BUF_IOCTL_IMPORT_SYNC_FILE:
> return dma_buf_import_sync_file(dmabuf, (const void __user *)arg);
> #endif
> + case DMA_BUF_IOCTL_REVOKE:
> + if (dmabuf->ops->revoke)
> + return dmabuf->ops->revoke(dmabuf);
> + else
> + return -EINVAL;
>
> default:
> return -ENOTTY;
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index 0bc492090237..a68c9ad7aebd 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -277,6 +277,28 @@ struct dma_buf_ops {
>
> int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map);
> void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map);
> +
> + /**
> + * @revoke:
> + *
> + * This callback is invoked from a userspace
> + * DMA_BUF_IOCTL_REVOKE operation, and requests that access to
> + * the buffer is immediately and permanently revoked. On
> + * successful return, the buffer is not accessible through any
> + * mmap() or dma-buf import. The request fails if the buffer
> + * is pinned; otherwise, the exporter marks the buffer as
> + * inaccessible and uses the move_notify callback to inform
> + * importers of the change. The buffer is permanently
> + * disabled, and the exporter must refuse all map, mmap,
> + * attach, etc. requests.
> + *
> + * Returns:
> + *
> + * 0 on success, or a negative error code on failure:
> + * -ENODEV if the associated device no longer exists/is closed.
> + * -EBADFD if the buffer has already been revoked.
> + */
> + int (*revoke)(struct dma_buf *dmabuf);
> };
>
> /**
> diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h
> index 5a6fda66d9ad..84bf2dd2d0f3 100644
> --- a/include/uapi/linux/dma-buf.h
> +++ b/include/uapi/linux/dma-buf.h
> @@ -178,5 +178,6 @@ struct dma_buf_import_sync_file {
> #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, __u64)
> #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file)
> #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file)
> +#define DMA_BUF_IOCTL_REVOKE _IO(DMA_BUF_BASE, 4)
>
> #endif
> --
> 2.47.3
>