Skip to content

Commit 545fc69

Browse files
author
Jennifer Berringer
committed
firmware: qcom: scm: Cleanup global '__scm' on probe failures
JIRA: https://issues.redhat.com/browse/RHEL-73299 commit 1e76b54 Author: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Date: Mon Dec 9 15:27:57 2024 +0100 firmware: qcom: scm: Cleanup global '__scm' on probe failures If SCM driver fails the probe, it should not leave global '__scm' variable assigned, because external users of this driver will assume the probe finished successfully. For example TZMEM parts ('__scm->mempool') are initialized later in the probe, but users of it (__scm_smc_call()) rely on the '__scm' variable. This fixes theoretical NULL pointer exception, triggered via introducing probe deferral in SCM driver with call trace: qcom_tzmem_alloc+0x70/0x1ac (P) qcom_tzmem_alloc+0x64/0x1ac (L) qcom_scm_assign_mem+0x78/0x194 qcom_rmtfs_mem_probe+0x2d4/0x38c platform_probe+0x68/0xc8 Fixes: 40289e3 ("firmware: qcom: scm: enable the TZ mem allocator") Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20241209-qcom-scm-missing-barriers-and-all-sort-of-srap-v2-4-9061013c8d92@linaro.org Signed-off-by: Bjorn Andersson <andersson@kernel.org> Signed-off-by: Jennifer Berringer <jberring@redhat.com>
1 parent 1209c36 commit 545fc69

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

drivers/firmware/qcom/qcom_scm.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,13 +2022,17 @@ static int qcom_scm_probe(struct platform_device *pdev)
20222022

20232023
irq = platform_get_irq_optional(pdev, 0);
20242024
if (irq < 0) {
2025-
if (irq != -ENXIO)
2026-
return irq;
2025+
if (irq != -ENXIO) {
2026+
ret = irq;
2027+
goto err;
2028+
}
20272029
} else {
20282030
ret = devm_request_threaded_irq(__scm->dev, irq, NULL, qcom_scm_irq_handler,
20292031
IRQF_ONESHOT, "qcom-scm", __scm);
2030-
if (ret < 0)
2031-
return dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n");
2032+
if (ret < 0) {
2033+
dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n");
2034+
goto err;
2035+
}
20322036
}
20332037

20342038
__get_convention();
@@ -2047,24 +2051,30 @@ static int qcom_scm_probe(struct platform_device *pdev)
20472051
qcom_scm_disable_sdi();
20482052

20492053
ret = of_reserved_mem_device_init(__scm->dev);
2050-
if (ret && ret != -ENODEV)
2051-
return dev_err_probe(__scm->dev, ret,
2052-
"Failed to setup the reserved memory region for TZ mem\n");
2054+
if (ret && ret != -ENODEV) {
2055+
dev_err_probe(__scm->dev, ret,
2056+
"Failed to setup the reserved memory region for TZ mem\n");
2057+
goto err;
2058+
}
20532059

20542060
ret = qcom_tzmem_enable(__scm->dev);
2055-
if (ret)
2056-
return dev_err_probe(__scm->dev, ret,
2057-
"Failed to enable the TrustZone memory allocator\n");
2061+
if (ret) {
2062+
dev_err_probe(__scm->dev, ret,
2063+
"Failed to enable the TrustZone memory allocator\n");
2064+
goto err;
2065+
}
20582066

20592067
memset(&pool_config, 0, sizeof(pool_config));
20602068
pool_config.initial_size = 0;
20612069
pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
20622070
pool_config.max_size = SZ_256K;
20632071

20642072
__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
2065-
if (IS_ERR(__scm->mempool))
2066-
return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
2067-
"Failed to create the SCM memory pool\n");
2073+
if (IS_ERR(__scm->mempool)) {
2074+
dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
2075+
"Failed to create the SCM memory pool\n");
2076+
goto err;
2077+
}
20682078

20692079
/*
20702080
* Initialize the QSEECOM interface.
@@ -2080,6 +2090,12 @@ static int qcom_scm_probe(struct platform_device *pdev)
20802090
WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
20812091

20822092
return 0;
2093+
2094+
err:
2095+
/* Paired with smp_load_acquire() in qcom_scm_is_available(). */
2096+
smp_store_release(&__scm, NULL);
2097+
2098+
return ret;
20832099
}
20842100

20852101
static void qcom_scm_shutdown(struct platform_device *pdev)

0 commit comments

Comments
 (0)