Commit ea3aba84 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab

[media] videobuf2: Add support for file access mode flags for DMABUF exporting

Currently it is not possible for userspace to map a DMABUF exported buffer
with write permissions. This patch allows to also pass O_RDONLY/O_RDWR when
exporting the buffer, so that userspace may map it with write permissions.
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent d8eec74a
...@@ -73,7 +73,8 @@ range from zero to the maximal number of valid planes for the currently active ...@@ -73,7 +73,8 @@ range from zero to the maximal number of valid planes for the currently active
format. For the single-planar API, applications must set <structfield> plane format. For the single-planar API, applications must set <structfield> plane
</structfield> to zero. Additional flags may be posted in the <structfield> </structfield> to zero. Additional flags may be posted in the <structfield>
flags </structfield> field. Refer to a manual for open() for details. flags </structfield> field. Refer to a manual for open() for details.
Currently only O_CLOEXEC is supported. All other fields must be set to zero. Currently only O_CLOEXEC, O_RDONLY, O_WRONLY, and O_RDWR are supported. All
other fields must be set to zero.
In the case of multi-planar API, every plane is exported separately using In the case of multi-planar API, every plane is exported separately using
multiple <constant> VIDIOC_EXPBUF </constant> calls. </para> multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
...@@ -170,8 +171,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry> ...@@ -170,8 +171,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry>
<entry>__u32</entry> <entry>__u32</entry>
<entry><structfield>flags</structfield></entry> <entry><structfield>flags</structfield></entry>
<entry>Flags for the newly created file, currently only <constant> <entry>Flags for the newly created file, currently only <constant>
O_CLOEXEC </constant> is supported, refer to the manual of open() for more O_CLOEXEC </constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY
details.</entry> </constant>, and <constant>O_RDWR</constant> are supported, refer to the manual
of open() for more details.</entry>
</row> </row>
<row> <row>
<entry>__s32</entry> <entry>__s32</entry>
......
...@@ -1824,8 +1824,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) ...@@ -1824,8 +1824,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
return -EINVAL; return -EINVAL;
} }
if (eb->flags & ~O_CLOEXEC) { if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) {
dprintk(1, "Queue does support only O_CLOEXEC flag\n"); dprintk(1, "Queue does support only O_CLOEXEC and access mode flags\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1848,14 +1848,14 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) ...@@ -1848,14 +1848,14 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
vb_plane = &vb->planes[eb->plane]; vb_plane = &vb->planes[eb->plane];
dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv); dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
if (IS_ERR_OR_NULL(dbuf)) { if (IS_ERR_OR_NULL(dbuf)) {
dprintk(1, "Failed to export buffer %d, plane %d\n", dprintk(1, "Failed to export buffer %d, plane %d\n",
eb->index, eb->plane); eb->index, eb->plane);
return -EINVAL; return -EINVAL;
} }
ret = dma_buf_fd(dbuf, eb->flags); ret = dma_buf_fd(dbuf, eb->flags & ~O_ACCMODE);
if (ret < 0) { if (ret < 0) {
dprintk(3, "buffer %d, plane %d failed to export (%d)\n", dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
eb->index, eb->plane, ret); eb->index, eb->plane, ret);
......
...@@ -393,7 +393,7 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf) ...@@ -393,7 +393,7 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
return sgt; return sgt;
} }
static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv) static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
{ {
struct vb2_dc_buf *buf = buf_priv; struct vb2_dc_buf *buf = buf_priv;
struct dma_buf *dbuf; struct dma_buf *dbuf;
...@@ -404,7 +404,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv) ...@@ -404,7 +404,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
if (WARN_ON(!buf->sgt_base)) if (WARN_ON(!buf->sgt_base))
return NULL; return NULL;
dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0); dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags);
if (IS_ERR(dbuf)) if (IS_ERR(dbuf))
return NULL; return NULL;
......
...@@ -83,7 +83,7 @@ struct vb2_fileio_data; ...@@ -83,7 +83,7 @@ struct vb2_fileio_data;
struct vb2_mem_ops { struct vb2_mem_ops {
void *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags); void *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags);
void (*put)(void *buf_priv); void (*put)(void *buf_priv);
struct dma_buf *(*get_dmabuf)(void *buf_priv); struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags);
void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr, void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write); unsigned long size, int write);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment