summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZiyi Guo <n7l8m4@u.northwestern.edu>2026-02-01 01:03:23 +0300
committerHans Verkuil <hverkuil+cisco@kernel.org>2026-03-23 13:18:33 +0300
commitf48050436746be75227fbc90066a8658cbe94d17 (patch)
tree8455d471aadd120f9297a6b09dad5df03ee029aa
parent95bd174a453f77b09ea66e1e22834680754ba501 (diff)
downloadlinux-f48050436746be75227fbc90066a8658cbe94d17.tar.xz
media: chips-media: wave5: add missing spinlock protection for send_eos_event()
Add spin_lock_irqsave()/spin_unlock_irqrestore() around send_eos_event() calls in the VB2 buffer queue and streamoff callbacks to fix the missing lock protection. wave5_vpu_dec_buf_queue_dst() and streamoff_output() call send_eos_event() without holding inst->state_spinlock. However, send_eos_event() has lockdep_assert_held(&inst->state_spinlock) indicating that callers must hold this lock. Other callers of send_eos_event() properly acquire the spinlock: - wave5_vpu_dec_finish_decode() acquires lock at line 431 - wave5_vpu_dec_encoder_cmd() acquires lock at line 821 - wave5_vpu_dec_device_run() acquires lock at line 1592 Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Fixes: 9707a6254a8a6b ("media: chips-media: wave5: Add the v4l2 layer") Cc: stable@vger.kernel.org Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index 80e1831a42e0..18cd1a6a7e1d 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -1303,13 +1303,17 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
if (vb2_is_streaming(vb->vb2_queue) && v4l2_m2m_dst_buf_is_last(m2m_ctx)) {
unsigned int i;
+ unsigned long flags;
for (i = 0; i < vb->num_planes; i++)
vb2_set_plane_payload(vb, i, 0);
vbuf->field = V4L2_FIELD_NONE;
+ spin_lock_irqsave(&inst->state_spinlock, flags);
send_eos_event(inst);
+ spin_unlock_irqrestore(&inst->state_spinlock, flags);
+
v4l2_m2m_last_buffer_done(m2m_ctx, vbuf);
} else {
v4l2_m2m_buf_queue(m2m_ctx, vbuf);
@@ -1462,8 +1466,13 @@ static int streamoff_output(struct vb2_queue *q)
inst->codec_info->dec_info.stream_rd_ptr = new_rd_ptr;
inst->codec_info->dec_info.stream_wr_ptr = new_rd_ptr;
- if (v4l2_m2m_has_stopped(m2m_ctx))
+ if (v4l2_m2m_has_stopped(m2m_ctx)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&inst->state_spinlock, flags);
send_eos_event(inst);
+ spin_unlock_irqrestore(&inst->state_spinlock, flags);
+ }
/* streamoff on output cancels any draining operation */
inst->eos = false;