Re: [PATCH v2] tpm_tis: work around status register bug in STMicroelectronics TPM

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Omar,


Am 16.04.20 um 02:23 schrieb Omar Sandoval:
From: Omar Sandoval <osandov@xxxxxx>

Thank you for the patch.

We've encountered a particular model of STMicroelectronics TPM that

Please add models you are encountering this with to the commit message.

transiently returns a bad value in the status register. This causes the

Have you contacted STMMicroelectronics?

kernel to believe that the TPM is ready to receive a command when it
actually isn't, which in turn causes the send to time out in
get_burstcount(). In testing, reading the status register one extra time
convinces the TPM to return a valid value.

Signed-off-by: Omar Sandoval <osandov@xxxxxx>
---
  drivers/char/tpm/tpm_tis_core.c | 19 +++++++++++++++++++
  1 file changed, 19 insertions(+)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 27c6ca031e23..5a2f6acaf768 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -238,6 +238,25 @@ static u8 tpm_tis_status(struct tpm_chip *chip)
  	rc = tpm_tis_read8(priv, TPM_STS(priv->locality), &status);
  	if (rc < 0)
  		return 0;
+	/*
+	 * Some STMicroelectronics TPMs have a bug where the status register is
+	 * sometimes bogus (all 1s) if read immediately after the access
+	 * register is written to. Bits 0, 1, and 5 are always supposed to read
+	 * as 0, so this is clearly invalid. Reading the register a second time
+	 * returns a valid value.
+	 */
+	if (unlikely(status == 0xff)) {

I’d like to see a debug message here, saying the TPM is buggy. Maybe the model can be printed to, and that the TPM manufacturer should be contacted.

+		rc = tpm_tis_read8(priv, TPM_STS(priv->locality), &status);
+		if (rc < 0)
+			return 0;
+		/*
+		 * The status is somehow still bad. This hasn't been observed in
+		 * practice, but clear it just in case so that it doesn't appear
+		 * to be ready.
+		 */
+		if (unlikely(status == 0xff))
+			status = 0;
+	}
return status;
  }


Kind regards,

Paul



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux