* [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency
@ 2024-12-09 14:27 Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 1/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available() Krzysztof Kozlowski
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, stable, Krzysztof Kozlowski
Changes in v2:
- Patch #2: Extend commit msg
- Patch #4: Store NULL
- Add Rb tags
- Link to v1: https://lore.kernel.org/r/20241119-qcom-scm-missing-barriers-and-all-sort-of-srap-v1-0-7056127007a7@linaro.org
Description
===========
SCM driver looks messy in terms of handling concurrency of probe. The
driver exports interface which is guarded by global '__scm' variable
but:
1. Lacks proper read barrier (commit adding write barriers mixed up
READ_ONCE with a read barrier).
2. Lacks barriers or checks for '__scm' in multiple places.
3. Lacks probe error cleanup.
All the issues here are non-urgent, IOW, they were here for some time
(v6.10-rc1 and earlier).
Best regards,
Krzysztof
---
Krzysztof Kozlowski (6):
firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available()
firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool()
firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem()
firmware: qcom: scm: Cleanup global '__scm' on probe failures
firmware: qcom: scm: smc: Handle missing SCM device
firmware: qcom: scm: smc: Narrow 'mempool' variable scope
drivers/firmware/qcom/qcom_scm-smc.c | 6 +++-
drivers/firmware/qcom/qcom_scm.c | 55 +++++++++++++++++++++++++-----------
2 files changed, 44 insertions(+), 17 deletions(-)
---
base-commit: d1486dca38afd08ca279ae94eb3a397f10737824
change-id: 20241119-qcom-scm-missing-barriers-and-all-sort-of-srap-a25d59074882
Best regards,
--
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available()
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
@ 2024-12-09 14:27 ` Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 2/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool() Krzysztof Kozlowski
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, stable, Krzysztof Kozlowski
Commit 2e4955167ec5 ("firmware: qcom: scm: Fix __scm and waitq
completion variable initialization") introduced a write barrier in probe
function to store global '__scm' variable. It also claimed that it
added a read barrier, because as we all known barriers are paired (see
memory-barriers.txt: "Note that write barriers should normally be paired
with read or address-dependency barriers"), however it did not really
add it.
The offending commit used READ_ONCE() to access '__scm' global which is
not a barrier.
The barrier is needed so the store to '__scm' will be properly visible.
This is most likely not fatal in current driver design, because missing
read barrier would mean qcom_scm_is_available() callers will access old
value, NULL. Driver does not support unbinding and does not correctly
handle probe failures, thus there is no risk of stale or old pointer in
'__scm' variable.
However for code correctness, readability and to be sure that we did not
mess up something in this tricky topic of SMP barriers, add a read
barrier for accessing '__scm'. Change also comment from useless/obvious
what does barrier do, to what is expected: which other parts of the code
are involved here.
Fixes: 2e4955167ec5 ("firmware: qcom: scm: Fix __scm and waitq completion variable initialization")
Cc: stable@vger.kernel.org
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
drivers/firmware/qcom/qcom_scm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 72bf87ddcd969834609cda2aa915b67505e93943..246d672e8f7f0e2a326a03a5af40cd434a665e67 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1867,7 +1867,8 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm)
*/
bool qcom_scm_is_available(void)
{
- return !!READ_ONCE(__scm);
+ /* Paired with smp_store_release() in qcom_scm_probe */
+ return !!smp_load_acquire(&__scm);
}
EXPORT_SYMBOL_GPL(qcom_scm_is_available);
@@ -2024,7 +2025,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
if (ret)
return ret;
- /* Let all above stores be available after this */
+ /* Paired with smp_load_acquire() in qcom_scm_is_available(). */
smp_store_release(&__scm, scm);
irq = platform_get_irq_optional(pdev, 0);
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool()
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 1/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available() Krzysztof Kozlowski
@ 2024-12-09 14:27 ` Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem() Krzysztof Kozlowski
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, stable, Krzysztof Kozlowski
Commit 2e4955167ec5 ("firmware: qcom: scm: Fix __scm and waitq
completion variable initialization") introduced a write barrier in probe
function to store global '__scm' variable. We all known barriers are
paired (see memory-barriers.txt: "Note that write barriers should
normally be paired with read or address-dependency barriers"), therefore
accessing it from concurrent contexts requires read barrier. Previous
commit added such barrier in qcom_scm_is_available(), so let's use that
directly.
Lack of this read barrier can result in fetching stale '__scm' variable
value, NULL, and dereferencing it.
Note that barrier in qcom_scm_is_available() satisfies here the control
dependency.
Fixes: ca61d6836e6f ("firmware: qcom: scm: fix a NULL-pointer dereference")
Fixes: 449d0d84bcd8 ("firmware: qcom: scm: smc: switch to using the SCM allocator")
Cc: <stable@vger.kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
drivers/firmware/qcom/qcom_scm.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 246d672e8f7f0e2a326a03a5af40cd434a665e67..5d91b8e22844608f35432f1ba9c08d477d4ff762 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -217,7 +217,10 @@ static DEFINE_SPINLOCK(scm_query_lock);
struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)
{
- return __scm ? __scm->mempool : NULL;
+ if (!qcom_scm_is_available())
+ return NULL;
+
+ return __scm->mempool;
}
static enum qcom_scm_convention __get_convention(void)
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem()
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 1/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available() Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 2/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool() Krzysztof Kozlowski
@ 2024-12-09 14:27 ` Krzysztof Kozlowski
2024-12-09 20:25 ` Bartosz Golaszewski
2025-01-07 0:42 ` Bjorn Andersson
2024-12-09 14:27 ` [PATCH v2 4/6] firmware: qcom: scm: Cleanup global '__scm' on probe failures Krzysztof Kozlowski
` (3 subsequent siblings)
6 siblings, 2 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, Krzysztof Kozlowski
The SCM driver can defer or fail probe, or just load a bit later so
callers of qcom_scm_assign_mem() should defer if the device is not ready.
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: d82bd359972a ("firmware: scm: Add new SCM call API for switching memory ownership")
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
I am not sure about commit introducing it (Fixes tag) thus not Cc-ing
stable.
---
drivers/firmware/qcom/qcom_scm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 5d91b8e22844608f35432f1ba9c08d477d4ff762..93212c8f20ad65ecc44804b00f4b93e3eaaf8d95 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1075,6 +1075,9 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
int ret, i, b;
u64 srcvm_bits = *srcvm;
+ if (!qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
src_sz = hweight64(srcvm_bits) * sizeof(*src);
mem_to_map_sz = sizeof(*mem_to_map);
dest_sz = dest_cnt * sizeof(*destvm);
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 4/6] firmware: qcom: scm: Cleanup global '__scm' on probe failures
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
` (2 preceding siblings ...)
2024-12-09 14:27 ` [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem() Krzysztof Kozlowski
@ 2024-12-09 14:27 ` Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 5/6] firmware: qcom: scm: smc: Handle missing SCM device Krzysztof Kozlowski
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, Krzysztof Kozlowski
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: 40289e35ca52 ("firmware: qcom: scm: enable the TZ mem allocator")
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
I am not really sure if authors wanted the cleanup at this point.
Also, I am not sure about commit introducing it (Fixes tag) thus not
Cc-ing stable.
Changes in v2:
1. Store NULL
---
drivers/firmware/qcom/qcom_scm.c | 42 +++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 93212c8f20ad65ecc44804b00f4b93e3eaaf8d95..bfb925586e05f7d3fb7f00e3d3d3eae4e35f39c0 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2036,13 +2036,17 @@ static int qcom_scm_probe(struct platform_device *pdev)
irq = platform_get_irq_optional(pdev, 0);
if (irq < 0) {
- if (irq != -ENXIO)
- return irq;
+ if (irq != -ENXIO) {
+ ret = irq;
+ goto err;
+ }
} else {
ret = devm_request_threaded_irq(__scm->dev, irq, NULL, qcom_scm_irq_handler,
IRQF_ONESHOT, "qcom-scm", __scm);
- if (ret < 0)
- return dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n");
+ if (ret < 0) {
+ dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n");
+ goto err;
+ }
}
__get_convention();
@@ -2061,14 +2065,18 @@ static int qcom_scm_probe(struct platform_device *pdev)
qcom_scm_disable_sdi();
ret = of_reserved_mem_device_init(__scm->dev);
- if (ret && ret != -ENODEV)
- return dev_err_probe(__scm->dev, ret,
- "Failed to setup the reserved memory region for TZ mem\n");
+ if (ret && ret != -ENODEV) {
+ dev_err_probe(__scm->dev, ret,
+ "Failed to setup the reserved memory region for TZ mem\n");
+ goto err;
+ }
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) {
+ dev_err_probe(__scm->dev, ret,
+ "Failed to enable the TrustZone memory allocator\n");
+ goto err;
+ }
memset(&pool_config, 0, sizeof(pool_config));
pool_config.initial_size = 0;
@@ -2076,9 +2084,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)) {
+ dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
+ "Failed to create the SCM memory pool\n");
+ goto err;
+ }
/*
* Initialize the QSEECOM interface.
@@ -2094,6 +2104,12 @@ static int qcom_scm_probe(struct platform_device *pdev)
WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
return 0;
+
+err:
+ /* Paired with smp_load_acquire() in qcom_scm_is_available(). */
+ smp_store_release(&__scm, NULL);
+
+ return ret;
}
static void qcom_scm_shutdown(struct platform_device *pdev)
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 5/6] firmware: qcom: scm: smc: Handle missing SCM device
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
` (3 preceding siblings ...)
2024-12-09 14:27 ` [PATCH v2 4/6] firmware: qcom: scm: Cleanup global '__scm' on probe failures Krzysztof Kozlowski
@ 2024-12-09 14:27 ` Krzysztof Kozlowski
2024-12-09 15:14 ` Bartosz Golaszewski
2024-12-09 14:27 ` [PATCH v2 6/6] firmware: qcom: scm: smc: Narrow 'mempool' variable scope Krzysztof Kozlowski
2025-01-07 16:38 ` (subset) [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Bjorn Andersson
6 siblings, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, Krzysztof Kozlowski
Commit ca61d6836e6f ("firmware: qcom: scm: fix a NULL-pointer
dereference") makes it explicit that qcom_scm_get_tzmem_pool() can
return NULL, therefore its users should handle this.
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
drivers/firmware/qcom/qcom_scm-smc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 2b4c2826f57251f25a1bc37c3b467dde28e1268b..3f10b23ec941b558e1d91761011776bb5c9d11b5 100644
--- a/drivers/firmware/qcom/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
@@ -173,6 +173,9 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
+ if (!mempool)
+ return -EINVAL;
+
args_virt = qcom_tzmem_alloc(mempool,
SCM_SMC_N_EXT_ARGS * sizeof(u64),
flag);
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 6/6] firmware: qcom: scm: smc: Narrow 'mempool' variable scope
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
` (4 preceding siblings ...)
2024-12-09 14:27 ` [PATCH v2 5/6] firmware: qcom: scm: smc: Handle missing SCM device Krzysztof Kozlowski
@ 2024-12-09 14:27 ` Krzysztof Kozlowski
2025-01-07 16:38 ` (subset) [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Bjorn Andersson
6 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-09 14:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Bartosz Golaszewski, Kuldeep Singh,
Elliot Berman, Andrew Halaney, Avaneesh Kumar Dwivedi, Andy Gross
Cc: linux-arm-msm, linux-kernel, Krzysztof Kozlowski
Only part of the __scm_smc_call() function uses 'mempool' variable, so
narrow the scope to make it more readable.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
drivers/firmware/qcom/qcom_scm-smc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 3f10b23ec941b558e1d91761011776bb5c9d11b5..574930729ddd72d98013770da97cc018a52554ff 100644
--- a/drivers/firmware/qcom/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
@@ -152,7 +152,6 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
enum qcom_scm_convention qcom_convention,
struct qcom_scm_res *res, bool atomic)
{
- struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
int arglen = desc->arginfo & 0xf;
int i, ret;
void *args_virt __free(qcom_tzmem) = NULL;
@@ -173,6 +172,8 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
+ struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
+
if (!mempool)
return -EINVAL;
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 5/6] firmware: qcom: scm: smc: Handle missing SCM device
2024-12-09 14:27 ` [PATCH v2 5/6] firmware: qcom: scm: smc: Handle missing SCM device Krzysztof Kozlowski
@ 2024-12-09 15:14 ` Bartosz Golaszewski
0 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2024-12-09 15:14 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Kuldeep Singh, Elliot Berman, Andrew Halaney,
Avaneesh Kumar Dwivedi, Andy Gross, linux-arm-msm, linux-kernel
On Mon, 9 Dec 2024 at 15:28, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> Commit ca61d6836e6f ("firmware: qcom: scm: fix a NULL-pointer
> dereference") makes it explicit that qcom_scm_get_tzmem_pool() can
> return NULL, therefore its users should handle this.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
> drivers/firmware/qcom/qcom_scm-smc.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
> index 2b4c2826f57251f25a1bc37c3b467dde28e1268b..3f10b23ec941b558e1d91761011776bb5c9d11b5 100644
> --- a/drivers/firmware/qcom/qcom_scm-smc.c
> +++ b/drivers/firmware/qcom/qcom_scm-smc.c
> @@ -173,6 +173,9 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
> smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
>
> if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
> + if (!mempool)
> + return -EINVAL;
> +
> args_virt = qcom_tzmem_alloc(mempool,
> SCM_SMC_N_EXT_ARGS * sizeof(u64),
> flag);
>
> --
> 2.43.0
>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem()
2024-12-09 14:27 ` [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem() Krzysztof Kozlowski
@ 2024-12-09 20:25 ` Bartosz Golaszewski
2025-01-07 0:42 ` Bjorn Andersson
1 sibling, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2024-12-09 20:25 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov,
Stephan Gerhold, Kuldeep Singh, Elliot Berman, Andrew Halaney,
Avaneesh Kumar Dwivedi, Andy Gross, linux-arm-msm, linux-kernel
On Mon, 9 Dec 2024 at 15:28, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> The SCM driver can defer or fail probe, or just load a bit later so
> callers of qcom_scm_assign_mem() should defer if the device is not ready.
>
> 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: d82bd359972a ("firmware: scm: Add new SCM call API for switching memory ownership")
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
>
> ---
>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem()
2024-12-09 14:27 ` [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem() Krzysztof Kozlowski
2024-12-09 20:25 ` Bartosz Golaszewski
@ 2025-01-07 0:42 ` Bjorn Andersson
2025-01-08 11:12 ` Krzysztof Kozlowski
1 sibling, 1 reply; 12+ messages in thread
From: Bjorn Andersson @ 2025-01-07 0:42 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov, Stephan Gerhold,
Bartosz Golaszewski, Kuldeep Singh, Elliot Berman, Andrew Halaney,
Avaneesh Kumar Dwivedi, Andy Gross, linux-arm-msm, linux-kernel
On Mon, Dec 09, 2024 at 03:27:56PM +0100, Krzysztof Kozlowski wrote:
> The SCM driver can defer or fail probe, or just load a bit later so
> callers of qcom_scm_assign_mem() should defer if the device is not ready.
>
> 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: d82bd359972a ("firmware: scm: Add new SCM call API for switching memory ownership")
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
>
> ---
>
> I am not sure about commit introducing it (Fixes tag) thus not Cc-ing
> stable.
> ---
> drivers/firmware/qcom/qcom_scm.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 5d91b8e22844608f35432f1ba9c08d477d4ff762..93212c8f20ad65ecc44804b00f4b93e3eaaf8d95 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -1075,6 +1075,9 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
> int ret, i, b;
> u64 srcvm_bits = *srcvm;
>
> + if (!qcom_scm_is_available())
> + return -EPROBE_DEFER;
This API is generally called from places other than probe, making the
return of EPROBE_DEFER undesirable. While not pretty, a client depending
on the scm driver to be probed is expected to call
qcom_scm_is_available().
qcom_rmtfs_mem_probe() does this right before calling
qcom_scm_assign_mem(), am I misunderstanding the case you're describing?
Regards,
Bjorn
> +
> src_sz = hweight64(srcvm_bits) * sizeof(*src);
> mem_to_map_sz = sizeof(*mem_to_map);
> dest_sz = dest_cnt * sizeof(*destvm);
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: (subset) [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
` (5 preceding siblings ...)
2024-12-09 14:27 ` [PATCH v2 6/6] firmware: qcom: scm: smc: Narrow 'mempool' variable scope Krzysztof Kozlowski
@ 2025-01-07 16:38 ` Bjorn Andersson
6 siblings, 0 replies; 12+ messages in thread
From: Bjorn Andersson @ 2025-01-07 16:38 UTC (permalink / raw)
To: Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov, Stephan Gerhold,
Bartosz Golaszewski, Kuldeep Singh, Elliot Berman, Andrew Halaney,
Avaneesh Kumar Dwivedi, Andy Gross, Krzysztof Kozlowski
Cc: linux-arm-msm, linux-kernel, stable
On Mon, 09 Dec 2024 15:27:53 +0100, Krzysztof Kozlowski wrote:
> Changes in v2:
> - Patch #2: Extend commit msg
> - Patch #4: Store NULL
> - Add Rb tags
> - Link to v1: https://lore.kernel.org/r/20241119-qcom-scm-missing-barriers-and-all-sort-of-srap-v1-0-7056127007a7@linaro.org
>
> Description
> ===========
> SCM driver looks messy in terms of handling concurrency of probe. The
> driver exports interface which is guarded by global '__scm' variable
> but:
> 1. Lacks proper read barrier (commit adding write barriers mixed up
> READ_ONCE with a read barrier).
> 2. Lacks barriers or checks for '__scm' in multiple places.
> 3. Lacks probe error cleanup.
>
> [...]
Applied, thanks!
[1/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available()
commit: 0a744cceebd0480cb39587b3b1339d66a9d14063
[2/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool()
commit: b628510397b5cafa1f5d3e848a28affd1c635302
[4/6] firmware: qcom: scm: Cleanup global '__scm' on probe failures
commit: 1e76b546e6fca7eb568161f408133904ca6bcf4f
[5/6] firmware: qcom: scm: smc: Handle missing SCM device
commit: 94f48ecf0a538019ca2025e0b0da391f8e7cc58c
[6/6] firmware: qcom: scm: smc: Narrow 'mempool' variable scope
commit: a4332f6c791e1d70bf025ac51afa968607b9812b
Best regards,
--
Bjorn Andersson <andersson@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem()
2025-01-07 0:42 ` Bjorn Andersson
@ 2025-01-08 11:12 ` Krzysztof Kozlowski
0 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-01-08 11:12 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Konrad Dybcio, Mukesh Ojha, Dmitry Baryshkov, Stephan Gerhold,
Bartosz Golaszewski, Kuldeep Singh, Elliot Berman, Andrew Halaney,
Avaneesh Kumar Dwivedi, Andy Gross, linux-arm-msm, linux-kernel
On 07/01/2025 01:42, Bjorn Andersson wrote:
>>
>> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
>> index 5d91b8e22844608f35432f1ba9c08d477d4ff762..93212c8f20ad65ecc44804b00f4b93e3eaaf8d95 100644
>> --- a/drivers/firmware/qcom/qcom_scm.c
>> +++ b/drivers/firmware/qcom/qcom_scm.c
>> @@ -1075,6 +1075,9 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
>> int ret, i, b;
>> u64 srcvm_bits = *srcvm;
>>
>> + if (!qcom_scm_is_available())
>> + return -EPROBE_DEFER;
>
> This API is generally called from places other than probe, making the
> return of EPROBE_DEFER undesirable. While not pretty, a client depending
> on the scm driver to be probed is expected to call
> qcom_scm_is_available().
>
> qcom_rmtfs_mem_probe() does this right before calling
> qcom_scm_assign_mem(), am I misunderstanding the case you're describing?
I tried to reproduce my NULL ptr but now I cannot and indeed if every
path is protected with qcom_scm_is_available() everything should be fine.
Let's skip this patch then.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-01-08 11:12 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-09 14:27 [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 1/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available() Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 2/6] firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool() Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 3/6] firmware: qcom: scm: Handle various probe ordering for qcom_scm_assign_mem() Krzysztof Kozlowski
2024-12-09 20:25 ` Bartosz Golaszewski
2025-01-07 0:42 ` Bjorn Andersson
2025-01-08 11:12 ` Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 4/6] firmware: qcom: scm: Cleanup global '__scm' on probe failures Krzysztof Kozlowski
2024-12-09 14:27 ` [PATCH v2 5/6] firmware: qcom: scm: smc: Handle missing SCM device Krzysztof Kozlowski
2024-12-09 15:14 ` Bartosz Golaszewski
2024-12-09 14:27 ` [PATCH v2 6/6] firmware: qcom: scm: smc: Narrow 'mempool' variable scope Krzysztof Kozlowski
2025-01-07 16:38 ` (subset) [PATCH v2 0/6] firmware: qcom: scm: Fixes for concurrency Bjorn Andersson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox