Skip to contentSkip to conversation

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

PATCH In review Jarkko Sakkinen 2 participants 2 messages Jun 9, 2021

Subsystems (3)
lore
Share & tools
lore

Jarkko Sakkinen

author maintainer
#0 lore raw

PATCH v3 1/1 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.

Fixes 55707d531af6 ("tpm_tis: Add a check for invalid status")
Cc Hans de Goede <[email protected]>
Cc Greg KH <[email protected]>

---

v3:
* torn -> tear
* A per chip flag TPM_TIS_INVALID_STATUS.

v2:
Dump also stack only once.

 drivers/char/tpm/tpm_tis_core.c | 25 ++++++++++++++++++-------
 drivers/char/tpm/tpm_tis_core.h |  3 ++-
 2 files changed, 20 insertions(+), 8 deletions(-)
drivers/char/tpm/tpm_tis_core.c +18 -7
index 55b9d3965ae1..69579efb247b 100644
@@ -196,13 +196,24 @@ static u8 tpm_tis_status(struct tpm_chip *chip)
 		return 0;
 
 	if (unlikely((status & TPM_STS_READ_ZERO) != 0)) {
-		/*
-		 * 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");
+		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.
+			 */
+			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;
 	}
 
drivers/char/tpm/tpm_tis_core.h +2 -1
index 9b2d32a59f67..b2a3c6c72882 100644
@@ -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;
Signature · 1 line
2.31.1
Reviewed-by Greg Kroah-Hartman on v3 1/1
#1 lore raw
Quoted 7 lines · Jarkko Sakkinen

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.

Quoted 7 lines
Fixes 55707d531af6 ("tpm_tis: Add a check for invalid status")
Cc Hans de Goede <[email protected]>
Cc Greg KH <[email protected]>

---