summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>2026-02-06 19:30:54 +0300
committerHans Verkuil <hverkuil+cisco@kernel.org>2026-03-24 18:13:09 +0300
commit72773ff1cdfaebc593f53b1719b2c1773ecf8c43 (patch)
tree51195a443df01ae777ce0bce4bf8d8fbbec60296
parent562d2e0a672075292e92538dad61664e89b34d30 (diff)
downloadlinux-72773ff1cdfaebc593f53b1719b2c1773ecf8c43.tar.xz
media: rzv2h-ivc: Fix concurrent buffer list access
The list of buffers (`rzv2h_ivc::buffers.queue`) is protected by a spinlock (`rzv2h_ivc::buffers.lock`). However, in `rzv2h_ivc_transfer_buffer()`, which runs in a separate workqueue, the `list_del()` call is executed without holding the spinlock, which makes it possible for the list to be concurrently modified Fix that by removing a buffer from the list in the lock protected section. Cc: stable@vger.kernel.org Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver") Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com> [assign ivc->buffers.curr in critical section as reported by Barnabas] Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
-rw-r--r--drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index 9b75e4b10e99..a22aee0fe1cf 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -153,14 +153,13 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
scoped_guard(spinlock_irqsave, &ivc->buffers.lock) {
buf = list_first_entry_or_null(&ivc->buffers.queue,
struct rzv2h_ivc_buf, queue);
- }
-
- if (!buf)
- return;
+ if (!buf)
+ return;
- list_del(&buf->queue);
+ list_del(&buf->queue);
+ ivc->buffers.curr = buf;
+ }
- ivc->buffers.curr = buf;
buf->addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_SADDL_P0, buf->addr);