// SPDX-License-Identifier: GPL-2.0 #ifndef IOU_DMA_BUF_H #define IOU_DMA_BUF_H #include #include #include "rsrc.h" struct io_buf_dma { struct dma_buf_io_ctx *ctx; struct file *target_file; }; int __io_register_dmabuf(struct io_ring_ctx *ctx, struct io_uring_regbuf_desc *desc, struct io_mapped_ubuf *imu); static inline void io_detach_dmabuf_map(struct io_kiocb *req) { if (!IS_ENABLED(CONFIG_DMA_SHARED_BUFFER)) return; if (!(req->flags & REQ_F_DMABUF) || !req->dmabuf_map) return; dma_buf_io_map_drop(req->dmabuf_map); req->dmabuf_map = NULL; } static inline int io_attach_dmabuf_map(struct io_kiocb *req, struct iov_iter *iter, unsigned issue_flags) { bool nowait = issue_flags & IO_URING_F_NONBLOCK; struct dma_buf_io_map *map; struct io_buf_dma *bd; if (!(req->flags & REQ_F_DMABUF)) return 0; if (!IS_ENABLED(CONFIG_DMA_SHARED_BUFFER)) return -EOPNOTSUPP; bd = req->buf_node->buf->priv; map = dma_buf_io_get_map(bd->ctx, nowait); if (unlikely(IS_ERR(map))) return PTR_ERR(map); req->dmabuf_map = map; iter->dmabuf_map = map; return 0; } static inline int io_import_dmabuf_map(struct io_kiocb *req, int ddir, struct iov_iter *iter, struct io_mapped_ubuf *imu, size_t len, size_t offset) { struct io_buf_dma *bd = imu->priv; if (!IS_ENABLED(CONFIG_DMA_SHARED_BUFFER)) return -EOPNOTSUPP; if (req->file != bd->target_file) return -EBADF; req->flags |= REQ_F_DMABUF; iov_iter_dmabuf_map(iter, ddir, NULL, offset, len); return 0; } static inline int io_register_dmabuf(struct io_ring_ctx *ctx, struct io_uring_regbuf_desc *desc, struct io_mapped_ubuf *imu) { if (!IS_ENABLED(CONFIG_DMA_SHARED_BUFFER)) return -EOPNOTSUPP; return __io_register_dmabuf(ctx, desc, imu); } #endif /* IOU_DMA_BUF_H */