From nobody Sun Oct 11 01:10:01 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4j2Mvs4NZDz6w8g6 for ; Sun, 11 Oct 2026 01:10:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j2Mvs36wbz3Jlk for ; Sun, 11 Oct 2026 01:10:01 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791681001; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=NpJ8hbKeAVzb/5rpnId/dyxw2xV49/Pbc0AjwjOA5M0=; b=cA94M/xU2NzihvUsPRVDQ/2CC2mFkIL6MztYTtb6k/7DqYJAHps0fEmFYNE/PcaJFbh9jT gabsVJ9VTBTKbBRQTph9U2O/zc+ZS/OzIhfiwmpjOJXn9nq+9DvZnnP35uMi8YMhQ4cVdP MOIXdxmavG+6geKTFVmiYB5M2oyv9ikJ41RMyYeP2KSpRLz8MU8HBr6UH63NU8G/r64bK5 krWSePOd0BCibb+t0KooxuUGuOZVGphq1OFIjZVN9BopnEPU6k6EjkMOXjIrDmJkbpzUyg L6Wv5zir1juUDzdFJvLhXwg4C0rvBCyGazOG0mbKpcWMduN38ayt86Rs8hvAmg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791681001; b=oEmqeZgfXKogq34xppJ8DndPoJ02MGXtiyEP3W1sZFOY0xerhP21qEC0uTH4CK8KkJr2Vp SsVbfVOTo+w3WKEwfBY2EBowbPrHBkmRrqws/2UrDlJa1DAqengHDT0Fac1jGrRVF38jLL GF81fu7Gta5Ql5O6x12+IlbLyXw/uvdjP/HhvKfz3HFT4GrHJyaz7b4ZVs3k4fxRTFkLt7 cK/O8vZVHn+1z/ZzEXZakaEP/vp+SFpVB1wj031mArXqxBleCLxKeHIN1ZqAx54UcV1M2V SuCt8asKhLRs5Dy3BKZ2MZXwbOQwTgmRTOxztlUiUymk1RXcUa/s76V2FbeCFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791681001; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=NpJ8hbKeAVzb/5rpnId/dyxw2xV49/Pbc0AjwjOA5M0=; b=RzGU3IPnZvGjDmu4tYYhQAj57q5k6HYRRFZvS/+vQmdxnfTxBORbteXuJRb/ZXegd/IMRH OHwT19VR44fMRwotpxZwqHQZ/dJutAQhl6SGdT08RrYiG0nqqyfkDuSDI2ppRwcHr5cY+c qe0N9dCQhHzSxP7tdT4hARvJRknuJ7nreU/Or+5hqJcsKWNvdFDzRri4YpXXR4PfTC06rg Jb9dOfeYtolWV4s1xvbvHm5E0CK68pqcKEpE1YHoPWg18uH+kiSha9UCjnAtKx8128kNny dc6GC+nYvBDVEZ/nHyX5JNNpHERecbc596rFezflxwzF5NWYnb9uqpigexa6Mg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j2Mvs2Bc0zJcs for ; Sun, 11 Oct 2026 01:10:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 34413 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 11 Oct 2026 01:10:01 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 3904c7a1c489 - stable/15 - tpm20: Release transport state after command failures List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 3904c7a1c489a419c4691b7a58d2d1e2a3e71d53 Auto-Submitted: auto-generated Date: Sun, 11 Oct 2026 01:10:01 +0000 Message-Id: <6acae1e9.34413.2a46198b@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=3904c7a1c489a419c4691b7a58d2d1e2a3e71d53 commit 3904c7a1c489a419c4691b7a58d2d1e2a3e71d53 Author: Kevin Bowling AuthorDate: 2026-08-27 12:48:05 +0000 Commit: Kevin Bowling CommitDate: 2026-10-11 01:09:50 +0000 tpm20: Release transport state after command failures Once a transport acquires locality, several TIS and CRB error paths return without relinquishing it. They can also leave a partial FIFO transaction or an active CRB command for the next operation to inherit. Route post-locality exits through common cleanup. Reset the TIS command state on every attempt. For CRB, cancel an active failed command when necessary, request the idle state, and relinquish locality even when the state transition itself fails. Successful command handling is unchanged apart from sharing the same cleanup path. Reviewed by: kevans Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D59243 (cherry picked from commit 2fe8510b0a06ad577789ece7be8c9319c8ce3d06) --- sys/dev/tpm/tpm_crb.c | 57 ++++++++++++++++++++++++++--------------- sys/dev/tpm/tpm_tis_core.c | 63 +++++++++++++++++++++++++++++----------------- 2 files changed, 77 insertions(+), 43 deletions(-) diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c index ac093c3857ba..3e567e215313 100644 --- a/sys/dev/tpm/tpm_crb.c +++ b/sys/dev/tpm/tpm_crb.c @@ -484,12 +484,15 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length) struct tpmcrb_sc *crb_sc; struct tpm_sc *sc; uint32_t mask, curr_cmd; - int timeout, bytes_available; + int bytes_available, error, timeout; + bool command_started, locality; crb_sc = device_get_softc(dev); sc = &crb_sc->base; sx_assert(&sc->dev_lock, SA_XLOCKED); + command_started = false; + locality = false; if (length > crb_sc->cmd_buf_size) { device_printf(dev, @@ -507,6 +510,7 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length) "Failed to obtain locality\n"); return (EIO); } + locality = true; /* Clear cancellation bit */ TPM_WRITE_4(dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR); @@ -515,7 +519,8 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length) if (!tpmcrb_state_idle(crb_sc, true)) { device_printf(dev, "Failed to transition to idle state\n"); - return (EIO); + error = EIO; + goto out; } } @@ -523,7 +528,8 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length) if (!tpmcrb_state_ready(crb_sc, true)) { device_printf(dev, "Failed to transition to ready state\n"); - return (EIO); + error = EIO; + goto out; } /* @@ -540,20 +546,25 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length) TPM_WRITE_4(dev, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD); TPM_WRITE_BARRIER(dev, TPM_CRB_CTRL_START, 4); + command_started = true; if (!tpmcrb_notify_cmdready(crb_sc, timeout)) { device_printf(dev, "Timeout while waiting for device to ready\n"); - if (!tpmcrb_cancel_cmd(sc)) - return (EIO); + if (!tpmcrb_cancel_cmd(sc)) { + error = EIO; + goto out; + } } mask = ~0; if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START, mask, ~mask, timeout)) { device_printf(dev, "Timeout while waiting for device to process cmd\n"); - if (!tpmcrb_cancel_cmd(sc)) - return (EIO); + if (!tpmcrb_cancel_cmd(sc)) { + error = EIO; + goto out; + } } /* Read response header. Length is passed in bytes 2 - 6. */ @@ -565,27 +576,33 @@ tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length) device_printf(dev, "Incorrect response size: %d\n", bytes_available); - return (EIO); + error = EIO; + goto out; } bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE, &priv->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE); - /* - * No need to wait for the transition to idle on the way out, we can - * relinquish locality right away. - */ - if (!tpmcrb_state_idle(crb_sc, false)) { - device_printf(dev, - "Failed to transition to idle state post-send\n"); - return (EIO); - } - - tpmcrb_relinquish_locality(sc); priv->offset = 0; priv->len = bytes_available; + error = 0; + +out: + if (locality) { + if (error != 0 && command_started && + (TPM_READ_4(dev, TPM_CRB_CTRL_START) & + TPM_CRB_CTRL_START_CMD) != 0) + (void)tpmcrb_cancel_cmd(sc); + if (!tpmcrb_state_idle(crb_sc, false)) { + device_printf(dev, + "Failed to transition to idle state post-send\n"); + if (error == 0) + error = EIO; + } + tpmcrb_relinquish_locality(sc); + } - return (0); + return (error); } /* StartMethod Implementation Details */ diff --git a/sys/dev/tpm/tpm_tis_core.c b/sys/dev/tpm/tpm_tis_core.c index 08d37ebcfe19..785c887e58cf 100644 --- a/sys/dev/tpm/tpm_tis_core.c +++ b/sys/dev/tpm/tpm_tis_core.c @@ -487,25 +487,30 @@ tpmtis_transmit(device_t dev, struct tpm_priv *priv, size_t length) struct tpm_sc *sc; size_t bytes_available; uint32_t mask, curr_cmd; - int timeout; + int error, timeout; + bool locality; sc = device_get_softc(dev); sx_assert(&sc->dev_lock, SA_XLOCKED); + locality = false; if (!tpmtis_request_locality(sc, 0)) { device_printf(dev, "Failed to obtain locality\n"); return (EIO); } + locality = true; if (!tpmtis_go_ready(sc)) { device_printf(dev, "Failed to switch to ready state\n"); - return (EIO); + error = EIO; + goto out; } if (!tpmtis_write_bytes(sc, length, priv->buf)) { device_printf(dev, "Failed to write cmd to device\n"); - return (EIO); + error = EIO; + goto out; } mask = TPM_STS_VALID; @@ -513,13 +518,15 @@ tpmtis_transmit(device_t dev, struct tpm_priv *priv, size_t length) TPM_INT_STS_VALID, true)) { device_printf(dev, "Timeout while waiting for valid bit\n"); - return (EIO); + error = EIO; + goto out; } if (TPM_READ_4(dev, TPM_STS) & TPM_STS_DATA_EXPECTED) { device_printf(dev, "Device expects more data even though we already" " sent everything we had\n"); - return (EIO); + error = EIO; + goto out; } /* @@ -541,22 +548,27 @@ tpmtis_transmit(device_t dev, struct tpm_priv *priv, size_t length) * Switching to ready state also cancels processing * current command */ - if (!tpmtis_go_ready(sc)) - return (EIO); + if (!tpmtis_go_ready(sc)) { + error = EIO; + goto out; + } /* * After canceling a command we should get a response, * check if there is one. */ if (!tpm_wait_for_reg(sc, TPM_STS, mask, mask, TPM_TIMEOUT_C, - TPM_INT_STS_DATA_AVAIL, true)) - return (EIO); + TPM_INT_STS_DATA_AVAIL, true)) { + error = EIO; + goto out; + } } /* Read response header. Length is passed in bytes 2 - 6. */ if (!tpmtis_read_bytes(sc, TPM_HEADER_SIZE, priv->buf)) { device_printf(dev, "Failed to read response header\n"); - return (EIO); + error = EIO; + goto out; } bytes_available = be32toh(*(uint32_t *) (&priv->buf[2])); @@ -564,29 +576,34 @@ tpmtis_transmit(device_t dev, struct tpm_priv *priv, size_t length) device_printf(dev, "Incorrect response size: %zu\n", bytes_available); - return (EIO); + error = EIO; + goto out; } if (!tpmtis_read_bytes(sc, bytes_available - TPM_HEADER_SIZE, &priv->buf[TPM_HEADER_SIZE])) { device_printf(dev, "Failed to read response\n"); - return (EIO); + error = EIO; + goto out; } + priv->offset = 0; + priv->len = bytes_available; + error = 0; +out: /* - * Per TIS 1.3 section 5.6.12, write commandReady after reading the - * response so the TPM can free the ReadFIFO and other internal - * resources. The next tpmtis_go_ready() provides the second - * write the spec mentions, and waits for the state transition, - * so no wait is needed here. + * Per TIS 1.3 section 5.6.12, write commandReady after every command + * attempt so the TPM can discard a partial FIFO transaction and free + * its internal resources. The next tpmtis_go_ready() provides the + * second write the spec mentions and waits for the state transition. */ - TPM_WRITE_4(sc->dev, TPM_STS, TPM_STS_CMD_RDY); - TPM_WRITE_BARRIER(sc->dev, TPM_STS, 4); - tpmtis_relinquish_locality(sc); - priv->offset = 0; - priv->len = bytes_available; + if (locality) { + TPM_WRITE_4(sc->dev, TPM_STS, TPM_STS_CMD_RDY); + TPM_WRITE_BARRIER(sc->dev, TPM_STS, 4); + tpmtis_relinquish_locality(sc); + } - return (0); + return (error); } /* ACPI Driver */