media: verisilicon: rockchip: Fix leaks in init

If one of the dma_alloc_coherent in the init function fails then
the previously allocated ones leak.

Fix by freeing them in the error path.

Fixes: 727a400686 ("media: verisilicon: Add Rockchip AV1 decoder")
Cc: stable@vger.kernel.org
Signed-off-by: Michail Tatas <michail.tatas@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
Michail Tatas 2026-08-19 12:28:12 +03:00 committed by Hans Verkuil
parent 7c7f31405b
commit 96f6b5e229

View File

@ -369,6 +369,7 @@ void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx)
int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
{
int ret = 0;
struct hantro_dev *vpu = ctx->dev;
struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
@ -377,39 +378,54 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, GLOBAL_MODEL_SIZE,
&av1_dec->global_model.dma,
GFP_KERNEL);
if (!av1_dec->global_model.cpu)
return -ENOMEM;
if (!av1_dec->global_model.cpu) {
ret = -ENOMEM;
goto global_model_cpu_err;
}
av1_dec->global_model.size = GLOBAL_MODEL_SIZE;
av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, AV1_TILE_INFO_SIZE,
&av1_dec->tile_info.dma,
GFP_KERNEL);
if (!av1_dec->tile_info.cpu)
return -ENOMEM;
if (!av1_dec->tile_info.cpu) {
ret = -ENOMEM;
goto tile_info_cpu_err;
}
av1_dec->tile_info.size = AV1_TILE_INFO_SIZE;
av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev,
ALIGN(sizeof(struct rockchip_av1_film_grain), 2048),
&av1_dec->film_grain.dma,
GFP_KERNEL);
if (!av1_dec->film_grain.cpu)
return -ENOMEM;
if (!av1_dec->film_grain.cpu) {
ret = -ENOMEM;
goto film_grain_cpu_err;
}
av1_dec->film_grain.size = ALIGN(sizeof(struct rockchip_av1_film_grain), 2048);
av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev,
ALIGN(sizeof(struct av1cdfs), 2048),
&av1_dec->prob_tbl.dma,
GFP_KERNEL);
if (!av1_dec->prob_tbl.cpu)
return -ENOMEM;
if (!av1_dec->prob_tbl.cpu) {
ret = -ENOMEM;
goto prob_tbl_cpu_err;
}
av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048);
av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev,
ALIGN(sizeof(struct av1cdfs), 2048),
&av1_dec->prob_tbl_out.dma,
GFP_KERNEL);
if (!av1_dec->prob_tbl_out.cpu)
return -ENOMEM;
if (!av1_dec->prob_tbl_out.cpu) {
ret = -ENOMEM;
goto prob_tbl_out_cpu_err;
}
av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048);
av1_dec->cdfs = &av1_dec->default_cdfs;
av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
@ -420,11 +436,37 @@ int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
AV1_TILE_SIZE,
&av1_dec->tile_buf.dma,
GFP_KERNEL);
if (!av1_dec->tile_buf.cpu)
return -ENOMEM;
if (!av1_dec->tile_buf.cpu) {
ret = -ENOMEM;
goto tile_buf_cpu_err;
}
av1_dec->tile_buf.size = AV1_TILE_SIZE;
return 0;
return ret;
tile_buf_cpu_err:
dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size,
av1_dec->prob_tbl_out.cpu,
av1_dec->prob_tbl_out.dma);
prob_tbl_out_cpu_err:
dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size,
av1_dec->prob_tbl.cpu,
av1_dec->prob_tbl.dma);
prob_tbl_cpu_err:
dma_free_coherent(vpu->dev, av1_dec->film_grain.size,
av1_dec->film_grain.cpu,
av1_dec->film_grain.dma);
film_grain_cpu_err:
dma_free_coherent(vpu->dev, av1_dec->tile_info.size,
av1_dec->tile_info.cpu,
av1_dec->tile_info.dma);
tile_info_cpu_err:
dma_free_coherent(vpu->dev, av1_dec->global_model.size,
av1_dec->global_model.cpu,
av1_dec->global_model.dma);
global_model_cpu_err:
return ret;
}
static int rockchip_vpu981_av1_dec_prepare_run(struct hantro_ctx *ctx)