git: 084f245a8514 - main - tpm: Tie exclusive-open cleanup to the file lifetime
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 30 Oct 2026 22:04:32 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=084f245a8514e89a506e43efd1a7ed44ffdbb5eb
commit 084f245a8514e89a506e43efd1a7ed44ffdbb5eb
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-09-18 12:16:54 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-10-30 22:03:58 +0000
tpm: Tie exclusive-open cleanup to the file lifetime
Use a cdevpriv destructor to abort an unfinished TPM 1.2 transaction and
release exclusive-open ownership. Register it before setting TPM_OPEN so
a failed registration leaves the device available. The last reference to
the successful open triggers cleanup, including after dup() or fork().
Suggested by: kevans
MFC after: 2 weeks
Sponsored by: BBOX.io
Differential Revision: https://reviews.freebsd.org/D59812
---
sys/dev/tpm/tpm.c | 34 ++++++++++++----------------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/sys/dev/tpm/tpm.c b/sys/dev/tpm/tpm.c
index 2880c69cf85c..42c31ba75518 100644
--- a/sys/dev/tpm/tpm.c
+++ b/sys/dev/tpm/tpm.c
@@ -139,15 +139,14 @@ int tpm_enabled;
((struct tpm_softc *)dev->si_drv1)
d_open_t tpmopen;
-d_close_t tpmclose;
d_read_t tpmread;
d_write_t tpmwrite;
d_ioctl_t tpmioctl;
+static d_priv_dtor_t tpm_dtor;
static struct cdevsw tpm_cdevsw = {
.d_version = D_VERSION,
.d_open = tpmopen,
- .d_close = tpmclose,
.d_read = tpmread,
.d_write = tpmwrite,
.d_ioctl = tpmioctl,
@@ -404,7 +403,8 @@ tpm_detach(device_t dev)
/*
* Prevent new methods from touching the transport. Do not hold the
- * lock while destroy_dev() drains methods already waiting for it.
+ * lock while destroy_dev() drains methods and cdevpriv destructors
+ * which also acquire it.
*/
if (sc->sc_cdev != NULL) {
destroy_dev(sc->sc_cdev);
@@ -1659,36 +1659,26 @@ tpmopen(struct cdev *dev, int flag, int mode, struct thread *td)
else if (sc->sc_suspend != 0 || (sc->sc_flags & TPM_OPEN) != 0)
error = EBUSY;
else {
- sc->sc_flags |= TPM_OPEN;
- error = 0;
+ error = devfs_set_cdevpriv(sc, tpm_dtor);
+ if (error == 0)
+ sc->sc_flags |= TPM_OPEN;
}
sx_xunlock(&sc->sc_lock);
return (error);
}
-int
-tpmclose(struct cdev *dev, int flag, int mode, struct thread *td)
+static void
+tpm_dtor(void *arg)
{
struct tpm_softc *sc;
- int error;
-
- sc = TPMSOFTC(dev);
- if (sc == NULL)
- return (ENXIO);
+ sc = arg;
sx_xlock(&sc->sc_lock);
- if ((sc->sc_flags & TPM_OPEN) == 0)
- error = EINVAL;
- else {
- if (sc->sc_init == tpm_tis12_init)
- tpm_tis12_abort(sc);
- sc->sc_flags &= ~TPM_OPEN;
- error = 0;
- }
+ if (sc->sc_init == tpm_tis12_init)
+ tpm_tis12_abort(sc);
+ sc->sc_flags &= ~TPM_OPEN;
sx_xunlock(&sc->sc_lock);
-
- return (error);
}
int