firmware: qcom: scm: Fix reserved memory cleanup on probe failure

of_reserved_mem_device_init() adds an entry to a global list with no
devres counterpart. If qcom_scm_probe() fails after the call the
assignment is never cleaned up. A probe retry would add a duplicate
entry, leaking the original one permanently.

Add an err_rmem label that calls of_reserved_mem_device_release() and
route all error paths after of_reserved_mem_device_init() through it.
of_reserved_mem_device_release() is safe to call unconditionally as it
simply walks an empty list when nothing was assigned.

Fixes: a33b2579c8 ("firmware: qcom: scm: add support for SHM bridge memory carveout")
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260724094939.613844-3-mukesh.ojha@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
This commit is contained in:
Mukesh Ojha
2026-07-24 15:19:38 +05:30
committed by Bjorn Andersson
parent 966d23c7e6
commit b697b20cea

View File

@@ -2850,9 +2850,11 @@ static int qcom_scm_probe(struct platform_device *pdev)
"Failed to setup the reserved memory region for TZ mem\n");
ret = qcom_tzmem_enable(scm->dev);
if (ret)
return dev_err_probe(scm->dev, ret,
"Failed to enable the TrustZone memory allocator\n");
if (ret) {
ret = dev_err_probe(scm->dev, ret,
"Failed to enable the TrustZone memory allocator\n");
goto err_rmem;
}
memset(&pool_config, 0, sizeof(pool_config));
pool_config.initial_size = 0;
@@ -2860,9 +2862,11 @@ static int qcom_scm_probe(struct platform_device *pdev)
pool_config.max_size = SZ_256K;
scm->mempool = devm_qcom_tzmem_pool_new(scm->dev, &pool_config);
if (IS_ERR(scm->mempool))
return dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
"Failed to create the SCM memory pool\n");
if (IS_ERR(scm->mempool)) {
ret = dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
"Failed to create the SCM memory pool\n");
goto err_rmem;
}
ret = qcom_scm_query_waitq_count(scm);
scm->wq_cnt = ret < 0 ? QCOM_SCM_DEFAULT_WAITQ_COUNT : ret;
@@ -2938,6 +2942,10 @@ static int qcom_scm_probe(struct platform_device *pdev)
qcom_scm_gunyah_wdt_init(scm);
return 0;
err_rmem:
of_reserved_mem_device_release(scm->dev);
return ret;
}
static void qcom_scm_shutdown(struct platform_device *pdev)