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