]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.8/media-mediatek-vcodec-adding-lock-to-protect-encoder.patch
Linux 6.6.27
[thirdparty/kernel/stable-queue.git] / queue-6.8 / media-mediatek-vcodec-adding-lock-to-protect-encoder.patch
1 From d127d19b73d6164afd4a623b0bfd206794df273f Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Thu, 14 Mar 2024 20:30:09 +0800
4 Subject: media: mediatek: vcodec: adding lock to protect encoder context list
5
6 From: Yunfei Dong <yunfei.dong@mediatek.com>
7
8 [ Upstream commit afaaf3a0f647a24a7bf6a2145d8ade37baaf75ad ]
9
10 Add a lock for the ctx_list, to avoid accessing a NULL pointer
11 within the 'vpu_enc_ipi_handler' function when the ctx_list has
12 been deleted due to an unexpected behavior on the SCP IP block.
13
14 Fixes: 1972e32431ed ("media: mediatek: vcodec: Fix possible invalid memory access for encoder")
15 Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
16 Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
17 Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
18 Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
19 Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
20 Signed-off-by: Sasha Levin <sashal@kernel.org>
21 ---
22 .../platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c | 4 ++--
23 .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c | 5 +++++
24 .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h | 2 ++
25 drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c | 2 ++
26 4 files changed, 11 insertions(+), 2 deletions(-)
27
28 diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
29 index 62cafe25fed94..d7027d600208f 100644
30 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
31 +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
32 @@ -65,12 +65,12 @@ static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
33
34 dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
35
36 - mutex_lock(&dev->dev_mutex);
37 + mutex_lock(&dev->dev_ctx_lock);
38 list_for_each_entry(ctx, &dev->ctx_list, list) {
39 ctx->state = MTK_STATE_ABORT;
40 mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
41 }
42 - mutex_unlock(&dev->dev_mutex);
43 + mutex_unlock(&dev->dev_ctx_lock);
44 }
45
46 static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
47 diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
48 index 6319f24bc714b..3cb8a16222220 100644
49 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
50 +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
51 @@ -177,7 +177,9 @@ static int fops_vcodec_open(struct file *file)
52 mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ",
53 ctx->id, ctx, ctx->m2m_ctx);
54
55 + mutex_lock(&dev->dev_ctx_lock);
56 list_add(&ctx->list, &dev->ctx_list);
57 + mutex_unlock(&dev->dev_ctx_lock);
58
59 mutex_unlock(&dev->dev_mutex);
60 mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
61 @@ -212,7 +214,9 @@ static int fops_vcodec_release(struct file *file)
62 v4l2_fh_exit(&ctx->fh);
63 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
64
65 + mutex_lock(&dev->dev_ctx_lock);
66 list_del_init(&ctx->list);
67 + mutex_unlock(&dev->dev_ctx_lock);
68 kfree(ctx);
69 mutex_unlock(&dev->dev_mutex);
70 return 0;
71 @@ -294,6 +298,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
72
73 mutex_init(&dev->enc_mutex);
74 mutex_init(&dev->dev_mutex);
75 + mutex_init(&dev->dev_ctx_lock);
76 spin_lock_init(&dev->irqlock);
77
78 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
79 diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
80 index a042f607ed8d1..0bd85d0fb379a 100644
81 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
82 +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
83 @@ -178,6 +178,7 @@ struct mtk_vcodec_enc_ctx {
84 *
85 * @enc_mutex: encoder hardware lock.
86 * @dev_mutex: video_device lock
87 + * @dev_ctx_lock: the lock of context list
88 * @encode_workqueue: encode work queue
89 *
90 * @enc_irq: h264 encoder irq resource
91 @@ -205,6 +206,7 @@ struct mtk_vcodec_enc_dev {
92 /* encoder hardware mutex lock */
93 struct mutex enc_mutex;
94 struct mutex dev_mutex;
95 + struct mutex dev_ctx_lock;
96 struct workqueue_struct *encode_workqueue;
97
98 int enc_irq;
99 diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
100 index 84ad1cc6ad171..51bb7ee141b9e 100644
101 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
102 +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
103 @@ -47,12 +47,14 @@ static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct ven
104 struct mtk_vcodec_enc_ctx *ctx;
105 int ret = false;
106
107 + mutex_lock(&enc_dev->dev_ctx_lock);
108 list_for_each_entry(ctx, &enc_dev->ctx_list, list) {
109 if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
110 ret = true;
111 break;
112 }
113 }
114 + mutex_unlock(&enc_dev->dev_ctx_lock);
115
116 return ret;
117 }
118 --
119 2.43.0
120