From nobody Sun Oct 11 01:10:37 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 4j2MwY6XbCz6w8p2 for ; Sun, 11 Oct 2026 01:10:37 +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 4j2MwY5Jlpz3Ktk for ; Sun, 11 Oct 2026 01:10:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791681037; 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=UMha8vYIB2spEUbL7Pvsh8szLJ+bGX9MmoD97LVL0t0=; b=n3KfVnCVQl93qGNmv0fJwjzVf3fwZIqGC76okcvAvcB9YWlVRPD3IqmNCfQmk/DLr4Tw1s teTunzy6HlC4UMapjYtinkvtrUfNVfL0fw4iNYiO5sn86HQmPJQ6PkqU7YFeR40Q3WvcLc alWiirV3PIy2jicf9xaSZFwlrPo6xYLfiwYj3DbvzhW3PmBewXITX499ZIClrCynW00UxW 7KiBAsaU382H3ltWYi6I9601NTCVnMDOEyHyX9m372q/GW5wgtx41R/67Ai14xCd3TV7Xp M3zH/E7LgQGea8MCMj/+epHiNivVnGjXJFoWeXBCu4d7hYECySaBvrvAU2Y/Ow== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791681037; b=RqyS0Qi0DBfQrqz4SAEwFo/yQEDMvtORLbSmklZHvhvMea2o6ZPELw3KecH7srC0Sowtfu jY3mzdpDaIpcyRrceeYFv5tKckERWvCV3u08WSf9qmN+qDmd0MIuEAsF5nw/ozHbitSxwX GYgj1IPLgtvrw00Qh1CUbMwsTqx74p9neZQKeC3O/HkTCzlpPwL1CGfEoJ6Fmpy23V5oZT H4MLRtviR4SQ3Pa3WiFeRC7rK1WaPMaIcY5gxWyh5QNDtvVsAS/k9y8bnBMEc0vARWiqfb VUByjAtKoof/Fg3vws3xZ2fLhY4G2QyQNlJemZ56kC8w2j1hLmBTCuXDKkogLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791681037; 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=UMha8vYIB2spEUbL7Pvsh8szLJ+bGX9MmoD97LVL0t0=; b=YAFNhZTpRm4La3TTCo/+qJ4DTJoSc/NrW90dz53C0fn0cbQa3RApfAfPw534txyMvjr6Rg XtXZeDJgdj6aysPgtyTOVbduh/ER5zaTLdIY5JHpY/3aBM88UNJcE1YywXq0q9+L5sedBC RvI3pO2WZoPS3kCn1GjgxqYEwN2RJA6ju+HwZ1qt750I/sroxcFbEHQmVmOPkKD+47Uo0o 9C+ePB3xToMAMSYG1AiLsek+fGAg9vxVTgvFWncTU99TfsvgwAauN/H6urW53/hxFqn9ow N/IjrLh8KxwRVac7cbgYXlBY5gTFzF90b64ZyjpN2t1XuI5WcYSzNDbJJd9PeA== 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 4j2MwY4MsZzJRD for ; Sun, 11 Oct 2026 01:10:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 35c4a by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 11 Oct 2026 01:10:37 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 606ce72478b7 - stable/15 - tpm20: Move user copies outside the lifecycle lock 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: 606ce72478b7f18aebc23df83e34f126b595623a Auto-Submitted: auto-generated Date: Sun, 11 Oct 2026 01:10:37 +0000 Message-Id: <6acae20d.35c4a.7767686e@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=606ce72478b7f18aebc23df83e34f126b595623a commit 606ce72478b7f18aebc23df83e34f126b595623a Author: Kevin Bowling AuthorDate: 2026-08-27 14:06:55 +0000 Commit: Kevin Bowling CommitDate: 2026-10-11 01:10:27 +0000 tpm20: Move user copies outside the lifecycle lock The TPM 2.0 character-device methods held the global device lock while uiomove() accessed user memory. User page faults could therefore delay suspend or detach even though the read response was already buffered. Add a per-open sleepable lock to serialize operations on each response buffer. Stage commands under that lock before acquiring the device lock, and copy them into the response buffer only after the lifecycle checks succeed. This preserves an unread response when suspend or detach rejects a write. Release the device lock before copying buffered responses out. Also advance the response offset by the bytes actually copied when uiomove() returns after a partial transfer. Validated on an Intel TPM 2.0 TIS device. PCR reads and GetRandom passed under 16-process mixed command load. A response was consumed correctly in 5-byte, 7-byte, and remainder reads. Module unload/reload recreated the device and entropy source without lock diagnostics. Source inspection confirmed rejected writes preserve unread responses. Reviewed by: kevans Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D59245 (cherry picked from commit 74c539fd1cefdbc993411274c613434c3f23b4b1) --- sys/dev/tpm/tpm20.c | 37 +++++++++++++++++++++++++++++-------- sys/dev/tpm/tpm20.h | 1 + 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c index bebf0af400fa..6c96f1ce848d 100644 --- a/sys/dev/tpm/tpm20.c +++ b/sys/dev/tpm/tpm20.c @@ -86,6 +86,7 @@ tpm20_read(struct cdev *dev, struct uio *uio, int flags) struct tpm_priv *priv; size_t bytes_to_transfer; size_t offset; + ssize_t resid; int result; sc = (struct tpm_sc *)dev->si_drv1; @@ -93,27 +94,36 @@ tpm20_read(struct cdev *dev, struct uio *uio, int flags) if (result != 0) return (result); + sx_xlock(&priv->io_lock); sx_xlock(&sc->dev_lock); if (atomic_load_bool(&sc->dying)) { result = ENXIO; - goto out; + goto out_locked; } if (sc->suspended) { result = EBUSY; - goto out; + goto out_locked; } offset = priv->offset; bytes_to_transfer = MIN(priv->len, uio->uio_resid); + sx_xunlock(&sc->dev_lock); + if (bytes_to_transfer > 0) { - result = uiomove((caddr_t) priv->buf + offset, bytes_to_transfer, uio); + resid = uio->uio_resid; + result = uiomove((caddr_t)priv->buf + offset, + (int)bytes_to_transfer, uio); + bytes_to_transfer = resid - uio->uio_resid; priv->offset += bytes_to_transfer; priv->len -= bytes_to_transfer; } else { result = 0; } + sx_xunlock(&priv->io_lock); + return (result); -out: +out_locked: sx_xunlock(&sc->dev_lock); + sx_xunlock(&priv->io_lock); return (result); } @@ -122,6 +132,7 @@ tpm20_write(struct cdev *dev, struct uio *uio, int flags) { struct tpm_sc *sc; struct tpm_priv *priv; + uint8_t *command; size_t byte_count; int result; @@ -143,6 +154,12 @@ tpm20_write(struct cdev *dev, struct uio *uio, int flags) return (E2BIG); } + command = malloc(byte_count, M_TPM20, M_WAITOK); + sx_xlock(&priv->io_lock); + result = uiomove(command, byte_count, uio); + if (result != 0) + goto out_priv; + sx_xlock(&sc->dev_lock); if (atomic_load_bool(&sc->dying)) { result = ENXIO; @@ -153,14 +170,16 @@ tpm20_write(struct cdev *dev, struct uio *uio, int flags) goto out; } - result = uiomove(priv->buf, byte_count, uio); - if (result != 0) - goto out; - + memcpy(priv->buf, command, byte_count); result = TPM_TRANSMIT(sc->dev, priv, byte_count); out: sx_xunlock(&sc->dev_lock); + if (result != 0) + uio->uio_resid = byte_count; +out_priv: + sx_xunlock(&priv->io_lock); + free(command, M_TPM20); return (result); } @@ -170,6 +189,7 @@ tpm20_priv_alloc(void) struct tpm_priv *priv; priv = malloc(sizeof (*priv), M_TPM20, M_WAITOK | M_ZERO); + sx_init(&priv->io_lock, "TPM per-open I/O lock"); return (priv); } @@ -178,6 +198,7 @@ tpm20_priv_dtor(void *data) { struct tpm_priv *priv = data; + sx_destroy(&priv->io_lock); free(priv, M_TPM20); } diff --git a/sys/dev/tpm/tpm20.h b/sys/dev/tpm/tpm20.h index 1d7a11265b02..f210cd84c331 100644 --- a/sys/dev/tpm/tpm20.h +++ b/sys/dev/tpm/tpm20.h @@ -110,6 +110,7 @@ MALLOC_DECLARE(M_TPM20); struct tpm_priv { + struct sx io_lock; uint8_t buf[TPM_BUFSIZE]; size_t offset; size_t len;