From 1b4af3728a3b94d7f46957d8bcb1fca979660c56 Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Wed, 18 Apr 2018 22:24:20 +0900 Subject: [PATCH] dma-buf: add buffer mask to dma-buf container Mask of dma-buf container is a bit-mask of buffers in the dma-buf container. The bit order in the mask is the position of buffers in the dma-buf container. LSB of the mask is the bit-mask of the buffer 0 in the dma-buf container. The mask of a dma-buf container is zero on creation. This means that all buffers in the dma-buf container are unmasked initially. Users of dma-buf container can modify the mask of buffers later with the following API functions/ioctl of dma-buf. - dmabuf_container_set_mask() - dmabuf_container_get_mask() - DMA_BUF_IOCTL_CONTAINER_SET_MASK - DMA_BUF_IOCTL_CONTAINER_GET_MASK The mask of dma-buf container is not used by dma-buf container itself. How to use the mask is entirely rely on the users. Users can configure the activation information of buffers of a dma-buf container. Others may use the mask to indicate buffers with special information. Change-Id: I2cc7d68812c060ed4fabb50da89271d52ad01ddc Signed-off-by: Cho KyongHo --- drivers/dma-buf/dma-buf-container.c | 68 +++++++++++++++++++++++++++++ drivers/dma-buf/dma-buf-container.h | 13 ++++++ drivers/dma-buf/dma-buf.c | 4 ++ include/linux/dma-buf-container.h | 12 +++++ include/uapi/linux/dma-buf.h | 2 + 5 files changed, 99 insertions(+) diff --git a/drivers/dma-buf/dma-buf-container.c b/drivers/dma-buf/dma-buf-container.c index f76500240739..ec5ef43ec277 100644 --- a/drivers/dma-buf/dma-buf-container.c +++ b/drivers/dma-buf/dma-buf-container.c @@ -108,11 +108,14 @@ static int dmabuf_container_put_user_data(unsigned int cmd, void __user *arg, * struct dma_buf_container - container description * @table: dummy sg_table for container * @count: the number of the buffers + * @dmabuf_mask: bit-mask of dma-bufs in @dmabufs. + * @dmabuf_mask is 0(unmasked) on creation of a dma-buf container. * @dmabufs: dmabuf array representing each buffers */ struct dma_buf_container { struct sg_table table; int count; + u32 dmabuf_mask; struct dma_buf *dmabufs[0]; }; @@ -313,6 +316,71 @@ long dma_buf_merge_ioctl(struct dma_buf *dmabuf, return 0; } +int dmabuf_container_set_mask_user(struct dma_buf *dmabuf, unsigned long arg) +{ + u32 mask; + + if (get_user(mask, (u32 __user *)arg)) { + pr_err("%s: failed to read mask from user\n", __func__); + return -EFAULT; + } + + return dmabuf_container_set_mask(dmabuf, mask); +} + +int dmabuf_container_get_mask_user(struct dma_buf *dmabuf, unsigned long arg) +{ + u32 mask; + int ret; + + ret = dmabuf_container_get_mask(dmabuf, &mask); + if (ret < 0) + return ret; + + if (put_user(mask, (u32 __user *)arg)) { + pr_err("%s: failed to write mask to user\n", __func__); + return -EFAULT; + } + + return 0; +} + +int dmabuf_container_set_mask(struct dma_buf *dmabuf, u32 mask) +{ + struct dma_buf_container *container; + + if (!is_dmabuf_container(dmabuf)) { + pr_err("%s: given dmabuf is not dma-buf container\n", __func__); + return -EINVAL; + } + + container = get_container(dmabuf); + + if (mask & ~((1 << container->count) - 1)) { + pr_err("%s: invalid mask %#x for %u buffers\n", + __func__, mask, container->count); + return -EINVAL; + } + + get_container(dmabuf)->dmabuf_mask = mask; + + return 0; +} +EXPORT_SYMBOL_GPL(dmabuf_container_set_mask); + +int dmabuf_container_get_mask(struct dma_buf *dmabuf, u32 *mask) +{ + if (!is_dmabuf_container(dmabuf)) { + pr_err("%s: given dmabuf is not dma-buf container\n", __func__); + return -EINVAL; + } + + *mask = get_container(dmabuf)->dmabuf_mask; + + return 0; +} +EXPORT_SYMBOL_GPL(dmabuf_container_get_mask); + int dmabuf_container_get_count(struct dma_buf *dmabuf) { if (!is_dmabuf_container(dmabuf)) diff --git a/drivers/dma-buf/dma-buf-container.h b/drivers/dma-buf/dma-buf-container.h index efd05d6b9f67..e53143374e02 100644 --- a/drivers/dma-buf/dma-buf-container.h +++ b/drivers/dma-buf/dma-buf-container.h @@ -42,6 +42,8 @@ struct dma_buf; long dma_buf_merge_ioctl(struct dma_buf *dmabuf, unsigned int cmd, unsigned long arg); +int dmabuf_container_set_mask_user(struct dma_buf *dmabuf, unsigned long arg); +int dmabuf_container_get_mask_user(struct dma_buf *dmabuf, unsigned long arg); #else static inline long dma_buf_merge_ioctl(struct dma_buf *dmabuf, @@ -49,6 +51,17 @@ static inline long dma_buf_merge_ioctl(struct dma_buf *dmabuf, { return -ENOTTY; } + +static inline int dmabuf_container_set_mask_user(struct dma_buf *dmabuf, + unsigned long arg) +{ + return -ENOTTY; +} +static inline int dmabuf_container_get_mask_user(struct dma_buf *dmabuf, + unsigned long arg) +{ + return -ENOTTY; +} #endif #endif /* _DMA_BUF_CONTAINER_H_ */ diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index cbda07b9570e..f6fab49d2c10 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -321,6 +321,10 @@ static long dma_buf_ioctl(struct file *file, #endif case DMA_BUF_IOCTL_MERGE: return dma_buf_merge_ioctl(dmabuf, cmd, arg); + case DMA_BUF_IOCTL_CONTAINER_SET_MASK: + return dmabuf_container_set_mask_user(dmabuf, arg); + case DMA_BUF_IOCTL_CONTAINER_GET_MASK: + return dmabuf_container_get_mask_user(dmabuf, arg); default: return -ENOTTY; } diff --git a/include/linux/dma-buf-container.h b/include/linux/dma-buf-container.h index f0d47299e58d..f646fc9201f0 100644 --- a/include/linux/dma-buf-container.h +++ b/include/linux/dma-buf-container.h @@ -6,6 +6,8 @@ int dmabuf_container_get_count(struct dma_buf *dmabuf); struct dma_buf *dmabuf_container_get_buffer(struct dma_buf *dmabuf, int index); +int dmabuf_container_set_mask(struct dma_buf *dmabuf, u32 mask); +int dmabuf_container_get_mask(struct dma_buf *dmabuf, u32 *mask); #else @@ -20,6 +22,16 @@ static inline struct dma_buf *dmabuf_container_get_buffer(struct dma_buf *dbuf, return NULL; } +static inline int dmabuf_container_set_mask(struct dma_buf *dmabuf, u32 mask) +{ + return -EINVAL; +} + +static inline int dmabuf_container_get_mask(struct dma_buf *dmabuf, u32 *mask) +{ + return -EINVAL; +} + #endif #endif /* _LINUX_DMA_BUF_CONTAINER_H_ */ diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h index d7dd380d483d..489f54c4b8d4 100644 --- a/include/uapi/linux/dma-buf.h +++ b/include/uapi/linux/dma-buf.h @@ -51,5 +51,7 @@ struct dma_buf_merge { __u32 reserved[2]; }; #define DMA_BUF_IOCTL_MERGE _IOWR(DMA_BUF_BASE, 13, struct dma_buf_merge) +#define DMA_BUF_IOCTL_CONTAINER_SET_MASK _IOW(DMA_BUF_BASE, 14, __u32) +#define DMA_BUF_IOCTL_CONTAINER_GET_MASK _IOR(DMA_BUF_BASE, 14, __u32) #endif -- 2.20.1