Commit 0178f9d0 authored by Jarkko Sakkinen's avatar Jarkko Sakkinen
Browse files

tpm: Replace WARN_ONCE() with dev_err_once() in tpm_tis_status()

Do not tear down the system when getting invalid status from a TPM chip.
This can happen when panic-on-warn is used.

Instead, introduce TPM_TIS_INVALID_STATUS bitflag and use it to trigger
once the error reporting per chip. In addition, print out the value of
TPM_STS for improved forensics.

Link: https://lore.kernel.org/keyrings/YKzlTR1AzUigShtZ@kroah.com/


Fixes: 55707d53 ("tpm_tis: Add a check for invalid status")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5a118a39
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -196,13 +196,24 @@ static u8 tpm_tis_status(struct tpm_chip *chip)
		return 0;

	if (unlikely((status & TPM_STS_READ_ZERO) != 0)) {
		if  (!test_and_set_bit(TPM_TIS_INVALID_STATUS, &priv->flags)) {
			/*
			 * If this trips, the chances are the read is
			 * returning 0xff because the locality hasn't been
			 * acquired.  Usually because tpm_try_get_ops() hasn't
			 * been called before doing a TPM operation.
			 */
		WARN_ONCE(1, "TPM returned invalid status\n");
			dev_err(&chip->dev, "invalid TPM_STS.x 0x%02x, dumping stack for forensics\n",
				status);

			/*
			 * Dump stack for forensics, as invalid TPM_STS.x could be
			 * potentially triggered by impaired tpm_try_get_ops() or
			 * tpm_find_get_ops().
			 */
			dump_stack();
		}

		return 0;
	}

+2 −1
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ enum tis_defaults {

enum tpm_tis_flags {
	TPM_TIS_ITPM_WORKAROUND		= BIT(0),
	TPM_TIS_INVALID_STATUS		= BIT(1),
};

struct tpm_tis_data {
@@ -90,7 +91,7 @@ struct tpm_tis_data {
	int locality;
	int irq;
	bool irq_tested;
	unsigned int flags;
	unsigned long flags;
	void __iomem *ilb_base_addr;
	u16 clkrun_enabled;
	wait_queue_head_t int_queue;