Module Name:    src
Committed By:   riastradh
Date:           Mon Dec 20 23:05:55 UTC 2021

Modified Files:
        src/sys/dev/ic: tpm.c tpmvar.h

Log Message:
tpm(4): Fix disabling of rnd source if tpm is deactivated.

Nothing prevents a second worker from being queued when the first one
is about to do rnd_detach_source.  Instead, just set a flag so future
requests don't bother running a new thread; if there's a concurrent
one that's already been scheduled on another CPU, well, too bad, we
get a couple extra log messages but that's fine.

A better way to do this would probably be to detect whether the tpm
is deactivated at attach time, but that requires reading more of the
tpm spec than I care to do when there are alternative ways to
procrastinate like scrubbing the toilet.


To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/ic/tpm.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/ic/tpmvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/tpm.c
diff -u src/sys/dev/ic/tpm.c:1.22 src/sys/dev/ic/tpm.c:1.23
--- src/sys/dev/ic/tpm.c:1.22	Wed Jun  2 21:35:17 2021
+++ src/sys/dev/ic/tpm.c	Mon Dec 20 23:05:55 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: tpm.c,v 1.22 2021/06/02 21:35:17 riastradh Exp $	*/
+/*	$NetBSD: tpm.c,v 1.23 2021/12/20 23:05:55 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.22 2021/06/02 21:35:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.23 2021/12/20 23:05:55 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -650,7 +650,7 @@ tpm_rng_work(struct work *wk, void *cook
 	 */
 	if (rv) {
 		device_printf(sc->sc_dev, "deactivating entropy source\n");
-		rnd_detach_source(&sc->sc_rnd);
+		atomic_store_relaxed(&sc->sc_rnddisabled, true);
 		/* XXX worker thread can't workqueue_destroy its own queue */
 	}
 
@@ -666,6 +666,8 @@ tpm_rng_get(size_t nbytes, void *cookie)
 {
 	struct tpm_softc *sc = cookie;
 
+	if (atomic_load_relaxed(&sc->sc_rnddisabled))
+		return;		/* tough */
 	if (atomic_swap_uint(&sc->sc_rndpending, MIN(nbytes, UINT_MAX/NBBY))
 	    == 0)
 		workqueue_enqueue(sc->sc_rndwq, &sc->sc_rndwk, NULL);

Index: src/sys/dev/ic/tpmvar.h
diff -u src/sys/dev/ic/tpmvar.h:1.9 src/sys/dev/ic/tpmvar.h:1.10
--- src/sys/dev/ic/tpmvar.h:1.9	Mon Jan  4 18:26:59 2021
+++ src/sys/dev/ic/tpmvar.h	Mon Dec 20 23:05:55 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: tpmvar.h,v 1.9 2021/01/04 18:26:59 riastradh Exp $	*/
+/*	$NetBSD: tpmvar.h,v 1.10 2021/12/20 23:05:55 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -98,6 +98,7 @@ struct tpm_softc {
 	struct workqueue *sc_rndwq;
 	struct work sc_rndwk;
 	volatile unsigned sc_rndpending;
+	bool sc_rnddisabled;
 };
 
 bool tpm_suspend(device_t, const pmf_qual_t *);

Reply via email to