Author: cem
Date: Thu Dec 26 19:32:11 2019
New Revision: 356096
URL: https://svnweb.freebsd.org/changeset/base/356096

Log:
  random(4): Simplify RANDOM_LOADABLE
  
  Simplify RANDOM_LOADABLE by removing the ability to unload a LOADABLE
  random(4) implementation.  This allows one-time random module selection
  at boot, by loader(8).  Swapping modules on the fly doesn't seem
  especially useful.
  
  This removes the need to hold a lock over the sleepable module calls
  read_random and read_random_uio.
  
  init/deinit have been pulled out of random_algorithm entirely.  Algorithms
  can run their own sysinits to initialize; deinit is removed entirely, as
  algorithms can not be unloaded.  Algorithms should initialize at
  SI_SUB_RANDOM:SI_ORDER_SECOND.  In LOADABLE systems, algorithms install
  a pointer to their local random_algorithm context in p_random_alg_context at
  that time.
  
  Go ahead and const'ify random_algorithm objects; there is no need to mutate
  them at runtime.
  
  LOADABLE kernel NULL checks are removed from random_harvestq by ordering
  random_harvestq initialization at SI_SUB_RANDOM:SI_ORDER_THIRD, after
  algorithm init.  Prior to random_harvestq init, hc_harvest_mask is zero and
  no events are forwarded to algorithms; after random_harvestq init, the
  relevant pointers will already have been installed.
  
  Remove the bulk of random_infra shim wrappers and instead expose the bare
  function pointers in sys/random.h.  In LOADABLE systems, read_random(9) et
  al are just thin shim macros around invoking the associated function
  pointer.  We do not provide a registration system but instead expect
  LOADABLE modules to register themselves at SI_SUB_RANDOM:SI_ORDER_SECOND.
  An example is provided in randomdev.c, as used in the random_fortuna.ko
  module.
  
  Approved by:  csprng(markm)
  Discussed with:       gordon
  Differential Revision:        https://reviews.freebsd.org/D22512

Modified:
  head/UPDATING
  head/sys/dev/random/fortuna.c
  head/sys/dev/random/other_algorithm.c
  head/sys/dev/random/random_harvestq.c
  head/sys/dev/random/random_infra.c
  head/sys/dev/random/randomdev.c
  head/sys/dev/random/randomdev.h
  head/sys/sys/random.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING       Thu Dec 26 18:59:43 2019        (r356095)
+++ head/UPDATING       Thu Dec 26 19:32:11 2019        (r356096)
@@ -26,6 +26,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
        disable the most expensive debugging functionality run
        "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
 
+20191226:
+       Kernel-loadable random(4) modules are no longer unloadable.
+
 20191222:
        Clang, llvm, lld, lldb, compiler-rt, libc++, libunwind and openmp have
        been upgraded to 9.0.1.  Please see the 20141231 entry below for

Modified: head/sys/dev/random/fortuna.c
==============================================================================
--- head/sys/dev/random/fortuna.c       Thu Dec 26 18:59:43 2019        
(r356095)
+++ head/sys/dev/random/fortuna.c       Thu Dec 26 19:32:11 2019        
(r356096)
@@ -261,15 +261,14 @@ static void random_fortuna_read(uint8_t *, size_t);
 static bool random_fortuna_seeded(void);
 static bool random_fortuna_seeded_internal(void);
 static void random_fortuna_process_event(struct harvest_event *);
-static void random_fortuna_init_alg(void *);
-static void random_fortuna_deinit_alg(void *);
 
 static void random_fortuna_reseed_internal(uint32_t *entropy_data, u_int 
blockcount);
 
-struct random_algorithm random_alg_context = {
+#ifdef RANDOM_LOADABLE
+static
+#endif
+const struct random_algorithm random_alg_context = {
        .ra_ident = "Fortuna",
-       .ra_init_alg = random_fortuna_init_alg,
-       .ra_deinit_alg = random_fortuna_deinit_alg,
        .ra_pre_read = random_fortuna_pre_read,
        .ra_read = random_fortuna_read,
        .ra_seeded = random_fortuna_seeded,
@@ -286,6 +285,10 @@ random_fortuna_init_alg(void *unused __unused)
        struct sysctl_oid *random_fortuna_o;
 #endif
 
+#ifdef RANDOM_LOADABLE
+       p_random_alg_context = &random_alg_context;
+#endif
+
        RANDOM_RESEED_INIT_LOCK();
        /*
         * Fortuna parameters. Do not adjust these unless you have
@@ -330,18 +333,8 @@ random_fortuna_init_alg(void *unused __unused)
        fortuna_state.fs_counter = UINT128_ZERO;
        explicit_bzero(&fortuna_state.fs_key, sizeof(fortuna_state.fs_key));
 }
-
-/* ARGSUSED */
-static void
-random_fortuna_deinit_alg(void *unused __unused)
-{
-
-       RANDOM_RESEED_DEINIT_LOCK();
-       explicit_bzero(&fortuna_state, sizeof(fortuna_state));
-#ifdef _KERNEL
-       sysctl_ctx_free(&random_clist);
-#endif
-}
+SYSINIT(random_alg, SI_SUB_RANDOM, SI_ORDER_SECOND, random_fortuna_init_alg,
+    NULL);
 
 /*-
  * FS&K - AddRandomEvent()

Modified: head/sys/dev/random/other_algorithm.c
==============================================================================
--- head/sys/dev/random/other_algorithm.c       Thu Dec 26 18:59:43 2019        
(r356095)
+++ head/sys/dev/random/other_algorithm.c       Thu Dec 26 19:32:11 2019        
(r356096)
@@ -87,8 +87,6 @@ static void random_other_pre_read(void);
 static void random_other_read(uint8_t *, size_t);
 static bool random_other_seeded(void);
 static void random_other_process_event(struct harvest_event *);
-static void random_other_init_alg(void *);
-static void random_other_deinit_alg(void *);
 
 /*
  * RANDOM_OTHER_NPOOLS is used when reading hardware random
@@ -97,10 +95,11 @@ static void random_other_deinit_alg(void *);
  */
 #define RANDOM_OTHER_NPOOLS 1
 
-struct random_algorithm random_alg_context = {
+#ifdef RANDOM_LOADABLE
+static
+#endif
+const struct random_algorithm random_alg_context = {
        .ra_ident = "other",
-       .ra_init_alg = random_other_init_alg,
-       .ra_deinit_alg = random_other_deinit_alg,
        .ra_pre_read = random_other_pre_read,
        .ra_read = random_other_read,
        .ra_seeded = random_other_seeded,
@@ -112,34 +111,20 @@ struct random_algorithm random_alg_context = {
 static mtx_t other_mtx;
 
 /*
- * void random_other_init_alg(void *unused __unused)
- *
  * Do algorithm-specific initialisation here.
  */
-void
+static void
 random_other_init_alg(void *unused __unused)
 {
 
+#ifdef RANDOM_LOADABLE
+       p_random_alg_context = &random_alg_context;
+#endif
+
        RANDOM_RESEED_INIT_LOCK();
-       /*
-        * Do set-up work here!
-        */
 }
-
-/*
- * void random_other_deinit_alg(void *unused __unused)
- *
- * Do algorithm-specific deinitialisation here.
- */
-static void
-random_other_deinit_alg(void *unused __unused)
-{
-
-       /*
-        * Do tear-down work here!
-        */
-       RANDOM_RESEED_DEINIT_LOCK();
-}
+SYSINIT(random_alg, SI_SUB_RANDOM, SI_ORDER_SECOND, random_other_init_alg,
+    NULL);
 
 /*
  * void random_other_pre_read(void)

Modified: head/sys/dev/random/random_harvestq.c
==============================================================================
--- head/sys/dev/random/random_harvestq.c       Thu Dec 26 18:59:43 2019        
(r356095)
+++ head/sys/dev/random/random_harvestq.c       Thu Dec 26 19:32:11 2019        
(r356096)
@@ -49,11 +49,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/unistd.h>
 
-#if defined(RANDOM_LOADABLE)
-#include <sys/lock.h>
-#include <sys/sx.h>
-#endif
-
 #include <machine/atomic.h>
 #include <machine/cpu.h>
 
@@ -163,14 +158,7 @@ static struct kproc_desc random_proc_kp = {
 static __inline void
 random_harvestq_fast_process_event(struct harvest_event *event)
 {
-#if defined(RANDOM_LOADABLE)
-       RANDOM_CONFIG_S_LOCK();
-       if (p_random_alg_context)
-#endif
        p_random_alg_context->ra_event_processor(event);
-#if defined(RANDOM_LOADABLE)
-       RANDOM_CONFIG_S_UNLOCK();
-#endif
        explicit_bzero(event, sizeof(*event));
 }
 
@@ -230,11 +218,6 @@ random_sources_feed(void)
         * Step over all of live entropy sources, and feed their output
         * to the system-wide RNG.
         */
-#if defined(RANDOM_LOADABLE)
-       RANDOM_CONFIG_S_LOCK();
-       if (p_random_alg_context) {
-       /* It's an indenting error. Yeah, Yeah. */
-#endif
        local_read_rate = atomic_readandclear_32(&read_rate);
        /* Perform at least one read per round */
        local_read_rate = MAX(local_read_rate, 1);
@@ -261,10 +244,6 @@ random_sources_feed(void)
                }
        }
        explicit_bzero(entropy, sizeof(entropy));
-#if defined(RANDOM_LOADABLE)
-       }
-       RANDOM_CONFIG_S_UNLOCK();
-#endif
 }
 
 void
@@ -396,7 +375,7 @@ random_harvestq_init(void *unused __unused)
        RANDOM_HARVEST_INIT_LOCK();
        harvest_context.hc_entropy_ring.in = 
harvest_context.hc_entropy_ring.out = 0;
 }
-SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, 
random_harvestq_init, NULL);
+SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_THIRD, 
random_harvestq_init, NULL);
 
 /*
  * Subroutine to slice up a contiguous chunk of 'entropy' and feed it into the
@@ -485,7 +464,7 @@ random_harvestq_deinit(void *unused __unused)
        while (random_kthread_control >= 0)
                tsleep(&harvest_context.hc_kthread_proc, 0, "harvqterm", hz/5);
 }
-SYSUNINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, 
random_harvestq_deinit, NULL);
+SYSUNINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_THIRD, 
random_harvestq_deinit, NULL);
 
 /*-
  * Entropy harvesting queue routine.

Modified: head/sys/dev/random/random_infra.c
==============================================================================
--- head/sys/dev/random/random_infra.c  Thu Dec 26 18:59:43 2019        
(r356095)
+++ head/sys/dev/random/random_infra.c  Thu Dec 26 19:32:11 2019        
(r356096)
@@ -35,11 +35,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/random.h>
 #include <sys/sysctl.h>
 
-#if defined(RANDOM_LOADABLE)
-#include <sys/lock.h>
-#include <sys/sx.h>
-#endif
-
 #include <dev/random/randomdev.h>
 
 /* Set up the sysctl root node for the entropy device */
@@ -102,107 +97,8 @@ SYSCTL_BOOL(_kern_random_initial_seeding, OID_AUTO,
 MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers and data 
structures");
 
 #if defined(RANDOM_LOADABLE)
-struct random_algorithm *p_random_alg_context = NULL;
-#else /* !defined(RANDOM_LOADABLE) */
-struct random_algorithm *p_random_alg_context = &random_alg_context;
-#endif /* defined(RANDOM_LOADABLE) */
-
-#if defined(RANDOM_LOADABLE)
-
-static void
-null_read_random(void *dummy __unused, u_int dummy2 __unused)
-{
-       panic("%s: no random module is loaded", __func__);
-}
-
-static bool
-null_is_random_seeded(void)
-{
-       return (false);
-}
-
-struct random_readers {
-       int     (*read_random_uio)(struct uio *, bool);
-       void    (*read_random)(void *, u_int);
-       bool    (*is_random_seeded)(void);
-} random_reader_context = {
-       (int (*)(struct uio *, bool))nullop,
-       null_read_random,
-       null_is_random_seeded,
-};
-
-struct sx randomdev_config_lock;
-
-static void
-random_infra_sysinit(void *dummy __unused)
-{
-
-       RANDOM_CONFIG_INIT_LOCK();
-}
-SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_FIRST, 
random_infra_sysinit, NULL);
-
-void
-random_infra_init(int (*p_random_read_uio)(struct uio *, bool),
-    void (*p_random_read)(void *, u_int),
-    bool (*p_is_random_seeded)(void))
-{
-
-       RANDOM_CONFIG_X_LOCK();
-       random_reader_context.read_random_uio = p_random_read_uio;
-       random_reader_context.read_random = p_random_read;
-       random_reader_context.is_random_seeded = p_is_random_seeded;
-       RANDOM_CONFIG_X_UNLOCK();
-}
-
-void
-random_infra_uninit(void)
-{
-
-       RANDOM_CONFIG_X_LOCK();
-       random_reader_context.read_random_uio = (int (*)(struct uio *, 
bool))nullop;
-       random_reader_context.read_random = null_read_random;
-       random_reader_context.is_random_seeded = null_is_random_seeded;
-       RANDOM_CONFIG_X_UNLOCK();
-}
-
-static void
-random_infra_sysuninit(void *dummy __unused)
-{
-
-       RANDOM_CONFIG_DEINIT_LOCK();
-}
-SYSUNINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_FIRST, 
random_infra_sysuninit, NULL);
-
-int
-read_random_uio(struct uio *uio, bool nonblock)
-{
-       int retval;
-
-       RANDOM_CONFIG_S_LOCK();
-       retval = random_reader_context.read_random_uio(uio, nonblock);
-       RANDOM_CONFIG_S_UNLOCK();
-       return (retval);
-}
-
-void
-read_random(void *buf, u_int len)
-{
-
-       RANDOM_CONFIG_S_LOCK();
-       random_reader_context.read_random(buf, len);
-       RANDOM_CONFIG_S_UNLOCK();
-}
-
-bool
-is_random_seeded(void)
-{
-       bool result;
-
-       RANDOM_CONFIG_S_LOCK();
-       result = random_reader_context.is_random_seeded();
-       RANDOM_CONFIG_S_UNLOCK();
-       return (result);
-}
-
-
+const struct random_algorithm *p_random_alg_context;
+void (*_read_random)(void *, u_int);
+int (*_read_random_uio)(struct uio *, bool);
+bool (*_is_random_seeded)(void);
 #endif /* defined(RANDOM_LOADABLE) */

Modified: head/sys/dev/random/randomdev.c
==============================================================================
--- head/sys/dev/random/randomdev.c     Thu Dec 26 18:59:43 2019        
(r356095)
+++ head/sys/dev/random/randomdev.c     Thu Dec 26 19:32:11 2019        
(r356096)
@@ -59,17 +59,17 @@ __FBSDID("$FreeBSD$");
 
 #define        RANDOM_UNIT     0
 
+/*
+ * In loadable random, the core randomdev.c / random(9) routines have static
+ * visibility and an alternative name to avoid conflicting with the function
+ * pointers of the real names in the core kernel.  random_alg_context_init
+ * installs pointers to the loadable static names into the core kernel's
+ * function pointers at SI_SUB_RANDOM:SI_ORDER_SECOND.
+ */
 #if defined(RANDOM_LOADABLE)
-#define READ_RANDOM_UIO        _read_random_uio
-#define READ_RANDOM    _read_random
-#define IS_RANDOM_SEEDED       _is_random_seeded
-static int READ_RANDOM_UIO(struct uio *, bool);
-static void READ_RANDOM(void *, u_int);
-static bool IS_RANDOM_SEEDED(void);
-#else
-#define READ_RANDOM_UIO        read_random_uio
-#define READ_RANDOM    read_random
-#define IS_RANDOM_SEEDED       is_random_seeded
+static int (read_random_uio)(struct uio *, bool);
+static void (read_random)(void *, u_int);
+static bool (is_random_seeded)(void);
 #endif
 
 static d_read_t randomdev_read;
@@ -89,31 +89,18 @@ static struct cdevsw random_cdevsw = {
 /* For use with make_dev(9)/destroy_dev(9). */
 static struct cdev *random_dev;
 
-static void
-random_alg_context_ra_init_alg(void *data)
-{
-
-       p_random_alg_context = &random_alg_context;
-       p_random_alg_context->ra_init_alg(data);
 #if defined(RANDOM_LOADABLE)
-       random_infra_init(READ_RANDOM_UIO, READ_RANDOM, IS_RANDOM_SEEDED);
-#endif
-}
-
 static void
-random_alg_context_ra_deinit_alg(void *data)
+random_alg_context_init(void *dummy __unused)
 {
-
-#if defined(RANDOM_LOADABLE)
-       random_infra_uninit();
-#endif
-       p_random_alg_context->ra_deinit_alg(data);
-       p_random_alg_context = NULL;
+       _read_random_uio = (read_random_uio);
+       _read_random = (read_random);
+       _is_random_seeded = (is_random_seeded);
 }
+SYSINIT(random_device, SI_SUB_RANDOM, SI_ORDER_SECOND, random_alg_context_init,
+    NULL);
+#endif
 
-SYSINIT(random_device, SI_SUB_RANDOM, SI_ORDER_THIRD, 
random_alg_context_ra_init_alg, NULL);
-SYSUNINIT(random_device, SI_SUB_RANDOM, SI_ORDER_THIRD, 
random_alg_context_ra_deinit_alg, NULL);
-
 static struct selinfo rsel;
 
 /*
@@ -124,7 +111,7 @@ static int
 randomdev_read(struct cdev *dev __unused, struct uio *uio, int flags)
 {
 
-       return (READ_RANDOM_UIO(uio, (flags & O_NONBLOCK) != 0));
+       return ((read_random_uio)(uio, (flags & O_NONBLOCK) != 0));
 }
 
 /*
@@ -154,7 +141,7 @@ randomdev_wait_until_seeded(bool interruptible)
                if (spamcount == 0)
                        printf("random: %s unblock wait\n", __func__);
                spamcount = (spamcount + 1) % 100;
-               error = tsleep(&random_alg_context, slpflags, "randseed",
+               error = tsleep(p_random_alg_context, slpflags, "randseed",
                    hz / 10);
                if (error == ERESTART || error == EINTR) {
                        KASSERT(interruptible,
@@ -170,7 +157,7 @@ randomdev_wait_until_seeded(bool interruptible)
 }
 
 int
-READ_RANDOM_UIO(struct uio *uio, bool nonblock)
+(read_random_uio)(struct uio *uio, bool nonblock)
 {
        /* 16 MiB takes about 0.08 s CPU time on my 2017 AMD Zen CPU */
 #define SIGCHK_PERIOD (16 * 1024 * 1024)
@@ -238,7 +225,7 @@ READ_RANDOM_UIO(struct uio *uio, bool nonblock)
                 */
                if (error == 0 && uio->uio_resid != 0 &&
                    total_read % sigchk_period == 0) {
-                       error = tsleep_sbt(&random_alg_context, PCATCH,
+                       error = tsleep_sbt(p_random_alg_context, PCATCH,
                            "randrd", SBT_1NS, 0, C_HARDCLOCK);
                        /* Squash tsleep timeout condition */
                        if (error == EWOULDBLOCK)
@@ -271,7 +258,7 @@ READ_RANDOM_UIO(struct uio *uio, bool nonblock)
  * 'kern.random.initial_seeding.read_random_bypassed_before_seeding'.
  */
 void
-READ_RANDOM(void *random_buf, u_int len)
+(read_random)(void *random_buf, u_int len)
 {
 
        KASSERT(random_buf != NULL, ("No suitable random buffer in %s", 
__func__));
@@ -305,7 +292,7 @@ READ_RANDOM(void *random_buf, u_int len)
 }
 
 bool
-IS_RANDOM_SEEDED(void)
+(is_random_seeded)(void)
 {
        return (p_random_alg_context->ra_seeded());
 }
@@ -356,7 +343,7 @@ randomdev_write(struct cdev *dev __unused, struct uio 
                if (error)
                        break;
                randomdev_accumulate(random_buf, c);
-               tsleep(&random_alg_context, 0, "randwr", hz/10);
+               tsleep(p_random_alg_context, 0, "randwr", hz/10);
        }
        if (nbytes != uio->uio_resid && (error == ERESTART || error == EINTR))
                /* Partial write, not error. */
@@ -385,7 +372,7 @@ randomdev_unblock(void)
 {
 
        selwakeuppri(&rsel, PUSER);
-       wakeup(&random_alg_context);
+       wakeup(p_random_alg_context);
        printf("random: unblocking device.\n");
        /* Do random(9) a favour while we are about it. */
        (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, 
ARC4_ENTR_HAVE);
@@ -424,7 +411,7 @@ randomdev_modevent(module_t mod __unused, int type, vo
                make_dev_alias(random_dev, "urandom"); /* compatibility */
                break;
        case MOD_UNLOAD:
-               destroy_dev(random_dev);
+               error = EBUSY;
                break;
        case MOD_SHUTDOWN:
                break;

Modified: head/sys/dev/random/randomdev.h
==============================================================================
--- head/sys/dev/random/randomdev.h     Thu Dec 26 18:59:43 2019        
(r356095)
+++ head/sys/dev/random/randomdev.h     Thu Dec 26 19:32:11 2019        
(r356096)
@@ -79,15 +79,18 @@ typedef u_int random_source_read_t(void *, u_int);
 struct random_algorithm {
        const char                      *ra_ident;
        u_int                            ra_poolcount;
-       void                            (*ra_init_alg)(void *);
-       void                            (*ra_deinit_alg)(void *);
        random_alg_pre_read_t           *ra_pre_read;
        random_alg_read_t               *ra_read;
        random_alg_seeded_t             *ra_seeded;
        random_alg_eventprocessor_t     *ra_event_processor;
 };
 
-extern struct random_algorithm random_alg_context, *p_random_alg_context;
+#if defined(RANDOM_LOADABLE)
+extern const struct random_algorithm *p_random_alg_context;
+#else
+extern const struct random_algorithm random_alg_context;
+#define        p_random_alg_context (&random_alg_context)
+#endif
 
 #ifdef _KERNEL
 
@@ -104,19 +107,6 @@ struct random_source {
 
 void random_source_register(struct random_source *);
 void random_source_deregister(struct random_source *);
-
-#if defined(RANDOM_LOADABLE)
-extern struct sx randomdev_config_lock;
-#define        RANDOM_CONFIG_INIT_LOCK(x)      sx_init(&randomdev_config_lock, 
"configuration change lock")
-#define        RANDOM_CONFIG_X_LOCK(x)         sx_xlock(&randomdev_config_lock)
-#define        RANDOM_CONFIG_X_UNLOCK(x)       
sx_xunlock(&randomdev_config_lock)
-#define        RANDOM_CONFIG_S_LOCK(x)         sx_slock(&randomdev_config_lock)
-#define        RANDOM_CONFIG_S_UNLOCK(x)       
sx_sunlock(&randomdev_config_lock)
-#define        RANDOM_CONFIG_DEINIT_LOCK(x)    
sx_destroy(&randomdev_config_lock)
-void random_infra_init(int (*)(struct uio *, bool), void (*)(void *, u_int),
-    bool (*)(void));
-void random_infra_uninit(void);
-#endif
 
 #endif /* _KERNEL */
 

Modified: head/sys/sys/random.h
==============================================================================
--- head/sys/sys/random.h       Thu Dec 26 18:59:43 2019        (r356095)
+++ head/sys/sys/random.h       Thu Dec 26 19:32:11 2019        (r356096)
@@ -37,9 +37,35 @@
 
 struct uio;
 
+/*
+ * In the loadable random world, there are set of dangling pointers left in the
+ * core kernel:
+ *   * read_random, read_random_uio, is_random_seeded are function pointers,
+ *     rather than functions.
+ *   * p_random_alg_context is a true pointer in loadable random kernels.
+ *
+ * These are initialized at SI_SUB_RANDOM:SI_ORDER_SECOND during boot.  The
+ * read-type pointers are initialized by random_alg_context_init() in
+ * randomdev.c and p_random_alg_context in the algorithm, e.g., fortuna.c's
+ * random_fortuna_init_alg().  The nice thing about function pointers is they
+ * have a similar calling convention to ordinary functions.
+ *
+ * (In !loadable, the read_random, etc, routines are just plain functions;
+ * p_random_alg_context is a macro for the public visibility
+ * &random_alg_context.)
+ */
+#if defined(RANDOM_LOADABLE)
+extern void (*_read_random)(void *, u_int);
+extern int (*_read_random_uio)(struct uio *, bool);
+extern bool (*_is_random_seeded)(void);
+#define        read_random(a, b)       (*_read_random)(a, b)
+#define        read_random_uio(a, b)   (*_read_random_uio)(a, b)
+#define        is_random_seeded()      (*_is_random_seeded)()
+#else
 void read_random(void *, u_int);
 int read_random_uio(struct uio *, bool);
 bool is_random_seeded(void);
+#endif
 
 /*
  * Note: if you add or remove members of random_entropy_source, remember to
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to