[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200225172437.106679-1-hsinyi@chromium.org>
Date: Wed, 26 Feb 2020 01:24:37 +0800
From: Hsin-Yi Wang <hsinyi@...omium.org>
To: linux-arm-kernel@...ts.infradead.org
Cc: Minghsiu Tsai <minghsiu.tsai@...iatek.com>,
Houlong Wei <houlong.wei@...iatek.com>,
Andrew-CT Chen <andrew-ct.chen@...iatek.com>,
Tiffany Lin <tiffany.lin@...iatek.com>,
Mauro Carvalho Chehab <mchehab+samsung@...nel.org>,
Matthias Brugger <matthias.bgg@...il.com>,
Enric Balletbo i Serra <enric.balletbo@...labora.com>,
Hans Verkuil <hverkuil-cisco@...all.nl>,
linux-media@...r.kernel.org, linux-mediatek@...ts.infradead.org,
linux-kernel@...r.kernel.org
Subject: [PATCH v3] media: mtk-vpu: avoid unaligned access to DTCM buffer.
struct vpu_run *run in vpu_init_ipi_handler() is an ioremapped DTCM (Data
Tightly Coupled Memory) buffer shared with AP. It's not able to do
unaligned access. Otherwise kernel would crash due to unable to handle
kernel paging request.
struct vpu_run {
u32 signaled;
char fw_ver[VPU_FW_VER_LEN];
unsigned int dec_capability;
unsigned int enc_capability;
wait_queue_head_t wq;
};
fw_ver starts at 4 byte boundary. If system enables
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, strscpy() will do
read_word_at_a_time(), which tries to read 8-byte: *(unsigned long *)addr
Copy the string by memcpy_fromio() for this buffer to avoid unaligned
access.
Fixes: 85709cbf1524 ("media: replace strncpy() by strscpy()")
Signed-off-by: Hsin-Yi Wang <hsinyi@...omium.org>
---
Change in v3:
- fix sparse warnings.
Change in v2:
- fix sparse warnings.
---
drivers/media/platform/mtk-vpu/mtk_vpu.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
index a768707abb94..e3fd2d1814f3 100644
--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
+++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
@@ -603,12 +603,14 @@ EXPORT_SYMBOL_GPL(vpu_load_firmware);
static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
{
struct mtk_vpu *vpu = (struct mtk_vpu *)priv;
- struct vpu_run *run = (struct vpu_run *)data;
-
- vpu->run.signaled = run->signaled;
- strscpy(vpu->run.fw_ver, run->fw_ver, sizeof(vpu->run.fw_ver));
- vpu->run.dec_capability = run->dec_capability;
- vpu->run.enc_capability = run->enc_capability;
+ struct vpu_run __iomem *run = (struct vpu_run __iomem __force *)data;
+
+ vpu->run.signaled = readl(&run->signaled);
+ memcpy_fromio(vpu->run.fw_ver, run->fw_ver, sizeof(vpu->run.fw_ver));
+ /* Make sure the string is NUL-terminated */
+ vpu->run.fw_ver[sizeof(vpu->run.fw_ver) - 1] = '\0';
+ vpu->run.dec_capability = readl(&run->dec_capability);
+ vpu->run.enc_capability = readl(&run->enc_capability);
wake_up_interruptible(&vpu->run.wq);
}
--
2.25.0.265.gbab2e86ba0-goog
Powered by blists - more mailing lists