aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKieran Bingham <[email protected]>2017-01-06 10:15:28 -0200
committerMauro Carvalho Chehab <[email protected]>2017-04-10 08:28:50 -0300
commit4461c84b52b4a952c657505ef7e4e06b016783df (patch)
treefdfd65bd7902b881b7ae1ef2fb7754ed3f771194
parent3425382288fbd13b60581f20076aebd0ef414282 (diff)
[media] v4l: vsp1: Prevent multiple streamon race commencing pipeline early
With multiple inputs through the BRU it is feasible for the streams to race each other at stream-on. Multiple VIDIOC_STREAMON calls racing each other could have process N-1 skipping over the pipeline setup section and then start the pipeline early, if videobuf2 has already enqueued buffers to the driver for process N but not called the .start_streaming() operation yet In the case of the video pipelines, this can present two serious issues. 1) A null-dereference if the pipe->dl is committed at the same time as the vsp1_video_setup_pipeline() is processing 2) A hardware hang, where a display list is committed without having called vsp1_video_setup_pipeline() first Repair this issue, by ensuring that only the stream which configures the pipeline is able to start it. Signed-off-by: Kieran Bingham <[email protected]> Reviewed-by: Laurent Pinchart <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 317fba485cd7..6c1b79f7aea5 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -797,6 +797,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct vsp1_video *video = vb2_get_drv_priv(vq);
struct vsp1_pipeline *pipe = video->rwpf->pipe;
+ bool start_pipeline = false;
unsigned long flags;
int ret;
@@ -807,11 +808,23 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
mutex_unlock(&pipe->lock);
return ret;
}
+
+ start_pipeline = true;
}
pipe->stream_count++;
mutex_unlock(&pipe->lock);
+ /*
+ * vsp1_pipeline_ready() is not sufficient to establish that all streams
+ * are prepared and the pipeline is configured, as multiple streams
+ * can race through streamon with buffers already queued; Therefore we
+ * don't even attempt to start the pipeline until the last stream has
+ * called through here.
+ */
+ if (!start_pipeline)
+ return 0;
+
spin_lock_irqsave(&pipe->irqlock, flags);
if (vsp1_pipeline_ready(pipe))
vsp1_video_pipeline_run(pipe);