Archive-only list for patches
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>,
	Johan Hovold <johan+linaro@kernel.org>,
	Bjorn Andersson <andersson@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	konradybcio@kernel.org, linux-arm-msm@vger.kernel.org
Subject: [PATCH AUTOSEL 6.12 10/69] firmware: qcom: scm: initialize tzmem before marking SCM as available
Date: Sun,  3 Aug 2025 20:30:20 -0400	[thread overview]
Message-ID: <20250804003119.3620476-10-sashal@kernel.org> (raw)
In-Reply-To: <20250804003119.3620476-1-sashal@kernel.org>

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

[ Upstream commit 87be3e7a2d0030cda6314d2ec96b37991f636ccd ]

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>
Link: https://lore.kernel.org/r/20250630-qcom-scm-race-v2-3-fa3851c98611@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

YES

This commit should be backported to stable kernel trees. The commit
fixes a critical race condition in the Qualcomm SCM (Secure Channel
Manager) driver that can lead to system crashes.

**Analysis of the race condition:**

Looking at the code changes, the commit moves the TrustZone memory
(TZMem) pool initialization from **after** the SCM is marked as
available (line 2254 in the original code: `smp_store_release(&__scm,
scm)`) to **before** it. This is a critical ordering fix because:

1. **The race window**: Once `__scm` is assigned via
   `smp_store_release(&__scm, scm)` at line 2254, the SCM API becomes
   available to all kernel consumers through `qcom_scm_is_available()`
   which checks this pointer.

2. **The problem**: Between lines 2254-2298 in the original code, the
   SCM is marked as available but the TZMem pool (`__scm->mempool`)
   hasn't been initialized yet. If any SCM consumer makes an API call
   during this window that requires memory allocation from the TZMem
   pool, it will access an uninitialized pointer, causing a crash.

3. **The fix**: The commit moves the TZMem initialization (lines
   2286-2298 in original) to lines 2253-2277 in the patched version,
   ensuring the memory pool is fully initialized before marking SCM as
   available.

**Why this qualifies for stable backport:**

1. **Fixes a real bug**: This addresses a genuine race condition that
   can cause kernel crashes, as reported by Johan Hovold.

2. **Security-critical subsystem**: The SCM driver handles secure
   communication with TrustZone firmware on Qualcomm platforms, making
   stability crucial.

3. **Small, contained fix**: The change is minimal - it simply reorders
   initialization steps without changing functionality or adding
   features.

4. **No architectural changes**: This is purely a bug fix that corrects
   initialization ordering.

5. **Clear problem and solution**: The race condition is well-defined,
   and the fix is straightforward and obvious.

6. **Minimal regression risk**: Moving initialization earlier in the
   probe sequence is a safe change that doesn't affect the driver's
   operation once initialized.

The commit message also references a specific bug report, indicating
this is a real issue encountered in production, not a theoretical
problem. For stable kernel trees supporting Qualcomm platforms, this fix
prevents potential crashes during system initialization.

 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 23aefbf6fca5..88f3ae652a87 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2000,7 +2000,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);
@@ -2033,32 +2058,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.39.5


  parent reply	other threads:[~2025-08-04  0:31 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-04  0:30 [PATCH AUTOSEL 6.12 01/69] usb: xhci: print xhci->xhc_state when queue_command failed Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 02/69] platform/x86/amd: pmc: Add Lenovo Yoga 6 13ALC6 to pmc quirk list Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 03/69] cpufreq: CPPC: Mark driver with NEED_UPDATE_LIMITS flag Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 04/69] selftests/futex: Define SYS_futex on 32-bit architectures with 64-bit time_t Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 05/69] usb: typec: ucsi: psy: Set current max to 100mA for BC 1.2 and Default Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 06/69] regulator: core: repeat voltage setting request for stepped regulators Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 07/69] usb: xhci: Avoid showing warnings for dying controller Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 08/69] usb: xhci: Set avg_trb_len = 8 for EP0 during Address Device Command Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 09/69] usb: xhci: Avoid showing errors during surprise removal Sasha Levin
2025-08-04  0:30 ` Sasha Levin [this message]
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 11/69] soc: qcom: rpmh-rsc: Add RSC version 4 support Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 12/69] ACPI: APEI: send SIGBUS to current task if synchronous memory error not recovered Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 13/69] remoteproc: imx_rproc: skip clock enable when M-core is managed by the SCU Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 14/69] usb: typec: tcpm/tcpci_maxim: fix irq wake usage Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 15/69] pmdomain: ti: Select PM_GENERIC_DOMAINS Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 16/69] gpio: wcd934x: check the return value of regmap_update_bits() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 17/69] cpufreq: Exit governor when failed to start old governor Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 18/69] cpufreq: intel_pstate: Add Granite Rapids support in no-HWP mode Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 19/69] ARM: rockchip: fix kernel hang during smp initialization Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 20/69] PM / devfreq: governor: Replace sscanf() with kstrtoul() in set_freq_store() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 21/69] EDAC/synopsys: Clear the ECC counters on init Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 22/69] ASoC: soc-dapm: set bias_level if snd_soc_dapm_set_bias_level() was successed Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 23/69] thermal/drivers/qcom-spmi-temp-alarm: Enable stage 2 shutdown when required Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 24/69] tools/nolibc: define time_t in terms of __kernel_old_time_t Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 25/69] iio: adc: ad_sigma_delta: don't overallocate scan buffer Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 26/69] gpio: tps65912: check the return value of regmap_update_bits() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 27/69] mfd: tps6594: Add TI TPS652G1 support Sasha Levin
2025-08-18  6:34   ` Michael Walle
2025-08-19  2:01     ` Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 28/69] ARM: tegra: Use I/O memcpy to write to IRAM Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 29/69] tools/build: Fix s390(x) cross-compilation with clang Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 30/69] selftests: tracing: Use mutex_unlock for testing glob filter Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 31/69] ACPI: PRM: Reduce unnecessary printing to avoid user confusion Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 32/69] firmware: arm_scmi: power_control: Ensure SCMI_SYSPOWER_IDLE is set early during resume Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 33/69] firmware: tegra: Fix IVC dependency problems Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 34/69] pwm: sifive: Fix PWM algorithm and clarify inverted compare behavior Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 35/69] PM: runtime: Clear power.needs_force_resume in pm_runtime_reinit() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 36/69] thermal: sysfs: Return ENODATA instead of EAGAIN for reads Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 37/69] PM: sleep: console: Fix the black screen issue Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 38/69] ACPI: processor: fix acpi_object initialization Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 39/69] mmc: sdhci-msm: Ensure SD card power isn't ON when card removed Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 40/69] ACPI: APEI: GHES: add TAINT_MACHINE_CHECK on GHES panic path Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 41/69] selftests: vDSO: vdso_test_getrandom: Always print TAP header Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 42/69] pps: clients: gpio: fix interrupt handling order in remove path Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 43/69] reset: brcmstb: Enable reset drivers for ARCH_BCM2835 Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 44/69] char: misc: Fix improper and inaccurate error code returned by misc_init() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 45/69] mei: bus: Check for still connected devices in mei_cl_bus_dev_release() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 46/69] mmc: rtsx_usb_sdmmc: Fix error-path in sd_set_power_mode() Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 47/69] platform/chrome: cros_ec_sensorhub: Retries when a sensor is not ready Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 48/69] ALSA: hda: Handle the jack polling always via a work Sasha Levin
2025-08-04  0:30 ` [PATCH AUTOSEL 6.12 49/69] ALSA: hda: Disable jack polling at shutdown Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 50/69] x86/bugs: Avoid warning when overriding return thunk Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 51/69] ASoC: hdac_hdmi: Rate limit logging on connection and disconnection Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 52/69] ALSA: intel8x0: Fix incorrect codec index usage in mixer for ICH4 Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 53/69] ASoC: SOF: topology: Parse the dapm_widget_tokens in case of DSPless mode Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 54/69] tty: serial: fix print format specifiers Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 55/69] ASoC: core: Check for rtd == NULL in snd_soc_remove_pcm_runtime() Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 56/69] usb: typec: intel_pmc_mux: Defer probe if SCU IPC isn't present Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 57/69] usb: core: usb_submit_urb: downgrade type check Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 58/69] usb: typec: fusb302: fix scheduling while atomic when using virtio-gpio Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 59/69] pm: cpupower: Fix the snapshot-order of tsc,mperf, clock in mperf_stop() Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 60/69] imx8m-blk-ctrl: set ISI panic write hurry level Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 61/69] soc: qcom: mdt_loader: Actually use the e_phoff Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 62/69] platform/x86: thinkpad_acpi: Handle KCOV __init vs inline mismatches Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 63/69] platform/chrome: cros_ec_typec: Defer probe on missing EC parent Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 64/69] ALSA: hda/ca0132: Fix buffer overflow in add_tuning_control Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 65/69] ALSA: pcm: Rewrite recalculate_boundary() to avoid costly loop Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 66/69] ALSA: usb-audio: Avoid precedence issues in mixer_quirks macros Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 67/69] iio: adc: ad7768-1: Ensure SYNC_IN pulse minimum timing requirement Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 68/69] ASoC: codecs: rt5640: Retry DEVICE_ID verification Sasha Levin
2025-08-04  0:31 ` [PATCH AUTOSEL 6.12 69/69] ASoC: qcom: use drvdata instead of component to keep id Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250804003119.3620476-10-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=andersson@kernel.org \
    --cc=bartosz.golaszewski@linaro.org \
    --cc=johan+linaro@kernel.org \
    --cc=konradybcio@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox