Skip to content

Commit 717d283

Browse files
wenssmb49
authored andcommitted
media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
BugLink: https://bugs.launchpad.net/bugs/1989230 commit 8310ca9 upstream. DST_QUEUE_OFF_BASE is applied to offset/mem_offset on MMAP capture buffers only for the VIDIOC_QUERYBUF ioctl, while the userspace fields (including offset/mem_offset) are filled in for VIDIOC_{QUERY,PREPARE,Q,DQ}BUF ioctls. This leads to differences in the values presented to userspace. If userspace attempts to mmap the capture buffer directly using values from DQBUF, it will fail. Move the code that applies the magic offset into a helper, and call that helper from all four ioctl entry points. [hverkuil: drop unnecessary '= 0' in v4l2_m2m_querybuf() for ret] Fixes: 7f98639 ("V4L/DVB: add memory-to-memory device helper framework for videobuf") Fixes: 908a0d7 ("[media] v4l: mem2mem: port to videobuf2") Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org> [OP: backport to 5.4: adjusted return logic in v4l2_m2m_qbuf() to match the logic in the original commit: call v4l2_m2m_adjust_mem_offset() only if !ret and before the v4l2_m2m_try_schedule() call] Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent c17f064 commit 717d283

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

drivers/media/v4l2-core/v4l2-mem2mem.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -460,28 +460,38 @@ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
460460
}
461461
EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
462462

463-
int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
464-
struct v4l2_buffer *buf)
463+
static void v4l2_m2m_adjust_mem_offset(struct vb2_queue *vq,
464+
struct v4l2_buffer *buf)
465465
{
466-
struct vb2_queue *vq;
467-
int ret = 0;
468-
unsigned int i;
469-
470-
vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
471-
ret = vb2_querybuf(vq, buf);
472-
473466
/* Adjust MMAP memory offsets for the CAPTURE queue */
474467
if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) {
475468
if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) {
469+
unsigned int i;
470+
476471
for (i = 0; i < buf->length; ++i)
477472
buf->m.planes[i].m.mem_offset
478473
+= DST_QUEUE_OFF_BASE;
479474
} else {
480475
buf->m.offset += DST_QUEUE_OFF_BASE;
481476
}
482477
}
478+
}
483479

484-
return ret;
480+
int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
481+
struct v4l2_buffer *buf)
482+
{
483+
struct vb2_queue *vq;
484+
int ret;
485+
486+
vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
487+
ret = vb2_querybuf(vq, buf);
488+
if (ret)
489+
return ret;
490+
491+
/* Adjust MMAP memory offsets for the CAPTURE queue */
492+
v4l2_m2m_adjust_mem_offset(vq, buf);
493+
494+
return 0;
485495
}
486496
EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
487497

@@ -500,20 +510,34 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
500510
return -EPERM;
501511
}
502512
ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf);
503-
if (!ret && !(buf->flags & V4L2_BUF_FLAG_IN_REQUEST))
513+
if (ret)
514+
return ret;
515+
516+
/* Adjust MMAP memory offsets for the CAPTURE queue */
517+
v4l2_m2m_adjust_mem_offset(vq, buf);
518+
519+
if (!(buf->flags & V4L2_BUF_FLAG_IN_REQUEST))
504520
v4l2_m2m_try_schedule(m2m_ctx);
505521

506-
return ret;
522+
return 0;
507523
}
508524
EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);
509525

510526
int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
511527
struct v4l2_buffer *buf)
512528
{
513529
struct vb2_queue *vq;
530+
int ret;
514531

515532
vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
516-
return vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK);
533+
ret = vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK);
534+
if (ret)
535+
return ret;
536+
537+
/* Adjust MMAP memory offsets for the CAPTURE queue */
538+
v4l2_m2m_adjust_mem_offset(vq, buf);
539+
540+
return 0;
517541
}
518542
EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
519543

@@ -522,9 +546,17 @@ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
522546
{
523547
struct video_device *vdev = video_devdata(file);
524548
struct vb2_queue *vq;
549+
int ret;
525550

526551
vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
527-
return vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf);
552+
ret = vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf);
553+
if (ret)
554+
return ret;
555+
556+
/* Adjust MMAP memory offsets for the CAPTURE queue */
557+
v4l2_m2m_adjust_mem_offset(vq, buf);
558+
559+
return 0;
528560
}
529561
EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf);
530562

0 commit comments

Comments
 (0)