git: bf62832039d7 - stable/15 - tpm: crb: check the error bit only after taking locality
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 11 Oct 2026 01:18:13 UTC
The branch stable/15 has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=bf62832039d7e72cbbd64ba94c2a80da340f2e83
commit bf62832039d7e72cbbd64ba94c2a80da340f2e83
Author: Olivier Cochard <olivier@FreeBSD.org>
AuthorDate: 2026-09-14 14:21:11 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-10-11 01:17:59 +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
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59661
(cherry picked from commit 7c375af72ef3f631e89431ae32a855d806e6ec98)
---
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);