From: Jarkko Sakkinen <jarkko@kernel.org>
To: Breno Leitao <leitao@debian.org>
Cc: Peter Huewe <peterhuewe@gmx.de>, Jason Gunthorpe <jgg@ziepe.ca>,
linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org,
surenkj@amazon.com, noodles@meta.com, kernel-team@meta.com
Subject: Re: [PATCH v2 1/2] tpm: Disable a TPM that stops responding
Date: Thu, 12 Nov 2026 16:03:06 +0200 [thread overview]
Message-ID: <avXHGmmdY-CVgxEf@kernel.org> (raw)
In-Reply-To: <avXGjiejK2ZlldKs@kernel.org>
On Thu, Nov 12, 2026 at 04:00:50PM +0200, Jarkko Sakkinen wrote:
> On Thu, Nov 12, 2026 at 04:30:17AM -0800, Breno Leitao wrote:
> > A TPM that stops responding fails each command only after the transport
> > timeout, and its callers keep sending more: the hwrng thread every 10
> > seconds forever, and userspace through /dev/tpmrm0. Each attempt holds
> > tpm_mutex for the whole timeout and logs an error:
> >
> > tpm tpm0: invalid TPM_STS.x 0xff, dumping stack for forensics
> > tpm tpm0: tpm_try_transmit: send(): error -62
> > tpm tpm0: tpm_try_transmit: send(): error -62
> > ...
> >
> > The core already stops using a TPM it cannot trust: tpm_try_get_ops()
> > fails with -EIO once TPM_CHIP_FLAG_DISABLE is set, which
> > tpm2_load_null() does when it cannot restore the null key. Set the same
> > flag once 60 commands in a row have timed out.
> >
> > A completed command, whatever its TPM return code, resets the count.
> > Some TPMs stall for half a minute, time out a handful of commands, and
> > then recover, so a short streak must not disable them.
> >
> > With only the hwrng retrying every 10 seconds, 60 timeouts take more
> > than ten minutes. A userspace poller gets there sooner, but each of its
> > commands still waits out the transport timeout.
> >
> > The limit is the tpm.max_unanswered boot parameter, so that slow
> > pre-production parts, such as FPGA prototypes, can raise it, or set it
> > to 0 to never disable the TPM. A disabled TPM stays disabled until the
> > driver is rebound or the machine reboots.
> >
> > Signed-off-by: Breno Leitao <leitao@debian.org>
> > ---
> > drivers/char/tpm/tpm-interface.c | 15 +++++++++++++++
> > include/linux/tpm.h | 1 +
> > 2 files changed, 16 insertions(+)
> >
> > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> > index e0385b16616b46..b7865ccb799289 100644
> > --- a/drivers/char/tpm/tpm-interface.c
> > +++ b/drivers/char/tpm/tpm-interface.c
> > @@ -40,6 +40,11 @@ module_param_named(suspend_pcr, tpm_suspend_pcr, uint, 0644);
> > MODULE_PARM_DESC(suspend_pcr,
> > "PCR to use for dummy writes to facilitate flush on suspend.");
> >
> > +static unsigned int tpm_max_unanswered = 60;
> > +module_param_named(max_unanswered, tpm_max_unanswered, uint, 0444);
> > +MODULE_PARM_DESC(max_unanswered,
> > + "Disable the TPM after this many commands in a row time out (0 = never).");
>
> Documentation/admin/kernel-parameters.txt update is also needed.
>
> tpm_max_missed_responses is what I would suggest, because it is more
> accurate e.g., on stating what is being counted :-)
>
>
> > +
> > /**
> > * tpm_calc_ordinal_duration() - calculate the maximum command duration
> > * @chip: TPM chip to use.
> > @@ -268,6 +273,16 @@ ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz)
> > delay_msec *= 2;
> > memcpy(buf, save, save_size);
> > }
> > +
> > + if (ret >= 0) {
> > + /* we are good, reset nr_unanswered */
>
> I'm not a huge fan in general of third person plural in the source code
> comments. Probably a comment here is not needed at all as it does not
> state anything that would not be obvious (i.e. something nothing
> non-obvious is documented).
>
> > + chip->nr_unanswered = 0;
> > + } else if (ret == -ETIME &&
> > + ++chip->nr_unanswered == tpm_max_unanswered) {
> > + dev_err(&chip->dev, "%u commands in a row timed out, disabling the TPM\n",
> > + chip->nr_unanswered);
> > + chip->flags |= TPM_CHIP_FLAG_DISABLE;
> > + }
> > return ret;
> > }
> >
> > diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> > index 0db277af45c393..e8191585a68e7a 100644
> > --- a/include/linux/tpm.h
> > +++ b/include/linux/tpm.h
> > @@ -131,6 +131,7 @@ struct tpm_chip {
> > struct hwrng hwrng;
> >
> > struct mutex tpm_mutex; /* tpm is processing */
> > + unsigned int nr_unanswered; /* commands in a row that timed out */
>
> This would be then nr_lost_responses.
Oops sorry.
I mean nr_missed_responses (and I would prefer "missed" over "lost").
Br, Jarkko
next prev parent reply other threads:[~2026-11-12 14:03 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 12:30 [PATCH v2 0/2] tpm: Stop retrying TPMs that have stopped working Breno Leitao
2026-11-12 12:30 ` [PATCH v2 1/2] tpm: Disable a TPM that stops responding Breno Leitao
2026-11-12 14:00 ` Jarkko Sakkinen
2026-11-12 14:03 ` Jarkko Sakkinen [this message]
2026-11-12 15:45 ` Breno Leitao
2026-11-12 20:40 ` Breno Leitao
2026-11-12 21:07 ` Jarkko Sakkinen
2026-11-12 21:16 ` Jarkko Sakkinen
2026-11-12 12:30 ` [PATCH v2 2/2] tpm: Disable TPM on TPM_RC_INITIALIZE Breno Leitao
2026-11-12 13:37 ` Jarkko Sakkinen
2026-11-12 22:57 ` David Laight
2026-11-12 23:31 ` Jarkko Sakkinen
2026-11-12 23:39 ` Jarkko Sakkinen
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=avXHGmmdY-CVgxEf@kernel.org \
--to=jarkko@kernel.org \
--cc=jgg@ziepe.ca \
--cc=kernel-team@meta.com \
--cc=leitao@debian.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=noodles@meta.com \
--cc=peterhuewe@gmx.de \
--cc=surenkj@amazon.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.