Re: [PATCH] firmware: qcom: tzmem: Use DO_ONCE_SLEEPABLE() in qcom_tzmem_enable()

Bartosz Golaszewski <[email protected]>
Newsgroups org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel
Message-ID <CAMRc=MffWt7TrSXaQpd6Zo_BHOrDv2tMxBh9cmMvkqem3Q245w@mail.gmail.com>
On Thu, 6 Aug 2026 13:27:09 +0200, Mukesh Ojha
<[email protected]> said:
> qcom_tzmem_enable() is called from qcom_scm_probe() in a sleepable process
> context. The helper it wraps, qcom_tzmem_init(), calls
> qcom_scm_shm_bridge_enable() -> qcom_scm_call(), which invokes
> might_sleep() and later acquires the qcom_scm_lock mutex via
> __scm_smc_do().
>
> DO_ONCE() takes the once_lock spinlock with IRQs disabled, so invoking
> qcom_tzmem_init() from inside DO_ONCE() runs a sleepable call chain in
> atomic context. CONFIG_DEBUG_ATOMIC_SLEEP=y catches this on boot:
>
>   BUG: sleeping function called from invalid context at drivers/firmware/qcom/qcom_scm.c:334
>   in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 49, name: kworker/u16:2
>   ...
>    __might_resched+0x148/0x24c
>    __might_sleep+0x48/0x7c
>    qcom_scm_call+0x30/0xc0
>    __qcom_scm_is_call_available+0x98/0x100
>    qcom_scm_shm_bridge_enable+0x60/0xbc
>    qcom_tzmem_enable+0xf8/0x118
>    qcom_scm_probe+0x2d0/0x680
>
>   [ BUG: Invalid wait context ]
>   ...
>   kworker/u16:2/49 is trying to lock:
>   ffffa83e8a485e38 (qcom_scm_lock){....}-{4:4}, at: __scm_smc_do+0x70/0x488
>
> Switch to DO_ONCE_SLEEPABLE(), which guards the one-shot init with a
> mutex-style path (__do_once_sleepable_start/done) that is safe to hold
> across sleeping callees. All callers of qcom_tzmem_enable() are in
> process context (driver probe), so this is safe.
>
> Fixes: 9941fe8a04f3 ("firmware: qcom: scm: Fix tzmem state on probe retry")
> Reported-by: Marek Szyprowski <[email protected]>
> Closes: https://lore.kernel.org/lkml/[email protected]/
> Signed-off-by: Mukesh Ojha <[email protected]>
> ---
>  drivers/firmware/qcom/qcom_tzmem.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> index 0fd9581275f1..ebcdee3c5975 100644
> --- a/drivers/firmware/qcom/qcom_tzmem.c
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -518,7 +518,7 @@ int qcom_tzmem_enable(struct device *dev)
>  	static int result;
>
>  	qcom_tzmem_dev = dev;
> -	DO_ONCE(qcom_tzmem_do_init, &result);
> +	DO_ONCE_SLEEPABLE(qcom_tzmem_do_init, &result);
>  	return result;
>  }
>  EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
> --
> 2.53.0
>
>

Reviewed-by: Bartosz Golaszewski <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.