]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
tpm, tpm_tis: Fix timeout handling when waiting for TPM status
authorJonathan McDowell <noodles@meta.com>
Wed, 12 Mar 2025 05:31:57 +0000 (07:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Apr 2025 08:45:23 +0000 (10:45 +0200)
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 <noodles@meta.com>
Reviewed-by: Michal Suchánek <msuchanek@suse.de>
Reviewed-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/tpm/tpm_tis_core.c

index 7ade8bd12ab26834d3bae83d28b2f4cd2fca8738..c71e61ccb95a2bd7903d3a7bf84a594128c46ae5 100644 (file)
@@ -114,11 +114,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;
 }