diff mbox

[PATCHv9,22/25] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

Message ID 1349188056-4886-23-git-send-email-t.stanislaws@samsung.com
State New
Headers show

Commit Message

Tomasz Stanislawski Oct. 2, 2012, 2:27 p.m. UTC
From: Marek Szyprowski <m.szyprowski@samsung.com>

The DMA transfer must be aligned to a specific value. If userptr is not aligned
to DMA requirements then unexpected corruptions of the memory may occur before
or after a buffer.  To prevent such situations, all unligned userptr buffers
are rejected at VIDIOC_QBUF.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/media/video/videobuf2-dma-contig.c |    7 +++++++
 1 file changed, 7 insertions(+)

Comments

Laurent Pinchart Oct. 7, 2012, 1:38 p.m. UTC | #1
Hi Tomasz,

Thanks for the patch.

On Tuesday 02 October 2012 16:27:33 Tomasz Stanislawski wrote:
> From: Marek Szyprowski <m.szyprowski@samsung.com>
> 
> The DMA transfer must be aligned to a specific value. If userptr is not
> aligned to DMA requirements then unexpected corruptions of the memory may
> occur before or after a buffer.  To prevent such situations, all unligned
> userptr buffers are rejected at VIDIOC_QBUF.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/media/video/videobuf2-dma-contig.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/media/video/videobuf2-dma-contig.c
> b/drivers/media/video/videobuf2-dma-contig.c index b4d287a..55f8c80 100644
> --- a/drivers/media/video/videobuf2-dma-contig.c
> +++ b/drivers/media/video/videobuf2-dma-contig.c
> @@ -494,6 +494,13 @@ static void *vb2_dc_get_userptr(void *alloc_ctx,
> unsigned long vaddr, struct vm_area_struct *vma;
>  	struct sg_table *sgt;
>  	unsigned long contig_size;
> +	unsigned long dma_align = dma_get_cache_alignment();
> +
> +	/* Only cache aligned DMA transfers are reliable */
> +	if (!IS_ALIGNED(vaddr | size, dma_align)) {
> +		pr_err("user data must be aligned to %lu bytes\n", dma_align);
> +		return ERR_PTR(-EINVAL);

Do you think EFAULT would be more descriptive ? EINVAL is already used quite 
extensively. We could then possibly turn pr_err() into pr_dbg() to avoid 
flooding the kernel log.

> +	}
> 
>  	buf = kzalloc(sizeof *buf, GFP_KERNEL);
>  	if (!buf)
diff mbox

Patch

diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
index b4d287a..55f8c80 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -494,6 +494,13 @@  static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
 	struct vm_area_struct *vma;
 	struct sg_table *sgt;
 	unsigned long contig_size;
+	unsigned long dma_align = dma_get_cache_alignment();
+
+	/* Only cache aligned DMA transfers are reliable */
+	if (!IS_ALIGNED(vaddr | size, dma_align)) {
+		pr_err("user data must be aligned to %lu bytes\n", dma_align);
+		return ERR_PTR(-EINVAL);
+	}
 
 	buf = kzalloc(sizeof *buf, GFP_KERNEL);
 	if (!buf)