On 5/13/25 11:27, wangtao wrote: > Add DMA_BUF_IOCTL_RW_FILE to save/restore data from/to a dma-buf.
Similar approach where rejected before in favor of using udmabuf. Is there any reason you can't use that approach as well? Regards, Christian. > > Signed-off-by: wangtao <tao.wang...@honor.com> > --- > drivers/dma-buf/dma-buf.c | 8 ++++++++ > include/linux/dma-buf.h | 3 +++ > include/uapi/linux/dma-buf.h | 29 +++++++++++++++++++++++++++++ > 3 files changed, 40 insertions(+) > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 5baa83b85515..95d8b0158ffd 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -460,6 +460,7 @@ static long dma_buf_ioctl(struct file *file, > struct dma_buf *dmabuf; > struct dma_buf_sync sync; > enum dma_data_direction direction; > + struct dma_buf_rw_file kfile; > int ret; > > dmabuf = file->private_data; > @@ -504,6 +505,13 @@ static long dma_buf_ioctl(struct file *file, > return dma_buf_import_sync_file(dmabuf, (const void __user > *)arg); > #endif > > + case DMA_BUF_IOCTL_RW_FILE: > + if (copy_from_user(&kfile, (void __user *) arg, sizeof(kfile))) > + return -EFAULT; > + if (!dmabuf->ops->rw_file) > + return -EINVAL; > + return dmabuf->ops->rw_file(dmabuf, &kfile); > + > default: > return -ENOTTY; > } > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > index 36216d28d8bd..de236ba2094b 100644 > --- a/include/linux/dma-buf.h > +++ b/include/linux/dma-buf.h > @@ -22,6 +22,7 @@ > #include <linux/fs.h> > #include <linux/dma-fence.h> > #include <linux/wait.h> > +#include <uapi/linux/dma-buf.h> > > struct device; > struct dma_buf; > @@ -285,6 +286,8 @@ struct dma_buf_ops { > > int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); > void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); > + > + int (*rw_file)(struct dma_buf *dmabuf, struct dma_buf_rw_file *file); > }; > > /** > diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h > index 5a6fda66d9ad..ec9164b7b753 100644 > --- a/include/uapi/linux/dma-buf.h > +++ b/include/uapi/linux/dma-buf.h > @@ -167,6 +167,29 @@ struct dma_buf_import_sync_file { > __s32 fd; > }; > > +/** > + * struct dma_buf_rw_file - read/write file associated with a dma-buf > + * > + * Userspace can performs a DMA_BUF_IOCTL_BACK to save data from a dma-buf or > + * restore data to a dma-buf. > + */ > +struct dma_buf_rw_file { > + > + /** @flags: Flags indicating read/write for this dma-buf. */ > + __u32 flags; > + /** @fd: File descriptor of the file associated with this dma-buf. */ > + __s32 fd; > + /** @file_offset: Offset within the file where this dma-buf starts. > + * > + * Offset and Length must be page-aligned for direct I/O. > + */ > + __u64 file_offset; > + /** @buf_offset: Offset within this dma-buf where the read/write > starts. */ > + __u64 buf_offset; > + /** @buf_len: Length of this dma-buf read/write. */ > + __u64 buf_len; > +}; > + > #define DMA_BUF_BASE 'b' > #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) > > @@ -179,4 +202,10 @@ struct dma_buf_import_sync_file { > #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_RW_FLAGS_OP_MASK (0xFF << 0) > +#define DMA_BUF_RW_FLAGS_READ (1 << 0) /* Restore dma-buf data */ > +#define DMA_BUF_RW_FLAGS_WRITE (2 << 0) /* Save dma-buf data */ > +#define DMA_BUF_RW_FLAGS_DIRECT (1u << 31) /* Direct read/write file */ > +#define DMA_BUF_IOCTL_RW_FILE _IOW(DMA_BUF_BASE, 4, struct > dma_buf_rw_file) > + > #endif