Skip to content

Commit d331f45

Browse files
naushirpelwell
authored andcommitted
media: bcm2835-unicam: Fix for possible dummy buffer overrun
The Unicam hardware has been observed to cause a buffer overrun when using the dummy buffer as a circular buffer. The conditions that cause the overrun are not fully known, but it seems to occur when the memory bus is heavily loaded. To avoid the overrun, program the hardware with a buffer size of 0 when using the dummy buffer. This will cause overrun into the allocated dummy buffer, but avoid out of bounds writes. Signed-off-by: Naushir Patuck <[email protected]>
1 parent f64b566 commit d331f45

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

drivers/media/platform/bcm2835/bcm2835-unicam.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,11 @@ MODULE_PARM_DESC(media_controller, "Use media controller API");
127127
#define UNICAM_EMBEDDED_SIZE 16384
128128

129129
/*
130-
* Size of the dummy buffer. Can be any size really, but the DMA
131-
* allocation works in units of page sizes.
130+
* Size of the dummy buffer allocation.
131+
*
132+
* Due to a HW bug causing buffer overruns in circular buffer mode under certain
133+
* (not yet fully known) conditions, the dummy buffer allocation is set to a
134+
* a single page size, but the hardware gets programmed with a buffer size of 0.
132135
*/
133136
#define DUMMY_BUF_SIZE (PAGE_SIZE)
134137

@@ -844,8 +847,7 @@ static void unicam_schedule_dummy_buffer(struct unicam_node *node)
844847
unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n",
845848
node->pad_id);
846849

847-
unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, DUMMY_BUF_SIZE,
848-
node->pad_id);
850+
unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, 0, node->pad_id);
849851
node->next_frm = NULL;
850852
}
851853

@@ -2665,8 +2667,8 @@ static void unicam_stop_streaming(struct vb2_queue *vq)
26652667
* This is only really needed if the embedded data pad is
26662668
* disabled before the image pad.
26672669
*/
2668-
unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr,
2669-
DUMMY_BUF_SIZE, METADATA_PAD);
2670+
unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, 0,
2671+
METADATA_PAD);
26702672
}
26712673

26722674
/* Clear all queued buffers for the node */

0 commit comments

Comments
 (0)