* [PATCH v5 1/3] venus: core: handle race condititon for core ops
2020-09-24 6:59 [PATCH v5 0/3] venus: core: add shutdown callback for venus Mansur Alisha Shaik
@ 2020-09-24 6:59 ` Mansur Alisha Shaik
2020-09-24 6:59 ` [PATCH v5 2/3] venus: handle use after free for iommu_map/iommu_unmap Mansur Alisha Shaik
2020-09-24 6:59 ` [PATCH v5 3/3] venus: core: add shutdown callback for venus Mansur Alisha Shaik
2 siblings, 0 replies; 4+ messages in thread
From: Mansur Alisha Shaik @ 2020-09-24 6:59 UTC (permalink / raw)
To: linux-media, stanimir.varbanov
Cc: linux-kernel, linux-arm-msm, vgarodia, Mansur Alisha Shaik
For core ops we are having only write protect but there
is no read protect, because of this in multithreading
and concurrency, one CPU core is reading without wait
which is causing the NULL pointer dereferece crash.
one such scenario is as show below, where in one CPU
core, core->ops becoming NULL and in another CPU core
calling core->ops->session_init().
CPU: core-7:
Call trace:
hfi_session_init+0x180/0x1dc [venus_core]
vdec_queue_setup+0x9c/0x364 [venus_dec]
vb2_core_reqbufs+0x1e4/0x368 [videobuf2_common]
vb2_reqbufs+0x4c/0x64 [videobuf2_v4l2]
v4l2_m2m_reqbufs+0x50/0x84 [v4l2_mem2mem]
v4l2_m2m_ioctl_reqbufs+0x2c/0x38 [v4l2_mem2mem]
v4l_reqbufs+0x4c/0x5c
__video_do_ioctl+0x2b0/0x39c
CPU: core-0:
Call trace:
venus_shutdown+0x98/0xfc [venus_core]
venus_sys_error_handler+0x64/0x148 [venus_core]
process_one_work+0x210/0x3d0
worker_thread+0x248/0x3f4
kthread+0x11c/0x12c
Signed-off-by: Mansur Alisha Shaik <mansur@codeaurora.org>
Acked-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
Changes in v5:
- Addressed review comments by stan in v4 version
drivers/media/platform/qcom/venus/hfi.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
index a59022a..638ed5c 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -198,6 +198,18 @@ int hfi_session_init(struct venus_inst *inst, u32 pixfmt)
const struct hfi_ops *ops = core->ops;
int ret;
+ /*
+ * If core shutdown is in progress or if we are in system
+ * recovery, return an error as during system error recovery
+ * session_init() can't pass successfully
+ */
+ mutex_lock(&core->lock);
+ if (!core->ops || core->sys_error) {
+ mutex_unlock(&core->lock);
+ return -EIO;
+ }
+ mutex_unlock(&core->lock);
+
if (inst->state != INST_UNINIT)
return -EINVAL;
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v5 2/3] venus: handle use after free for iommu_map/iommu_unmap
2020-09-24 6:59 [PATCH v5 0/3] venus: core: add shutdown callback for venus Mansur Alisha Shaik
2020-09-24 6:59 ` [PATCH v5 1/3] venus: core: handle race condititon for core ops Mansur Alisha Shaik
@ 2020-09-24 6:59 ` Mansur Alisha Shaik
2020-09-24 6:59 ` [PATCH v5 3/3] venus: core: add shutdown callback for venus Mansur Alisha Shaik
2 siblings, 0 replies; 4+ messages in thread
From: Mansur Alisha Shaik @ 2020-09-24 6:59 UTC (permalink / raw)
To: linux-media, stanimir.varbanov
Cc: linux-kernel, linux-arm-msm, vgarodia, Mansur Alisha Shaik
In concurrency usecase and reboot scenario we are seeing muliple
crashes related to iommu_map/iommu_unamp of core->fw.iommu_domain.
In one case we are seeing "Unable to handle kernel NULL pointer
dereference at virtual address 0000000000000008" crash, this is
because of core->fw.iommu_domain in venus_firmware_deinit() and
trying to map in venus_boot() during venus_sys_error_handler()
Call trace:
__iommu_map+0x4c/0x348
iommu_map+0x5c/0x70
venus_boot+0x184/0x230 [venus_core]
venus_sys_error_handler+0xa0/0x14c [venus_core]
process_one_work+0x210/0x3d0
worker_thread+0x248/0x3f4
kthread+0x11c/0x12c
ret_from_fork+0x10/0x18
In second case we are seeing "Unable to handle kernel paging request
at virtual address 006b6b6b6b6b6b9b" crash, this is because of
unmapping iommu domain which is already unmapped.
Call trace:
venus_remove+0xf8/0x108 [venus_core]
venus_core_shutdown+0x1c/0x34 [venus_core]
platform_drv_shutdown+0x28/0x34
device_shutdown+0x154/0x1fc
kernel_restart_prepare+0x40/0x4c
kernel_restart+0x1c/0x64
__arm64_sys_reboot+0x190/0x238
el0_svc_common+0xa4/0x154
el0_svc_compat_handler+0x2c/0x38
el0_svc_compat+0x8/0x10
Signed-off-by: Mansur Alisha Shaik <mansur@codeaurora.org>
---
drivers/media/platform/qcom/venus/firmware.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c
index 1db64a8..d03e2dd 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -171,9 +171,14 @@ static int venus_shutdown_no_tz(struct venus_core *core)
iommu = core->fw.iommu_domain;
- unmapped = iommu_unmap(iommu, VENUS_FW_START_ADDR, mapped);
- if (unmapped != mapped)
- dev_err(dev, "failed to unmap firmware\n");
+ if (core->fw.mapped_mem_size && iommu) {
+ unmapped = iommu_unmap(iommu, VENUS_FW_START_ADDR, mapped);
+
+ if (unmapped != mapped)
+ dev_err(dev, "failed to unmap firmware\n");
+ else
+ core->fw.mapped_mem_size = 0;
+ }
return 0;
}
@@ -305,7 +310,11 @@ void venus_firmware_deinit(struct venus_core *core)
iommu = core->fw.iommu_domain;
iommu_detach_device(iommu, core->fw.dev);
- iommu_domain_free(iommu);
+
+ if (core->fw.iommu_domain) {
+ iommu_domain_free(iommu);
+ core->fw.iommu_domain = NULL;
+ }
platform_device_unregister(to_platform_device(core->fw.dev));
}
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v5 3/3] venus: core: add shutdown callback for venus
2020-09-24 6:59 [PATCH v5 0/3] venus: core: add shutdown callback for venus Mansur Alisha Shaik
2020-09-24 6:59 ` [PATCH v5 1/3] venus: core: handle race condititon for core ops Mansur Alisha Shaik
2020-09-24 6:59 ` [PATCH v5 2/3] venus: handle use after free for iommu_map/iommu_unmap Mansur Alisha Shaik
@ 2020-09-24 6:59 ` Mansur Alisha Shaik
2 siblings, 0 replies; 4+ messages in thread
From: Mansur Alisha Shaik @ 2020-09-24 6:59 UTC (permalink / raw)
To: linux-media, stanimir.varbanov
Cc: linux-kernel, linux-arm-msm, vgarodia, Mansur Alisha Shaik
After the SMMU translation is disabled in the
arm-smmu shutdown callback during reboot, if
any subsystem are still alive then IOVAs they
are using will become PAs on bus, which may
lead to crash.
So implemented shutdown callback, which detach iommu maps.
Signed-off-by: Mansur Alisha Shaik <mansur@codeaurora.org>
Acked-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
---
drivers/media/platform/qcom/venus/core.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 6103aaf..65b71ac 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -345,6 +345,14 @@ static int venus_remove(struct platform_device *pdev)
return ret;
}
+static void venus_core_shutdown(struct platform_device *pdev)
+{
+ struct venus_core *core = platform_get_drvdata(pdev);
+
+ venus_shutdown(core);
+ venus_firmware_deinit(core);
+}
+
static __maybe_unused int venus_runtime_suspend(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
@@ -602,6 +610,7 @@ static struct platform_driver qcom_venus_driver = {
.of_match_table = venus_dt_match,
.pm = &venus_pm_ops,
},
+ .shutdown = venus_core_shutdown,
};
module_platform_driver(qcom_venus_driver);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 4+ messages in thread