linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem
@ 2025-06-30 12:12 Bartosz Golaszewski
  2025-06-30 12:12 ` [PATCH v2 1/4] firmware: qcom: scm: remove unused arguments from SHM bridge routines Bartosz Golaszewski
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2025-06-30 12:12 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski, Konrad Dybcio,
	Johan Hovold

There's a race condition between the SCM call API consumers and the TZMem
initialization in the SCM firmware driver. The internal __scm pointer is
assigned - marking SCM as ready for accepting calls - before the tzmem
memory pool is fully initialized. While the race is unlikely to be hit
thanks to the SCM driver being initialized early, it still must be
addressed.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
Changes in v2:
- add comments explaining the ordering of operations in probe()
- add Johan's Reported-by and Closes tags
- Link to v1: https://lore.kernel.org/r/20250625-qcom-scm-race-v1-0-45601e1f248b@linaro.org

---
Bartosz Golaszewski (4):
      firmware: qcom: scm: remove unused arguments from SHM bridge routines
      firmware: qcom: scm: take struct device as argument in SHM bridge enable
      firmware: qcom: scm: initialize tzmem before marking SCM as available
      firmware: qcom: scm: request the waitqueue irq *after* initializing SCM

 drivers/firmware/qcom/qcom_scm.c       | 95 ++++++++++++++++------------------
 drivers/firmware/qcom/qcom_scm.h       |  1 +
 drivers/firmware/qcom/qcom_tzmem.c     | 11 ++--
 include/linux/firmware/qcom/qcom_scm.h |  5 +-
 4 files changed, 55 insertions(+), 57 deletions(-)
---
base-commit: f817b6dd2b62d921a6cdc0a3ac599cd1851f343c
change-id: 20250624-qcom-scm-race-5e7737f7f39f

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/4] firmware: qcom: scm: remove unused arguments from SHM bridge routines
  2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
@ 2025-06-30 12:12 ` Bartosz Golaszewski
  2025-06-30 12:12 ` [PATCH v2 2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable Bartosz Golaszewski
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2025-06-30 12:12 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski, Konrad Dybcio

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

qcom_scm_shm_bridge_create() and qcom_scm_shm_bridge_delete() take
struct device as argument but don't use it. Remove it from these
functions' prototypes.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/firmware/qcom/qcom_scm.c       | 4 ++--
 drivers/firmware/qcom/qcom_tzmem.c     | 8 ++++----
 include/linux/firmware/qcom/qcom_scm.h | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index f63b716be5b027550ae3a987e784f0814ea6d678..d830511a0082a6a52e544a4b247b2863d8b06dbd 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1631,7 +1631,7 @@ int qcom_scm_shm_bridge_enable(void)
 }
 EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
 
-int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,
 			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
 			       u64 ns_vmids, u64 *handle)
 {
@@ -1659,7 +1659,7 @@ int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
 }
 EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
 
-int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle)
+int qcom_scm_shm_bridge_delete(u64 handle)
 {
 	struct qcom_scm_desc desc = {
 		.svc = QCOM_SCM_SVC_MP,
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 94196ad87105c6efc229bccebfd15e0be55f72c0..4fe333fd2f075a4e92ac6462d854848255665e18 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -124,9 +124,9 @@ static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
 	if (!handle)
 		return -ENOMEM;
 
-	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
-					 ipfn_and_s_perm, size_and_flags,
-					 QCOM_SCM_VMID_HLOS, handle);
+	ret = qcom_scm_shm_bridge_create(pfn_and_ns_perm, ipfn_and_s_perm,
+					 size_and_flags, QCOM_SCM_VMID_HLOS,
+					 handle);
 	if (ret)
 		return ret;
 
@@ -142,7 +142,7 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
 	if (!qcom_tzmem_using_shm_bridge)
 		return;
 
-	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
+	qcom_scm_shm_bridge_delete(*handle);
 	kfree(handle);
 }
 
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 983e1591bbba75215cc1ae3eb28455c0c360e0ce..82b1b8c50ca3e5f97665e6975e8d7e8e4299e65d 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -149,10 +149,10 @@ bool qcom_scm_lmh_dcvsh_available(void);
 int qcom_scm_gpu_init_regs(u32 gpu_req);
 
 int qcom_scm_shm_bridge_enable(void);
-int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,
 			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
 			       u64 ns_vmids, u64 *handle);
-int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle);
+int qcom_scm_shm_bridge_delete(u64 handle);
 
 #ifdef CONFIG_QCOM_QSEECOM
 

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable
  2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
  2025-06-30 12:12 ` [PATCH v2 1/4] firmware: qcom: scm: remove unused arguments from SHM bridge routines Bartosz Golaszewski
@ 2025-06-30 12:12 ` Bartosz Golaszewski
  2025-06-30 12:43   ` Konrad Dybcio
  2025-06-30 12:12 ` [PATCH v2 3/4] firmware: qcom: scm: initialize tzmem before marking SCM as available Bartosz Golaszewski
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Bartosz Golaszewski @ 2025-06-30 12:12 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

qcom_scm_shm_bridge_enable() is used early in the SCM initialization
routine. It makes an SCM call and so expects the internal __scm pointer
in the SCM driver to be assigned. For this reason the tzmem memory pool
is allocated *after* this pointer is assigned. However, this can lead to
a crash if another consumer of the SCM API makes a call using the memory
pool between the assignment of the __scm pointer and the initialization
of the tzmem memory pool.

As qcom_scm_shm_bridge_enable() is a special case, not meant to be
called by ordinary users, pull it into the local SCM header. Make it
take struct device as argument. This is the device that will be used to
make the SCM call as opposed to the global __scm pointer. This will
allow us to move the tzmem initialization *before* the __scm assignment
in the core SCM driver.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/firmware/qcom/qcom_scm.c       | 12 +++++++++---
 drivers/firmware/qcom/qcom_scm.h       |  1 +
 drivers/firmware/qcom/qcom_tzmem.c     |  3 ++-
 include/linux/firmware/qcom/qcom_scm.h |  1 -
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index d830511a0082a6a52e544a4b247b2863d8b06dbd..09b698b9021644660468d59bef496cd7859aec7f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1603,7 +1603,13 @@ bool qcom_scm_lmh_dcvsh_available(void)
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
 
-int qcom_scm_shm_bridge_enable(void)
+/*
+ * This is only supposed to be called once by the TZMem module. It takes the
+ * SCM struct device as argument and uses it to pass the call as at the time
+ * the SHM Bridge is enabled, the SCM is not yet fully set up and doesn't
+ * accept global user calls. Don't try to use the __scm pointer here.
+ */
+int qcom_scm_shm_bridge_enable(struct device *scm_dev)
 {
 	int ret;
 
@@ -1615,11 +1621,11 @@ int qcom_scm_shm_bridge_enable(void)
 
 	struct qcom_scm_res res;
 
-	if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+	if (!__qcom_scm_is_call_available(scm_dev, QCOM_SCM_SVC_MP,
 					  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
 		return -EOPNOTSUPP;
 
-	ret = qcom_scm_call(__scm->dev, &desc, &res);
+	ret = qcom_scm_call(scm_dev, &desc, &res);
 
 	if (ret)
 		return ret;
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index 3133d826f5fae8d135a8f03758173903a87e718b..0e8dd838099e1176b6d6bf76a204c875698eb1f7 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -83,6 +83,7 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
 		    struct qcom_scm_res *res);
 
 struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
+int qcom_scm_shm_bridge_enable(struct device *scm_dev);
 
 #define QCOM_SCM_SVC_BOOT		0x01
 #define QCOM_SCM_BOOT_SET_ADDR		0x01
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 4fe333fd2f075a4e92ac6462d854848255665e18..ea0a35355657064b1c08a6ebed7cfb483a60dd3f 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
+#include "qcom_scm.h"
 #include "qcom_tzmem.h"
 
 struct qcom_tzmem_area {
@@ -94,7 +95,7 @@ static int qcom_tzmem_init(void)
 			goto notsupp;
 	}
 
-	ret = qcom_scm_shm_bridge_enable();
+	ret = qcom_scm_shm_bridge_enable(qcom_tzmem_dev);
 	if (ret == -EOPNOTSUPP)
 		goto notsupp;
 
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 82b1b8c50ca3e5f97665e6975e8d7e8e4299e65d..0f667bf1d4d9d8c3e63d69159e3cdec2fb40396b 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -148,7 +148,6 @@ bool qcom_scm_lmh_dcvsh_available(void);
 
 int qcom_scm_gpu_init_regs(u32 gpu_req);
 
-int qcom_scm_shm_bridge_enable(void);
 int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,
 			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
 			       u64 ns_vmids, u64 *handle);

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/4] firmware: qcom: scm: initialize tzmem before marking SCM as available
  2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
  2025-06-30 12:12 ` [PATCH v2 1/4] firmware: qcom: scm: remove unused arguments from SHM bridge routines Bartosz Golaszewski
  2025-06-30 12:12 ` [PATCH v2 2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable Bartosz Golaszewski
@ 2025-06-30 12:12 ` Bartosz Golaszewski
  2025-06-30 12:12 ` [PATCH v2 4/4] firmware: qcom: scm: request the waitqueue irq *after* initializing SCM Bartosz Golaszewski
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2025-06-30 12:12 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski, Johan Hovold

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Now that qcom_scm_shm_bridge_enable() uses the struct device passed to
it as argument to make the QCOM_SCM_MP_SHM_BRIDGE_ENABLE SCM call, we
can move the TZMem initialization before the assignment of the __scm
pointer in the SCM driver (which marks SCM as ready to users) thus
fixing the potential race between consumer calls and the memory pool
initialization.

Reported-by: Johan Hovold <johan+linaro@kernel.org>
Closes: https://lore.kernel.org/all/20250120151000.13870-1-johan+linaro@kernel.org/
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/firmware/qcom/qcom_scm.c | 53 ++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 09b698b9021644660468d59bef496cd7859aec7f..b6e0420bb2b72247e4d772b66314d81f336f5d9d 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2256,7 +2256,32 @@ static int qcom_scm_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	/* Paired with smp_load_acquire() in qcom_scm_is_available(). */
+	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");
+
+	ret = qcom_tzmem_enable(scm->dev);
+	if (ret)
+		return dev_err_probe(scm->dev, ret,
+				     "Failed to enable the TrustZone memory allocator\n");
+
+	memset(&pool_config, 0, sizeof(pool_config));
+	pool_config.initial_size = 0;
+	pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
+	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");
+
+	/*
+	 * Paired with smp_load_acquire() in qcom_scm_is_available().
+	 *
+	 * This marks the SCM API as ready to accept user calls and can only
+	 * be called after the TrustZone memory pool is initialized.
+	 */
 	smp_store_release(&__scm, scm);
 
 	irq = platform_get_irq_optional(pdev, 0);
@@ -2289,32 +2314,6 @@ static int qcom_scm_probe(struct platform_device *pdev)
 	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled") || !download_mode)
 		qcom_scm_disable_sdi();
 
-	ret = of_reserved_mem_device_init(__scm->dev);
-	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) {
-		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;
-	pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
-	pool_config.max_size = SZ_256K;
-
-	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
-	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;
-	}
-
 	/*
 	 * Initialize the QSEECOM interface.
 	 *

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/4] firmware: qcom: scm: request the waitqueue irq *after* initializing SCM
  2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
                   ` (2 preceding siblings ...)
  2025-06-30 12:12 ` [PATCH v2 3/4] firmware: qcom: scm: initialize tzmem before marking SCM as available Bartosz Golaszewski
@ 2025-06-30 12:12 ` Bartosz Golaszewski
  2025-07-11  7:52 ` [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
  2025-07-17  4:30 ` Bjorn Andersson
  5 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2025-06-30 12:12 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski, Konrad Dybcio

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

There's a subtle race in the SCM driver: we assign the __scm pointer
before requesting the waitqueue interrupt. Assigning __scm marks the SCM
API as ready to accept calls. It's possible that a user makes a call
right after we set __scm and the firmware raises an interrupt before the
driver's ready to service it. Move the __scm assignment after we request
the interrupt.

This has the added benefit of allowing us to drop the goto label.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/firmware/qcom/qcom_scm.c | 36 ++++++++++++++----------------------
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index b6e0420bb2b72247e4d772b66314d81f336f5d9d..26cd0458aacd67dcd36f065675e969cea97eb465 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2276,29 +2276,27 @@ static int qcom_scm_probe(struct platform_device *pdev)
 		return dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
 				     "Failed to create the SCM memory pool\n");
 
+	irq = platform_get_irq_optional(pdev, 0);
+	if (irq < 0) {
+		if (irq != -ENXIO)
+			return irq;
+	} 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");
+	}
+
 	/*
 	 * Paired with smp_load_acquire() in qcom_scm_is_available().
 	 *
 	 * This marks the SCM API as ready to accept user calls and can only
-	 * be called after the TrustZone memory pool is initialized.
+	 * be called after the TrustZone memory pool is initialized and the
+	 * waitqueue interrupt requested.
 	 */
 	smp_store_release(&__scm, scm);
 
-	irq = platform_get_irq_optional(pdev, 0);
-	if (irq < 0) {
-		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) {
-			dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n");
-			goto err;
-		}
-	}
-
 	__get_convention();
 
 	/*
@@ -2328,12 +2326,6 @@ 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.48.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable
  2025-06-30 12:12 ` [PATCH v2 2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable Bartosz Golaszewski
@ 2025-06-30 12:43   ` Konrad Dybcio
  0 siblings, 0 replies; 8+ messages in thread
From: Konrad Dybcio @ 2025-06-30 12:43 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski



On 30-Jun-25 14:12, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> qcom_scm_shm_bridge_enable() is used early in the SCM initialization
> routine. It makes an SCM call and so expects the internal __scm pointer
> in the SCM driver to be assigned. For this reason the tzmem memory pool
> is allocated *after* this pointer is assigned. However, this can lead to
> a crash if another consumer of the SCM API makes a call using the memory
> pool between the assignment of the __scm pointer and the initialization
> of the tzmem memory pool.
> 
> As qcom_scm_shm_bridge_enable() is a special case, not meant to be
> called by ordinary users, pull it into the local SCM header. Make it
> take struct device as argument. This is the device that will be used to
> make the SCM call as opposed to the global __scm pointer. This will
> allow us to move the tzmem initialization *before* the __scm assignment
> in the core SCM driver.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem
  2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
                   ` (3 preceding siblings ...)
  2025-06-30 12:12 ` [PATCH v2 4/4] firmware: qcom: scm: request the waitqueue irq *after* initializing SCM Bartosz Golaszewski
@ 2025-07-11  7:52 ` Bartosz Golaszewski
  2025-07-17  4:30 ` Bjorn Andersson
  5 siblings, 0 replies; 8+ messages in thread
From: Bartosz Golaszewski @ 2025-07-11  7:52 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Johan Hovold
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski, Konrad Dybcio,
	Johan Hovold

On Mon, Jun 30, 2025 at 2:12 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> There's a race condition between the SCM call API consumers and the TZMem
> initialization in the SCM firmware driver. The internal __scm pointer is
> assigned - marking SCM as ready for accepting calls - before the tzmem
> memory pool is fully initialized. While the race is unlikely to be hit
> thanks to the SCM driver being initialized early, it still must be
> addressed.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---

We're late into rc5 so gentle ping, any chance we could get this
queued for v6.17?

Bartosz

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem
  2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
                   ` (4 preceding siblings ...)
  2025-07-11  7:52 ` [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
@ 2025-07-17  4:30 ` Bjorn Andersson
  5 siblings, 0 replies; 8+ messages in thread
From: Bjorn Andersson @ 2025-07-17  4:30 UTC (permalink / raw)
  To: Konrad Dybcio, Johan Hovold, Bartosz Golaszewski
  Cc: linux-arm-msm, linux-kernel, Bartosz Golaszewski, Konrad Dybcio,
	Johan Hovold


On Mon, 30 Jun 2025 14:12:01 +0200, Bartosz Golaszewski wrote:
> There's a race condition between the SCM call API consumers and the TZMem
> initialization in the SCM firmware driver. The internal __scm pointer is
> assigned - marking SCM as ready for accepting calls - before the tzmem
> memory pool is fully initialized. While the race is unlikely to be hit
> thanks to the SCM driver being initialized early, it still must be
> addressed.
> 
> [...]

Applied, thanks!

[1/4] firmware: qcom: scm: remove unused arguments from SHM bridge routines
      commit: 23972da96e1eee7f10c8ef641d56202ab9af8ba7
[2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable
      commit: dc3f4e75c54c19bad9a70419afae00ce6baf3ebf
[3/4] firmware: qcom: scm: initialize tzmem before marking SCM as available
      commit: 87be3e7a2d0030cda6314d2ec96b37991f636ccd
[4/4] firmware: qcom: scm: request the waitqueue irq *after* initializing SCM
      commit: 7ab36b51c6bee56e1a1939063dd10d602fe49d13

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-07-17  4:31 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-30 12:12 [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
2025-06-30 12:12 ` [PATCH v2 1/4] firmware: qcom: scm: remove unused arguments from SHM bridge routines Bartosz Golaszewski
2025-06-30 12:12 ` [PATCH v2 2/4] firmware: qcom: scm: take struct device as argument in SHM bridge enable Bartosz Golaszewski
2025-06-30 12:43   ` Konrad Dybcio
2025-06-30 12:12 ` [PATCH v2 3/4] firmware: qcom: scm: initialize tzmem before marking SCM as available Bartosz Golaszewski
2025-06-30 12:12 ` [PATCH v2 4/4] firmware: qcom: scm: request the waitqueue irq *after* initializing SCM Bartosz Golaszewski
2025-07-11  7:52 ` [PATCH v2 0/4] firmware: qcom: scm: fix potential race condition with tzmem Bartosz Golaszewski
2025-07-17  4:30 ` Bjorn Andersson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).