Re: tpm: spi: do not call blocking ops when !TASK_RUNNING; during shutdown

Jarkko Sakkinen <[email protected]>
Newsgroups org.kernel.vger.linux-integrity,dev.linux.lists.imx,org.infradead.lists.linux-arm-kernel
Message-ID <[email protected]>
On Mon, May 04, 2026 at 06:05:25PM +0200, Stefan Wahren wrote:
> Am 04.05.26 um 15:42 schrieb Jarkko Sakkinen:
> > Hi Stefan,
> > 
> > On Mon, Apr 20, 2026 at 12:25:21PM +0200, Stefan Wahren wrote:
> > > Hi,
> > > we use a custom i.MX93 board, which based on Phytec Phycore i.MX93 with a
> > > TPM connected via SPI. If I enable CONFIG_DEBUG_ATOMIC_SLEEP=y in our kernel
> > > config with mainline kernel 6.18.23 and reboot our board, I will get the
> > > following warning:
> > Please provide results with the latest mainline kernel.
> > 
> Here you are
> 
> [   69.085410] do not call blocking ops when !TASK_RUNNING; state=1 set at
> [<0000000090f4020f>] prepare_to_wait_event+0x54/0x14c
> [   69.097076] WARNING: kernel/sched/core.c:9086 at __might_sleep+0x74/0x7c,
> CPU#0: systemd-shutdow/1
> [   69.106026] Modules linked in: flexcan can_dev rtc_rv3028 mse102x
> phy_can_transceiver fuse autofs4
> [   69.114991] CPU: 0 UID: 0 PID: 1 Comm: systemd-shutdow Not tainted
> 7.1.0-rc2-00005-g6d35786de281-dirty #45 PREEMPT
> [   69.125405] Hardware name: chargebyte Charge SOM Evaluation Kit (DT)
> [   69.131741] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS
> BTYPE=--)
> [   69.138690] pc : __might_sleep+0x74/0x7c
> [   69.142608] lr : __might_sleep+0x74/0x7c
> [   69.146525] sp : ffff800081b7b710
> [   69.149827] x29: ffff800081b7b710 x28: 0000000000000080 x27:
> ffff000002cafe80
> [   69.156951] x26: ffff800081965000 x25: 0000000000000018 x24:
> 0000000000000000
> [   69.164075] x23: ffff800081b7b8f7 x22: 0000000000000000 x21:
> 0000000000000080
> [   69.171199] x20: 000000000000013c x19: ffff8000813e2880 x18:
> 0000000000000000
> [   69.178323] x17: 003fffffffffffff x16: 000000000017d600 x15:
> ffff00003fda1a00
> [   69.185447] x14: ffff000000132c00 x13: 00000000000002ce x12:
> 0000000000000000
> [   69.192571] x11: 00000000000000c0 x10: 00000000000009e0 x9 :
> ffff800081b7b580
> [   69.199695] x8 : ffff0000001335c0 x7 : ffff00003fda1280 x6 :
> 0000000000000000
> [   69.206819] x5 : 000000001fffffff x4 : 0000000000000001 x3 :
> 0000000000000010
> [   69.213943] x2 : 0000000000000000 x1 : 0000000000000000 x0 :
> ffff000000132b80
> [   69.221068] Call trace:
> [   69.223503]  __might_sleep+0x74/0x7c (P)
> [   69.227420]  mutex_lock+0x24/0x80
> [   69.230731]  spi_bus_lock+0x20/0x50
> [   69.234214]  tpm_tis_spi_transfer_full+0x70/0x2c4
> [   69.238912]  tpm_tis_spi_read_bytes+0x3c/0x48
> [   69.243263]  tpm_tis_status+0x58/0xf8
> [   69.246920]  wait_for_tpm_stat_cond+0x30/0x90
> [   69.251271]  wait_for_tpm_stat+0x1cc/0x2e0
> [   69.255361]  tpm_tis_send_data+0xdc/0x35c
> [   69.259365]  tpm_tis_send_main+0x74/0x18c
> [   69.263369]  tpm_tis_send+0xd4/0x13c
> [   69.266940]  tpm_transmit+0xc4/0x3c4
> [   69.270511]  tpm_transmit_cmd+0x38/0xd4
> [   69.274341]  tpm2_shutdown+0x6c/0xa4
> [   69.277912]  tpm_class_shutdown+0x60/0x88
> [   69.281916]  device_shutdown+0x130/0x258
> [   69.285833]  kernel_restart+0x44/0xa4
> [   69.289491]  __do_sys_reboot+0x114/0x244
> [   69.293408]  __arm64_sys_reboot+0x24/0x30
> [   69.297412]  invoke_syscall+0x54/0x10c
> [   69.301156]  el0_svc_common.constprop.0+0x40/0xe0
> [   69.305853]  do_el0_svc+0x1c/0x28
> [   69.309164]  el0_svc+0x38/0x138
> [   69.312301]  el0t_64_sync_handler+0xa0/0xe4
> [   69.316478]  el0t_64_sync+0x198/0x19c

Thank you. This bug has been active since IRQs were enabled in tpm_tis_spi.
It's quite surprising that getting a report on it has taken so many years.
Anyway, my conclusion is that the bug report is totally legit.

"state=1" in the dump above refers to TASK_INTERRUPTIBLE, which unrolled
the root cause (I believe).

Here's an experimental fix that uses wake_woken(). It ensures that we
read status only while task is running.

BR, Jarkko
test.patch (text/x-diff, 2.7 KB)
From bf458dd675988a4fd78859a3e6a348071ecd2695 Mon Sep 17 00:00:00 2001
From: Jarkko Sakkinen <[email protected]>
Date: Sat, 9 May 2026 19:55:30 +0300
Subject: [PATCH] tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat()

wait_event_interruptible_timeout() evaluates its condition after setting
the current task state to TASK_INTERRUPTIBLE.

With CONFIG_DEBUG_ATOMIC_SLEEP this triggers a warning when the IRQ wait
path is used:

    tpm_tis_status()
      tpm_tis_spi_read_bytes()
        tpm_tis_spi_transfer_full()
          spi_bus_lock()
            mutex_lock()

Address this with the following measures:

1. Call wait_tpm_stat_cond() only while tasking is running.
2. Use wait_woken() to wait for changes.

Cc: [email protected] # v4.19+
Cc: Linus Walleij <[email protected]>
Reported-by: Stefan Wahren <[email protected]>
Closes: https://lore.kernel.org/linux-integrity/[email protected]/
Fixes: 1a339b658d9d ("tpm_tis_spi: Pass the SPI IRQ down to the driver")
Signed-off-by: Jarkko Sakkinen <[email protected]>
---
 drivers/char/tpm/tpm_tis_core.c | 40 +++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 21d79ad3b164..097ad0762895 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -66,8 +66,8 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
 		bool check_cancel)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+	DEFINE_WAIT_FUNC(wait, woken_wake_function);
 	unsigned long stop;
-	long rc;
 	u8 status;
 	bool canceled = false;
 	u8 sts_mask;
@@ -87,23 +87,29 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
 	/* process status changes with irq support */
 	if (sts_mask) {
 		ret = -ETIME;
-again:
-		timeout = stop - jiffies;
-		if ((long)timeout <= 0)
-			return -ETIME;
-		rc = wait_event_interruptible_timeout(*queue,
-			wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
-					       &canceled),
-			timeout);
-		if (rc > 0) {
-			if (canceled)
-				return -ECANCELED;
-			ret = 0;
-		}
-		if (rc == -ERESTARTSYS && freezing(current)) {
-			clear_thread_flag(TIF_SIGPENDING);
-			goto again;
+		add_wait_queue(queue, &wait);
+		for (;;) {
+			if (wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
+						   &canceled)) {
+				ret = canceled ? -ECANCELED : 0;
+				break;
+			}
+
+			timeout = stop - jiffies;
+			if ((long)timeout <= 0)
+				break;
+
+			if (signal_pending(current)) {
+				if (freezing(current)) {
+					clear_thread_flag(TIF_SIGPENDING);
+					continue;
+				}
+				break;
+			}
+
+			wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
 		}
+		remove_wait_queue(queue, &wait);
 	}

 	if (ret)
--
2.47.3
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.