From: Mukesh Ojha mukesh.ojha@oss.qualcomm.com
[ Upstream commit 121fcf3c871181edce0708a49d2397cedd6ad21f ]
When qcom_scm_assign_mem() fails, the error value is currently being overwritten after it is logged, resulting in the loss of the original error code. Fix this by retaining and returning the original error value as intended.
Signed-off-by: Mukesh Ojha mukesh.ojha@oss.qualcomm.com Reviewed-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Link: https://lore.kernel.org/r/20250807124451.2623019-1-mukesh.ojha@oss.qualcomm.... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Based on my comprehensive analysis, here is my assessment:
## **Backport Status: YES**
### Summary of Analysis
This commit fixes a **7-year-old bug** in error handling for Qualcomm Secure Channel Manager memory assignment operations. The bug was introduced in commit d82bd359972a7f (Oct 2017) and has persisted across all kernel versions since then.
### Bug Description
In `qcom_scm_assign_mem()` at **drivers/firmware/qcom/qcom_scm.c:1122**, when the secure call `__qcom_scm_assign_mem()` fails: - The actual error code is logged: `"Assign memory protection call failed %d\n", ret` - But then **-EINVAL is hardcoded** in the return: `return -EINVAL;` - The fix changes this to: `return ret;`
This means callers lose critical diagnostic information about *why* the memory assignment failed.
### Impact Assessment
**Affected Subsystems** (verified via code search): - **drivers/misc/fastrpc.c** - FastRPC DSP communication (6 call sites) - **drivers/net/wireless/ath/ath10k/qmi.c** - WiFi driver (2 call sites) - **drivers/remoteproc/qcom_q6v5_mss.c** - Modem remoteproc (1 call site) - **drivers/remoteproc/qcom_q6v5_pas.c** - Peripheral remoteproc (2 call sites) - **drivers/soc/qcom/rmtfs_mem.c** - Remote filesystem memory (2 call sites)
All these subsystems need accurate error codes to distinguish between: - `-ENOMEM` - Memory allocation failures - `-ETIMEDOUT` - Secure call timeout - Firmware-specific error codes from `res.result[0]`
Currently, all failures return `-EINVAL`, making debugging Qualcomm platform issues significantly harder.
### Stable Kernel Criteria Compliance
✅ **Fixes a real bug**: Yes - error codes are incorrectly reported, affecting debugging ✅ **Small and contained**: Yes - single line change ✅ **Obviously correct**: Yes - preserves the actual error instead of overwriting it ✅ **No architectural changes**: Correct - purely error handling ✅ **Minimal regression risk**: Extremely low - only changes error return value ✅ **Already in mainline**: Yes - commit 121fcf3c871181edce0708a49d2397cedd6ad21f (Aug 2025) ✅ **Applies to all stable trees**: Verified present in v4.19, v5.10, v5.15, v6.6, v6.17
### Code Change Analysis
**Before:** ```c ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, ptr_phys, src_sz, dest_phys, dest_sz); if (ret) { dev_err(__scm->dev, "Assign memory protection call failed %d\n", ret); return -EINVAL; // ❌ Wrong - loses actual error } ```
**After:** ```c return ret; // ✅ Correct - preserves actual error ```
### Why This Should Be Backported
1. **Debugging improvement**: Users and developers debugging WiFi, modem, or DSP issues on Qualcomm platforms will get accurate error codes 2. **No behavior change for success case**: Only affects error paths 3. **No dependencies**: Applies cleanly across all kernel versions since 2017 4. **Consistent with kernel practices**: Error codes should be propagated, not overwritten 5. **Long-standing issue**: Bug has existed since initial implementation - affects many kernel versions in production
**Recommendation**: Backport to all active stable trees (6.12+, 6.6.x, 6.1.x, 5.15.x, 5.10.x, 5.4.x, 4.19.x).
drivers/firmware/qcom/qcom_scm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 26cd0458aacd6..5243d5abbbe99 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1119,7 +1119,7 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, if (ret) { dev_err(__scm->dev, "Assign memory protection call failed %d\n", ret); - return -EINVAL; + return ret; }
*srcvm = next_vm;