git: 7c375af72ef3 - main - tpm: crb: check the error bit only after taking locality
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 14 Sep 2026 14:28:44 UTC
The branch main has been updated by olivier:
URL: https://cgit.FreeBSD.org/src/commit/?id=7c375af72ef3f631e89431ae32a855d806e6ec98
commit 7c375af72ef3f631e89431ae32a855d806e6ec98
Author: Olivier Cochard <olivier@FreeBSD.org>
AuthorDate: 2026-09-14 14:21:11 +0000
Commit: Olivier Cochard <olivier@FreeBSD.org>
CommitDate: 2026-09-14 14:25:47 +0000
tpm: crb: check the error bit only after taking locality
tpmcrb_transmit() read CRB_CTRL_STS before requesting locality 0.
An AMD Pluton fTPM (like FrameWork Desktop) using the plain CRB start method
reads the control area as all-ones until locality is assigned, so bit 0 looks
like a stuck tpmSts and every command failed with EIO.
With RANDOM_ENABLE_TPM the harvester retries every 10 seconds, so this printed
"Device has Error bit set" forever.
Reviewed by: kbowling
Approved by: kbowling
MFC after: 2 weeks
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59661
---
sys/dev/tpm/tpm_crb.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c
index e5bbec5d46da..f62d350948c8 100644
--- a/sys/dev/tpm/tpm_crb.c
+++ b/sys/dev/tpm/tpm_crb.c
@@ -514,17 +514,25 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length)
return (E2BIG);
}
- if (TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
- device_printf(dev,
- "Device has Error bit set\n");
- return (EIO);
- }
if (!tpmcrb_request_locality(sc, 0)) {
device_printf(dev,
"Failed to obtain locality\n");
return (EIO);
}
locality = true;
+
+ /*
+ * Only check for the error once we own the locality: some
+ * implementations do not return meaningful values in the control area
+ * before then. An AMD Pluton fTPM using the plain CRB start method
+ * reads all-ones, which looks like a permanently stuck tpmSts.
+ */
+ if (TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
+ device_printf(dev,
+ "Device has Error bit set\n");
+ error = EIO;
+ goto out;
+ }
/* Clear cancellation bit */
TPM_WRITE_4(dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);