media: mediatek: vcodec: adding lock to protect encoder context list
[ Upstream commit afaaf3a0f647a24a7bf6a2145d8ade37baaf75ad ]
Add a lock for the ctx_list, to avoid accessing a NULL pointer
within the 'vpu_enc_ipi_handler' function when the ctx_list has
been deleted due to an unexpected behavior on the SCP IP block.
Fixes: 1972e32431
("media: mediatek: vcodec: Fix possible invalid memory access for encoder")
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
0a2dc707aa
commit
41671f0c01
|
@ -65,12 +65,12 @@ static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
|
|||
|
||||
dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
|
||||
|
||||
mutex_lock(&dev->dev_mutex);
|
||||
mutex_lock(&dev->dev_ctx_lock);
|
||||
list_for_each_entry(ctx, &dev->ctx_list, list) {
|
||||
ctx->state = MTK_STATE_ABORT;
|
||||
mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
|
||||
}
|
||||
mutex_unlock(&dev->dev_mutex);
|
||||
mutex_unlock(&dev->dev_ctx_lock);
|
||||
}
|
||||
|
||||
static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
|
||||
|
|
|
@ -177,7 +177,9 @@ static int fops_vcodec_open(struct file *file)
|
|||
mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ",
|
||||
ctx->id, ctx, ctx->m2m_ctx);
|
||||
|
||||
mutex_lock(&dev->dev_ctx_lock);
|
||||
list_add(&ctx->list, &dev->ctx_list);
|
||||
mutex_unlock(&dev->dev_ctx_lock);
|
||||
|
||||
mutex_unlock(&dev->dev_mutex);
|
||||
mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
|
||||
|
@ -212,7 +214,9 @@ static int fops_vcodec_release(struct file *file)
|
|||
v4l2_fh_exit(&ctx->fh);
|
||||
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
|
||||
|
||||
mutex_lock(&dev->dev_ctx_lock);
|
||||
list_del_init(&ctx->list);
|
||||
mutex_unlock(&dev->dev_ctx_lock);
|
||||
kfree(ctx);
|
||||
mutex_unlock(&dev->dev_mutex);
|
||||
return 0;
|
||||
|
@ -294,6 +298,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
|
|||
|
||||
mutex_init(&dev->enc_mutex);
|
||||
mutex_init(&dev->dev_mutex);
|
||||
mutex_init(&dev->dev_ctx_lock);
|
||||
spin_lock_init(&dev->irqlock);
|
||||
|
||||
snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
|
||||
|
|
|
@ -178,6 +178,7 @@ struct mtk_vcodec_enc_ctx {
|
|||
*
|
||||
* @enc_mutex: encoder hardware lock.
|
||||
* @dev_mutex: video_device lock
|
||||
* @dev_ctx_lock: the lock of context list
|
||||
* @encode_workqueue: encode work queue
|
||||
*
|
||||
* @enc_irq: h264 encoder irq resource
|
||||
|
@ -205,6 +206,7 @@ struct mtk_vcodec_enc_dev {
|
|||
/* encoder hardware mutex lock */
|
||||
struct mutex enc_mutex;
|
||||
struct mutex dev_mutex;
|
||||
struct mutex dev_ctx_lock;
|
||||
struct workqueue_struct *encode_workqueue;
|
||||
|
||||
int enc_irq;
|
||||
|
|
|
@ -47,12 +47,14 @@ static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct ven
|
|||
struct mtk_vcodec_enc_ctx *ctx;
|
||||
int ret = false;
|
||||
|
||||
mutex_lock(&enc_dev->dev_ctx_lock);
|
||||
list_for_each_entry(ctx, &enc_dev->ctx_list, list) {
|
||||
if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&enc_dev->dev_ctx_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue