summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Tretter <m.tretter@pengutronix.de>2019-12-04 12:32:27 +0100
committerMichael Tretter <m.tretter@pengutronix.de>2020-03-03 17:48:15 +0100
commit7812783685c7776c4cd9c9c4b795c4d4291ff11a (patch)
tree76ebba80bb142a88d9610378258e076fb62c5ed5
parentb3b66f30f6c4a22d6133fd73d0db509acabe42c1 (diff)
downloadlinux-0-day-7812783685c7776c4cd9c9c4b795c4d4291ff11a.tar.gz
linux-0-day-7812783685c7776c4cd9c9c4b795c4d4291ff11a.tar.xz
media: allegro: verify source and destination buffer in VCU response
The PUT_STREAM_BUFFER and ENCODE_FRAME request have fields that allow to pass arbitrary 64 bit values through the firmware to the ENCODE_FRAME response. Use these values to verify that the buffers when finishing the frame are actually the same buffers that have been sent for encoding a frame. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- Changelog: v1 -> v2: - Fix warnings about lines over 80 characters - Fix warnings about cast from ptr to u64
-rw-r--r--drivers/staging/media/allegro-dvt/allegro-core.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c b/drivers/staging/media/allegro-dvt/allegro-core.c
index d994a53e73cf5..d2b999159a2da 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -565,6 +565,11 @@ static inline u32 to_codec_addr(struct allegro_dev *dev, dma_addr_t phys)
return lower_32_bits(phys);
}
+static inline u64 ptr_to_u64(const void *ptr)
+{
+ return (uintptr_t)ptr;
+}
+
/* Helper functions for channel and user operations */
static unsigned long allegro_next_user_id(struct allegro_dev *dev)
@@ -1213,7 +1218,8 @@ static int allegro_mcu_send_destroy_channel(struct allegro_dev *dev,
static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
struct allegro_channel *channel,
dma_addr_t paddr,
- unsigned long size)
+ unsigned long size,
+ u64 stream_id)
{
struct mcu_msg_put_stream_buffer msg;
@@ -1227,7 +1233,8 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
msg.mcu_addr = to_mcu_addr(dev, paddr);
msg.size = size;
msg.offset = ENCODER_STREAM_OFFSET;
- msg.stream_id = 0; /* copied to mcu_msg_encode_frame_response */
+ /* copied to mcu_msg_encode_frame_response */
+ msg.stream_id = stream_id;
allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));
allegro_mcu_interrupt(dev);
@@ -1237,7 +1244,8 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,
struct allegro_channel *channel,
- dma_addr_t src_y, dma_addr_t src_uv)
+ dma_addr_t src_y, dma_addr_t src_uv,
+ u64 src_handle)
{
struct mcu_msg_encode_frame msg;
@@ -1250,7 +1258,8 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,
msg.encoding_options = AL_OPT_FORCE_LOAD;
msg.pps_qp = 26; /* qp are relative to 26 */
msg.user_param = 0; /* copied to mcu_msg_encode_frame_response */
- msg.src_handle = 0; /* copied to mcu_msg_encode_frame_response */
+ /* src_handle is copied to mcu_msg_encode_frame_response */
+ msg.src_handle = src_handle;
msg.src_y = to_codec_addr(dev, src_y);
msg.src_uv = to_codec_addr(dev, src_uv);
msg.stride = channel->stride;
@@ -1600,8 +1609,17 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel,
ssize_t free;
src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx);
+ if (ptr_to_u64(src_buf) != msg->src_handle)
+ v4l2_warn(&dev->v4l2_dev,
+ "channel %d: invalid source buffer (0x%llx)\n",
+ channel->mcu_channel_id, msg->src_handle);
dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
+ if (ptr_to_u64(dst_buf) != msg->stream_id)
+ v4l2_warn(&dev->v4l2_dev,
+ "channel %d: invalid stream buffer (0x%llx)\n",
+ channel->mcu_channel_id, msg->stream_id);
+
dst_buf->sequence = channel->csequence++;
if (msg->error_code & AL_ERROR) {
@@ -2998,14 +3016,16 @@ static void allegro_device_run(void *priv)
dst_buf = v4l2_m2m_next_dst_buf(channel->fh.m2m_ctx);
dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
dst_size = vb2_plane_size(&dst_buf->vb2_buf, 0);
- allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size);
+ allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size,
+ ptr_to_u64(dst_buf));
src_buf = v4l2_m2m_next_src_buf(channel->fh.m2m_ctx);
src_buf->sequence = channel->osequence++;
src_y = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
src_uv = src_y + (channel->stride * channel->height);
- allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv);
+ allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv,
+ ptr_to_u64(src_buf));
}
static const struct v4l2_m2m_ops allegro_m2m_ops = {