From 09d2f2a880af40e1deb60d22d84095b450614453 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 8 Aug 2022 15:34:45 +0200 Subject: [PATCH] 5.4-stable patches added patches: media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch --- ...f_base-on-mmap-buffers-across-ioctls.patch | 143 ++++++++++++++++++ queue-5.4/series | 1 + 2 files changed, 144 insertions(+) create mode 100644 queue-5.4/media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch diff --git a/queue-5.4/media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch b/queue-5.4/media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch new file mode 100644 index 00000000000..7aec7a1844f --- /dev/null +++ b/queue-5.4/media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch @@ -0,0 +1,143 @@ +From 8310ca94075e784bbb06593cd6c068ee6b6e4ca6 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 9 Dec 2021 17:38:03 +0100 +Subject: media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls + +From: Chen-Yu Tsai + +commit 8310ca94075e784bbb06593cd6c068ee6b6e4ca6 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: 7f98639def42 ("V4L/DVB: add memory-to-memory device helper framework for videobuf") +Fixes: 908a0d7c588e ("[media] v4l: mem2mem: port to videobuf2") +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +[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 +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/v4l2-core/v4l2-mem2mem.c | 60 +++++++++++++++++++++++++-------- + 1 file changed, 46 insertions(+), 14 deletions(-) + +--- a/drivers/media/v4l2-core/v4l2-mem2mem.c ++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c +@@ -460,19 +460,14 @@ int v4l2_m2m_reqbufs(struct file *file, + } + EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs); + +-int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, +- struct v4l2_buffer *buf) ++static void v4l2_m2m_adjust_mem_offset(struct vb2_queue *vq, ++ struct v4l2_buffer *buf) + { +- struct vb2_queue *vq; +- int ret = 0; +- unsigned int i; +- +- vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); +- ret = vb2_querybuf(vq, buf); +- + /* Adjust MMAP memory offsets for the CAPTURE queue */ + if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) { + if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) { ++ unsigned int i; ++ + for (i = 0; i < buf->length; ++i) + buf->m.planes[i].m.mem_offset + += DST_QUEUE_OFF_BASE; +@@ -480,8 +475,23 @@ int v4l2_m2m_querybuf(struct file *file, + buf->m.offset += DST_QUEUE_OFF_BASE; + } + } ++} ++ ++int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, ++ struct v4l2_buffer *buf) ++{ ++ struct vb2_queue *vq; ++ int ret; + +- return ret; ++ vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); ++ ret = vb2_querybuf(vq, buf); ++ if (ret) ++ return ret; ++ ++ /* Adjust MMAP memory offsets for the CAPTURE queue */ ++ v4l2_m2m_adjust_mem_offset(vq, buf); ++ ++ return 0; + } + EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf); + +@@ -500,10 +510,16 @@ int v4l2_m2m_qbuf(struct file *file, str + return -EPERM; + } + ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf); +- if (!ret && !(buf->flags & V4L2_BUF_FLAG_IN_REQUEST)) ++ if (ret) ++ return ret; ++ ++ /* Adjust MMAP memory offsets for the CAPTURE queue */ ++ v4l2_m2m_adjust_mem_offset(vq, buf); ++ ++ if (!(buf->flags & V4L2_BUF_FLAG_IN_REQUEST)) + v4l2_m2m_try_schedule(m2m_ctx); + +- return ret; ++ return 0; + } + EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf); + +@@ -511,9 +527,17 @@ int v4l2_m2m_dqbuf(struct file *file, st + struct v4l2_buffer *buf) + { + struct vb2_queue *vq; ++ int ret; + + vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); +- return vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK); ++ ret = vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK); ++ if (ret) ++ return ret; ++ ++ /* Adjust MMAP memory offsets for the CAPTURE queue */ ++ v4l2_m2m_adjust_mem_offset(vq, buf); ++ ++ return 0; + } + EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); + +@@ -522,9 +546,17 @@ int v4l2_m2m_prepare_buf(struct file *fi + { + struct video_device *vdev = video_devdata(file); + struct vb2_queue *vq; ++ int ret; + + vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); +- return vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf); ++ ret = vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf); ++ if (ret) ++ return ret; ++ ++ /* Adjust MMAP memory offsets for the CAPTURE queue */ ++ v4l2_m2m_adjust_mem_offset(vq, buf); ++ ++ return 0; + } + EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf); + diff --git a/queue-5.4/series b/queue-5.4/series index f6b34e3622e..6066f472279 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -9,3 +9,4 @@ selftests-bpf-fix-test_align-verifier-log-patterns.patch selftests-bpf-fix-dubious-pointer-arithmetic-test.patch kvm-don-t-null-dereference-ops-destroy.patch selftests-kvm-handle-compiler-optimizations-in-ucall.patch +media-v4l2-mem2mem-apply-dst_queue_off_base-on-mmap-buffers-across-ioctls.patch -- 2.47.3