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 *);