tpm: Fix entropy harvesting logic

Use a taskqueue instead of a callout.
Callout functions mustn't sleep, where as the TPM driver
uses a sx lock in order to serialize accesses to the device.
Since the entropy harvesting feature is not enabled by default,
this commit should not bring any functional changes to the GENERIC
kernel.

Approved by:	mw(mentor)
Sponsored by:	Stormshield
Obtained from:	Semihalf
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D36412
This commit is contained in:
Kornel Dulęba 2022-09-02 13:07:03 +02:00
parent 2486b446db
commit e23ad9c4ba
2 changed files with 15 additions and 13 deletions

View File

@ -39,13 +39,13 @@ __FBSDID("$FreeBSD$");
* we don't want to execute this too often
* as the chip is likely to be used by others too.
*/
#define TPM_HARVEST_INTERVAL 10000000
#define TPM_HARVEST_INTERVAL 10
MALLOC_DEFINE(M_TPM20, "tpm_buffer", "buffer for tpm 2.0 driver");
static void tpm20_discard_buffer(void *arg);
#ifdef TPM_HARVEST
static void tpm20_harvest(void *arg);
static void tpm20_harvest(void *arg, int unused);
#endif
static int tpm20_save_state(device_t dev, bool suspend);
@ -192,11 +192,6 @@ tpm20_init(struct tpm_sc *sc)
cv_init(&sc->buf_cv, "TPM buffer cv");
callout_init(&sc->discard_buffer_callout, 1);
#ifdef TPM_HARVEST
sc->harvest_ticks = TPM_HARVEST_INTERVAL / tick;
callout_init(&sc->harvest_callout, 1);
callout_reset(&sc->harvest_callout, 0, tpm20_harvest, sc);
#endif
sc->pending_data_length = 0;
make_dev_args_init(&args);
@ -209,6 +204,12 @@ tpm20_init(struct tpm_sc *sc)
if (result != 0)
tpm20_release(sc);
#ifdef TPM_HARVEST
TIMEOUT_TASK_INIT(taskqueue_thread, &sc->harvest_task, 0,
tpm20_harvest, sc);
taskqueue_enqueue_timeout(taskqueue_thread, &sc->harvest_task, 0);
#endif
return (result);
}
@ -218,7 +219,8 @@ tpm20_release(struct tpm_sc *sc)
{
#ifdef TPM_HARVEST
callout_drain(&sc->harvest_callout);
if (device_is_attached(sc->dev))
taskqueue_drain_timeout(taskqueue_thread, &sc->harvest_task);
#endif
if (sc->buf != NULL)
@ -243,13 +245,12 @@ tpm20_shutdown(device_t dev)
}
#ifdef TPM_HARVEST
/*
* Get TPM_HARVEST_SIZE random bytes and add them
* into system entropy pool.
*/
static void
tpm20_harvest(void *arg)
tpm20_harvest(void *arg, int unused)
{
struct tpm_sc *sc;
unsigned char entropy[TPM_HARVEST_SIZE];
@ -290,7 +291,8 @@ tpm20_harvest(void *arg)
if (entropy_size > 0)
random_harvest_queue(entropy, entropy_size, RANDOM_PURE_TPM);
callout_reset(&sc->harvest_callout, sc->harvest_ticks, tpm20_harvest, sc);
taskqueue_enqueue_timeout(taskqueue_thread, &sc->harvest_task,
hz * TPM_HARVEST_INTERVAL);
}
#endif /* TPM_HARVEST */

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/sx.h>
#include <sys/taskqueue.h>
#include <sys/uio.h>
#include <machine/bus.h>
@ -125,8 +126,7 @@ struct tpm_sc {
struct callout discard_buffer_callout;
#ifdef TPM_HARVEST
struct callout harvest_callout;
int harvest_ticks;
struct timeout_task harvest_task;
#endif
int (*transmit)(struct tpm_sc *, size_t);