[PATCH v3 2/2] firmware: qcom: scm: Allow the SMC request to freeze

From: Albert Esteve

Date: Thu Oct 01 2026 - 12:35:29 EST


From: Yuvaraj Ranganathan <yrangana@xxxxxxxxxxxxxxxx>

qcom_scm_wait_for_wq_completion() waits in TASK_IDLE. That is
uninterruptible, so a thread parked on a firmware waitq cannot be
frozen or killed. A long wait then blocks suspend, and shutdown
cannot tear the task down.

Wait with TASK_IDLE | TASK_FREEZABLE so the freezer can freeze the
waiter during suspend; after resume it is still waiting
for the same waitq completion.

TASK_KILLABLE is not added. If a fatal signal aborts the wait, the
driver returns early without issuing QCOM_SCM_WAITQ_RESUME, leaking
the TrustZone execution context.

Fixes: 366f05e348b2 ("firmware: qcom_scm: Use TASK_IDLE state in wait_for_wq_completion()")
Signed-off-by: Yuvaraj Ranganathan <yrangana@xxxxxxxxxxxxxxxx>
Signed-off-by: Albert Esteve <aesteve@xxxxxxxxxx>
---
drivers/firmware/qcom/qcom_scm.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index ea4481385412..92cee2263ed4 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2664,9 +2664,7 @@ int qcom_scm_wait_for_wq_completion(struct device *dev, u32 wq_ctx)
if (IS_ERR(wq))
return PTR_ERR(wq);

- wait_for_completion_state(wq, TASK_IDLE);
-
- return 0;
+ return wait_for_completion_state(wq, TASK_IDLE | TASK_FREEZABLE);
}

static int qcom_scm_waitq_wakeup(struct qcom_scm *scm, unsigned int wq_ctx)

--
2.55.0