Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Convert the entropy pool framework from pseudo-callout-d...
details: https://anonhg.NetBSD.org/src/rev/40b566e5b1fb
branches: trunk
changeset: 787367:40b566e5b1fb
user: tls <tls%NetBSD.org@localhost>
date: Thu Jun 13 00:55:01 2013 +0000
description:
Convert the entropy pool framework from pseudo-callout-driven to
soft interrupt driven operation.
Add a polling mode of operation -- now we can ask hardware random number
generators to top us up just when we need it (bcm2835_rng and amdpm
converted as examples).
Fix a stall noticed with repeated reads from /dev/random while testing.
diffstat:
sys/arch/arm/broadcom/bcm2835_rng.c | 55 +++++---
sys/dev/pci/amdpm.c | 49 ++++++-
sys/dev/pci/amdpm_smbus.c | 6 +-
sys/dev/pci/amdpmvar.h | 3 +-
sys/dev/pci/hifn7751.c | 186 ++++++++++++++++++-----------
sys/dev/pci/hifn7751var.h | 5 +-
sys/dev/pci/ubsec.c | 103 +++++++++++----
sys/dev/pci/ubsecvar.h | 5 +-
sys/dev/rndpseudo.c | 30 +++-
sys/dev/scsipi/sd.c | 12 +-
sys/kern/kern_rndpool.c | 7 +-
sys/kern/kern_rndq.c | 226 ++++++++++++++++++++++++-----------
sys/kern/subr_cprng.c | 17 ++-
sys/sys/rnd.h | 13 +-
14 files changed, 491 insertions(+), 226 deletions(-)
diffs (truncated from 1765 to 300 lines):
diff -r d7719ddcf18d -r 40b566e5b1fb sys/arch/arm/broadcom/bcm2835_rng.c
--- a/sys/arch/arm/broadcom/bcm2835_rng.c Wed Jun 12 21:35:29 2013 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_rng.c Thu Jun 13 00:55:01 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_rng.c,v 1.3 2013/02/01 16:10:16 skrll Exp $ */
+/* $NetBSD: bcm2835_rng.c,v 1.4 2013/06/13 00:55:01 tls Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_rng.c,v 1.3 2013/02/01 16:10:16 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_rng.c,v 1.4 2013/06/13 00:55:01 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,6 +38,7 @@
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/rnd.h>
+#include <sys/atomic.h>
#include <arm/broadcom/bcm_amba.h>
#include <arm/broadcom/bcm2835reg.h>
@@ -59,16 +60,16 @@
bus_space_handle_t sc_ioh;
krndsource_t sc_rnd;
- callout_t sc_tick;
+
+ kmutex_t sc_mutex;
uint32_t sc_data[RNG_DATA_MAX];
};
+static void bcmrng_get(size_t, void *);
static int bcmrng_match(device_t, cfdata_t, void *);
static void bcmrng_attach(device_t, device_t, void *);
-static void bcmrng_tick(void *);
-
CFATTACH_DECL_NEW(bcmrng_amba, sizeof(struct bcm2835rng_softc),
bcmrng_match, bcmrng_attach, NULL, NULL);
@@ -103,11 +104,11 @@
return;
}
- rnd_attach_source(&sc->sc_rnd, device_xname(self), RND_TYPE_RNG,
- RND_FLAG_NO_ESTIMATE);
+ mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
- callout_init(&sc->sc_tick, CALLOUT_MPSAFE);
- callout_setfunc(&sc->sc_tick, bcmrng_tick, sc);
+ rndsource_setcb(&sc->sc_rnd, bcmrng_get, sc);
+ rnd_attach_source(&sc->sc_rnd, device_xname(self), RND_TYPE_RNG,
+ RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
/* discard initial numbers, broadcom says they are "less random" */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS, 0x40000);
@@ -116,26 +117,34 @@
ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL);
ctrl |= RNG_CTRL_EN;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL, ctrl);
-
- /* start timer */
- bcmrng_tick(sc);
}
static void
-bcmrng_tick(void *priv)
+bcmrng_get(size_t bytes, void *priv)
{
- struct bcm2835rng_softc *sc = priv;
+ struct bcm2835rng_softc *sc = priv;
uint32_t status;
- int cnt;
+ int need = bytes, cnt;
- status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS);
- cnt = (status & RNG_STATUS_CNT_MASK) >> RNG_STATUS_CNT_SHIFT;
- if (cnt > 0) {
- bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, RNG_DATA,
- sc->sc_data, cnt);
- rnd_add_data(&sc->sc_rnd, sc->sc_data,
- cnt * 4, cnt * 4 * NBBY);
+ mutex_spin_enter(&sc->sc_mutex);
+
+ printf("bcmrng: asked for %d bytes", (int)bytes);
+
+ if (__predict_false(need < 1)) {
+ return;
}
- callout_schedule(&sc->sc_tick, 1);
+ while (need > 0) {
+ status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS);
+ cnt = (status & RNG_STATUS_CNT_MASK) >> RNG_STATUS_CNT_SHIFT;
+ if (cnt > 0) {
+ bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh,
+ RNG_DATA, sc->sc_data, cnt);
+ rnd_add_data(&sc->sc_rnd, sc->sc_data,
+ cnt * 4, cnt * 4 * NBBY);
+ }
+
+ need -= cnt * 4;
+ }
+ mutex_spin_exit(&sc->sc_mutex);
}
diff -r d7719ddcf18d -r 40b566e5b1fb sys/dev/pci/amdpm.c
--- a/sys/dev/pci/amdpm.c Wed Jun 12 21:35:29 2013 +0000
+++ b/sys/dev/pci/amdpm.c Thu Jun 13 00:55:01 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amdpm.c,v 1.36 2012/10/27 17:18:28 chs Exp $ */
+/* $NetBSD: amdpm.c,v 1.37 2013/06/13 00:55:01 tls Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.36 2012/10/27 17:18:28 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.37 2013/06/13 00:55:01 tls Exp $");
#include "opt_amdpm.h"
@@ -40,6 +40,7 @@
#include <sys/device.h>
#include <sys/callout.h>
#include <sys/rnd.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <dev/ic/acpipmtimer.h>
@@ -55,6 +56,7 @@
#include <dev/pci/amdpm_smbusreg.h>
static void amdpm_rnd_callout(void *);
+static void amdpm_rnd_callout_locked(void *);
#ifdef AMDPM_RND_COUNTERS
#define AMDPM_RNDCNT_INCR(ev) (ev)->ev_count++
@@ -83,6 +85,17 @@
}
static void
+amdpm_rnd_get(size_t bytes, void *priv)
+{
+ struct amdpm_softc *sc = priv;
+
+ mutex_enter(&sc->sc_mutex);
+ sc->sc_rnd_need = bytes;
+ amdpm_rnd_callout_locked(sc);
+ mutex_exit(&sc->sc_mutex);
+}
+
+static void
amdpm_attach(device_t parent, device_t self, void *aux)
{
struct amdpm_softc *sc = device_private(self);
@@ -151,6 +164,9 @@
AMDPM_TMR, ((confreg & AMDPM_TMR32) ? ACPIPMT_32BIT : 0));
}
+ /* XXX this mutex is IPL_VM because it can be taken by rnd_getmore() */
+ mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
+
/* try to attach devices on the smbus */
if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC8111_ACPI ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC768_PMC ||
@@ -173,7 +189,9 @@
aprint_normal_dev(self, ""
"random number generator enabled (apprx. %dms)\n",
i);
- callout_init(&sc->sc_rnd_ch, 0);
+ callout_init(&sc->sc_rnd_ch, CALLOUT_MPSAFE);
+ rndsource_setcb(&sc->sc_rnd_source,
+ amdpm_rnd_get, sc);
rnd_attach_source(&sc->sc_rnd_source,
device_xname(self), RND_TYPE_RNG,
/*
@@ -187,7 +205,7 @@
* XXX as entropy, which is not a good idea since
* XXX we add data periodically from a callout.
*/
- RND_FLAG_NO_ESTIMATE);
+ RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
#ifdef AMDPM_RND_COUNTERS
evcnt_attach_dynamic(&sc->sc_rnd_hits, EVCNT_TYPE_MISC,
NULL, device_xname(self), "rnd hits");
@@ -199,6 +217,7 @@
"rnd data");
}
#endif
+ sc->sc_rnd_need = RND_POOLBITS / NBBY;
amdpm_rnd_callout(sc);
}
}
@@ -208,7 +227,7 @@
amdpm_match, amdpm_attach, NULL, NULL);
static void
-amdpm_rnd_callout(void *v)
+amdpm_rnd_callout_locked(void *v)
{
struct amdpm_softc *sc = v;
u_int32_t rngreg;
@@ -216,12 +235,18 @@
int i;
#endif
+ if (sc->sc_rnd_need < 1) {
+ callout_stop(&sc->sc_rnd_ch);
+ return;
+ }
+
if ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, AMDPM_RNGSTAT) &
AMDPM_RNGDONE) != 0) {
rngreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
AMDPM_RNGDATA);
rnd_add_data(&sc->sc_rnd_source, &rngreg,
sizeof(rngreg), sizeof(rngreg) * NBBY);
+ sc->sc_rnd_need -= sizeof(rngreg);
#ifdef AMDPM_RND_COUNTERS
AMDPM_RNDCNT_INCR(&sc->sc_rnd_hits);
for (i = 0; i < sizeof(rngreg); i++, rngreg >>= NBBY)
@@ -232,5 +257,17 @@
else
AMDPM_RNDCNT_INCR(&sc->sc_rnd_miss);
#endif
- callout_reset(&sc->sc_rnd_ch, 1, amdpm_rnd_callout, sc);
+ if (sc->sc_rnd_need > 0) {
+ callout_reset(&sc->sc_rnd_ch, 1, amdpm_rnd_callout, sc);
+ }
}
+
+static void
+amdpm_rnd_callout(void *v)
+{
+ struct amdpm_softc *sc = v;
+
+ mutex_enter(&sc->sc_mutex);
+ amdpm_rnd_callout_locked(v);
+ mutex_exit(&sc->sc_mutex);
+}
diff -r d7719ddcf18d -r 40b566e5b1fb sys/dev/pci/amdpm_smbus.c
--- a/sys/dev/pci/amdpm_smbus.c Wed Jun 12 21:35:29 2013 +0000
+++ b/sys/dev/pci/amdpm_smbus.c Thu Jun 13 00:55:01 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amdpm_smbus.c,v 1.19 2012/10/27 17:18:28 chs Exp $ */
+/* $NetBSD: amdpm_smbus.c,v 1.20 2013/06/13 00:55:01 tls Exp $ */
/*
* Copyright (c) 2005 Anil Gopinath (anil_public%yahoo.com@localhost)
@@ -32,7 +32,7 @@
* AMD-8111 HyperTransport I/O Hub
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdpm_smbus.c,v 1.19 2012/10/27 17:18:28 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdpm_smbus.c,v 1.20 2013/06/13 00:55:01 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -83,8 +83,6 @@
sc->sc_i2c.ic_write_byte = NULL;
sc->sc_i2c.ic_exec = amdpm_smbus_exec;
- mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
-
iba.iba_tag = &sc->sc_i2c;
(void)config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
}
diff -r d7719ddcf18d -r 40b566e5b1fb sys/dev/pci/amdpmvar.h
--- a/sys/dev/pci/amdpmvar.h Wed Jun 12 21:35:29 2013 +0000
+++ b/sys/dev/pci/amdpmvar.h Thu Jun 13 00:55:01 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: amdpmvar.h,v 1.9 2012/10/27 17:18:28 chs Exp $ */
+/* $NetBSD: amdpmvar.h,v 1.10 2013/06/13 00:55:01 tls Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -53,6 +53,7 @@
struct callout sc_rnd_ch;
krndsource_t sc_rnd_source;
+ int sc_rnd_need;
#ifdef AMDPM_RND_COUNTERS
struct evcnt sc_rnd_hits;
struct evcnt sc_rnd_miss;
diff -r d7719ddcf18d -r 40b566e5b1fb sys/dev/pci/hifn7751.c
--- a/sys/dev/pci/hifn7751.c Wed Jun 12 21:35:29 2013 +0000
+++ b/sys/dev/pci/hifn7751.c Thu Jun 13 00:55:01 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hifn7751.c,v 1.51 2012/10/27 17:18:32 chs Exp $ */
+/* $NetBSD: hifn7751.c,v 1.52 2013/06/13 00:55:01 tls Exp $ */
/* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */
/* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */
Home |
Main Index |
Thread Index |
Old Index