mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 08:01:12 +02:00
media: verisilicon: rockchip: guard VPU981 AV1 divisor and tile buffer
rockchip_vpu981_av1_dec_set_tile_info() divides context_update_tile_id by
tile_info->tile_cols and writes one descriptor per tile into the tile_info
DMA buffer, which holds AV1_MAX_TILES entries; tile_cols and tile_rows
come from the bitstream. Guard the division against a zero tile_cols by
initialising the context-update values to zero and computing them only
when tile_cols is non-zero, and stop the descriptor writes once the
tile_info buffer is full. The tile geometry written to the hardware
registers is left unmodified; the per-dimension and total tile bounds are
enforced by the control validation.
Fixes: 727a400686 ("media: verisilicon: Add Rockchip AV1 decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
parent
06236b094c
commit
b84f6533a8
|
|
@ -578,16 +578,30 @@ static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx)
|
|||
const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info;
|
||||
const struct v4l2_ctrl_av1_tile_group_entry *group_entry =
|
||||
ctrls->tile_group_entry;
|
||||
int context_update_y =
|
||||
tile_info->context_update_tile_id / tile_info->tile_cols;
|
||||
int context_update_x =
|
||||
tile_info->context_update_tile_id % tile_info->tile_cols;
|
||||
int context_update_tile_id =
|
||||
context_update_x * tile_info->tile_rows + context_update_y;
|
||||
int context_update_y = 0;
|
||||
int context_update_x = 0;
|
||||
int context_update_tile_id = 0;
|
||||
u8 *dst = av1_dec->tile_info.cpu;
|
||||
u8 *dst_end = dst + av1_dec->tile_info.size;
|
||||
struct hantro_dev *vpu = ctx->dev;
|
||||
int tile0, tile1;
|
||||
|
||||
/*
|
||||
* tile_cols and tile_rows are bounded by the V4L2 control validation
|
||||
* (V4L2_AV1_MAX_TILE_{COLS,ROWS} and V4L2_AV1_MAX_TILE_COUNT). Guard
|
||||
* the divisor here, and keep the descriptor writes within the
|
||||
* AV1_MAX_TILES tile_info buffer below; the register values use the
|
||||
* unmodified tile geometry.
|
||||
*/
|
||||
if (tile_info->tile_cols) {
|
||||
context_update_y =
|
||||
tile_info->context_update_tile_id / tile_info->tile_cols;
|
||||
context_update_x =
|
||||
tile_info->context_update_tile_id % tile_info->tile_cols;
|
||||
context_update_tile_id =
|
||||
context_update_x * tile_info->tile_rows + context_update_y;
|
||||
}
|
||||
|
||||
memset(dst, 0, av1_dec->tile_info.size);
|
||||
|
||||
for (tile0 = 0; tile0 < tile_info->tile_cols; tile0++) {
|
||||
|
|
@ -598,6 +612,10 @@ static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx)
|
|||
tile_info->height_in_sbs_minus_1[tile1] + 1;
|
||||
u32 x0 = tile_info->width_in_sbs_minus_1[tile0] + 1;
|
||||
|
||||
/* Stop once the tile_info descriptor buffer is full. */
|
||||
if (dst + 16 > dst_end)
|
||||
break;
|
||||
|
||||
/* tile size in SB units (width,height) */
|
||||
*dst++ = x0;
|
||||
*dst++ = 0;
|
||||
|
|
@ -622,6 +640,8 @@ static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx)
|
|||
*dst++ = (end >> 16) & 255;
|
||||
*dst++ = (end >> 24) & 255;
|
||||
}
|
||||
if (dst + 16 > dst_end)
|
||||
break;
|
||||
}
|
||||
|
||||
hantro_reg_write(vpu, &av1_multicore_expect_context_update, !!(context_update_x == 0));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user