From a3f4d28273dabad5383b760ed29bd4aed16c51af Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Wed, 12 Mar 2025 07:31:57 +0200 Subject: [PATCH] tpm, tpm_tis: Fix timeout handling when waiting for TPM status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7146dffa875cd00e7a7f918e1fce79c7593ac1fa upstream. The change to only use interrupts to handle supported status changes introduced an issue when it is necessary to poll for the status. Rather than checking for the status after sleeping the code now sleeps after the check. This means a correct, but slower, status change on the part of the TPM can be missed, resulting in a spurious timeout error, especially on a more loaded system. Switch back to sleeping *then* checking. An up front check of the status has been done at the start of the function, so this does not cause an additional delay when the status is already what we're looking for. Cc: stable@vger.kernel.org # v6.4+ Fixes: e87fcf0dc2b4 ("tpm, tpm_tis: Only handle supported interrupts") Signed-off-by: Jonathan McDowell Reviewed-by: Michal Suchánek Reviewed-by: Lino Sanfilippo Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm_tis_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 4e294a915925..caf9ba2dc0b1 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -104,11 +104,10 @@ again: return 0; /* process status changes without irq support */ do { + usleep_range(priv->timeout_min, priv->timeout_max); status = chip->ops->status(chip); if ((status & mask) == mask) return 0; - usleep_range(priv->timeout_min, - priv->timeout_max); } while (time_before(jiffies, stop)); return -ETIME; }