random: credit architectural init the exact amount
[linux-2.6-microblaze.git] / drivers / char / random.c
index 4c9adb4..2906259 100644 (file)
  *   - Sysctl interface.
  *
  * The high level overview is that there is one input pool, into which
- * various pieces of data are hashed. Some of that data is then "credited" as
- * having a certain number of bits of entropy. When enough bits of entropy are
- * available, the hash is finalized and handed as a key to a stream cipher that
- * expands it indefinitely for various consumers. This key is periodically
- * refreshed as the various entropy collectors, described below, add data to the
- * input pool and credit it. There is currently no Fortuna-like scheduler
- * involved, which can lead to malicious entropy sources causing a premature
- * reseed, and the entropy estimates are, at best, conservative guesses.
+ * various pieces of data are hashed. Prior to initialization, some of that
+ * data is then "credited" as having a certain number of bits of entropy.
+ * When enough bits of entropy are available, the hash is finalized and
+ * handed as a key to a stream cipher that expands it indefinitely for
+ * various consumers. This key is periodically refreshed as the various
+ * entropy collectors, described below, add data to the input pool.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -53,6 +51,8 @@
 #include <linux/completion.h>
 #include <linux/uuid.h>
 #include <linux/uaccess.h>
+#include <linux/suspend.h>
+#include <linux/siphash.h>
 #include <crypto/chacha.h>
 #include <crypto/blake2s.h>
 #include <asm/processor.h>
  *********************************************************************/
 
 /*
- * crng_init =  0 --> Uninitialized
- *             1 --> Initialized
- *             2 --> Initialized from input_pool
- *
  * crng_init is protected by base_crng->lock, and only increases
- * its value (from 0->1->2).
+ * its value (from empty->early->ready).
  */
-static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 1))
-/* Various types of waiters for crng_init->2 transition. */
+static enum {
+       CRNG_EMPTY = 0, /* Little to no entropy collected */
+       CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */
+       CRNG_READY = 2  /* Fully initialized with POOL_READY_BITS collected */
+} crng_init = CRNG_EMPTY;
+#define crng_ready() (likely(crng_init >= CRNG_READY))
+/* Various types of waiters for crng_init->CRNG_READY transition. */
 static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
 static struct fasync_struct *fasync;
 static DEFINE_SPINLOCK(random_ready_chain_lock);
 static RAW_NOTIFIER_HEAD(random_ready_chain);
 
 /* Control how we warn userspace. */
-static struct ratelimit_state unseeded_warning =
-       RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
 static struct ratelimit_state urandom_warning =
        RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
-static int ratelimit_disable __read_mostly;
+static int ratelimit_disable __read_mostly =
+       IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM);
 module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
 MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
 
@@ -182,27 +181,15 @@ static void process_random_ready_list(void)
        spin_unlock_irqrestore(&random_ready_chain_lock, flags);
 }
 
-#define warn_unseeded_randomness(previous) \
-       _warn_unseeded_randomness(__func__, (void *)_RET_IP_, (previous))
+#define warn_unseeded_randomness() \
+       _warn_unseeded_randomness(__func__, (void *)_RET_IP_)
 
-static void _warn_unseeded_randomness(const char *func_name, void *caller, void **previous)
+static void _warn_unseeded_randomness(const char *func_name, void *caller)
 {
-#ifdef CONFIG_WARN_ALL_UNSEEDED_RANDOM
-       const bool print_once = false;
-#else
-       static bool print_once __read_mostly;
-#endif
-
-       if (print_once || crng_ready() ||
-           (previous && (caller == READ_ONCE(*previous))))
+       if (!IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) || crng_ready())
                return;
-       WRITE_ONCE(*previous, caller);
-#ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM
-       print_once = true;
-#endif
-       if (__ratelimit(&unseeded_warning))
-               printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n",
-                               func_name, caller, crng_init);
+       printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n",
+                       func_name, caller, crng_init);
 }
 
 
@@ -232,8 +219,8 @@ static void _warn_unseeded_randomness(const char *func_name, void *caller, void
  *********************************************************************/
 
 enum {
-       CRNG_RESEED_INTERVAL = 300 * HZ,
-       CRNG_INIT_CNT_THRESH = 2 * CHACHA_KEY_SIZE
+       CRNG_RESEED_START_INTERVAL = HZ,
+       CRNG_RESEED_INTERVAL = 60 * HZ
 };
 
 static struct {
@@ -256,24 +243,17 @@ static DEFINE_PER_CPU(struct crng, crngs) = {
        .lock = INIT_LOCAL_LOCK(crngs.lock),
 };
 
-/* Used by crng_reseed() to extract a new seed from the input pool. */
-static bool drain_entropy(void *buf, size_t nbytes, bool force);
+/* Used by crng_reseed() and crng_make_state() to extract a new seed from the input pool. */
+static void extract_entropy(void *buf, size_t nbytes);
 
-/*
- * This extracts a new crng key from the input pool, but only if there is a
- * sufficient amount of entropy available or force is true, in order to
- * mitigate bruteforcing of newly added bits.
- */
-static void crng_reseed(bool force)
+/* This extracts a new crng key from the input pool. */
+static void crng_reseed(void)
 {
        unsigned long flags;
        unsigned long next_gen;
        u8 key[CHACHA_KEY_SIZE];
-       bool finalize_init = false;
 
-       /* Only reseed if we can, to prevent brute forcing a small amount of new bits. */
-       if (!drain_entropy(key, sizeof(key), force))
-               return;
+       extract_entropy(key, sizeof(key));
 
        /*
         * We copy the new key into the base_crng, overwriting the old one,
@@ -288,28 +268,10 @@ static void crng_reseed(bool force)
                ++next_gen;
        WRITE_ONCE(base_crng.generation, next_gen);
        WRITE_ONCE(base_crng.birth, jiffies);
-       if (!crng_ready()) {
-               crng_init = 2;
-               finalize_init = true;
-       }
+       if (!crng_ready())
+               crng_init = CRNG_READY;
        spin_unlock_irqrestore(&base_crng.lock, flags);
        memzero_explicit(key, sizeof(key));
-       if (finalize_init) {
-               process_random_ready_list();
-               wake_up_interruptible(&crng_init_wait);
-               kill_fasync(&fasync, SIGIO, POLL_IN);
-               pr_notice("crng init done\n");
-               if (unseeded_warning.missed) {
-                       pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n",
-                                 unseeded_warning.missed);
-                       unseeded_warning.missed = 0;
-               }
-               if (urandom_warning.missed) {
-                       pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
-                                 urandom_warning.missed);
-                       urandom_warning.missed = 0;
-               }
-       }
 }
 
 /*
@@ -345,10 +307,10 @@ static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE],
 }
 
 /*
- * Return whether the crng seed is considered to be sufficiently
- * old that a reseeding might be attempted. This happens if the last
- * reseeding was CRNG_RESEED_INTERVAL ago, or during early boot, at
- * an interval proportional to the uptime.
+ * Return whether the crng seed is considered to be sufficiently old
+ * that a reseeding is needed. This happens if the last reseeding
+ * was CRNG_RESEED_INTERVAL ago, or during early boot, at an interval
+ * proportional to the uptime.
  */
 static bool crng_has_old_seed(void)
 {
@@ -360,10 +322,10 @@ static bool crng_has_old_seed(void)
                if (uptime >= CRNG_RESEED_INTERVAL / HZ * 2)
                        WRITE_ONCE(early_boot, false);
                else
-                       interval = max_t(unsigned int, 5 * HZ,
+                       interval = max_t(unsigned int, CRNG_RESEED_START_INTERVAL,
                                         (unsigned int)uptime / 2 * HZ);
        }
-       return time_after(jiffies, READ_ONCE(base_crng.birth) + interval);
+       return time_is_before_jiffies(READ_ONCE(base_crng.birth) + interval);
 }
 
 /*
@@ -382,28 +344,31 @@ static void crng_make_state(u32 chacha_state[CHACHA_STATE_WORDS],
        /*
         * For the fast path, we check whether we're ready, unlocked first, and
         * then re-check once locked later. In the case where we're really not
-        * ready, we do fast key erasure with the base_crng directly, because
-        * this is what crng_pre_init_inject() mutates during early init.
+        * ready, we do fast key erasure with the base_crng directly, extracting
+        * when crng_init is CRNG_EMPTY.
         */
        if (!crng_ready()) {
                bool ready;
 
                spin_lock_irqsave(&base_crng.lock, flags);
                ready = crng_ready();
-               if (!ready)
+               if (!ready) {
+                       if (crng_init == CRNG_EMPTY)
+                               extract_entropy(base_crng.key, sizeof(base_crng.key));
                        crng_fast_key_erasure(base_crng.key, chacha_state,
                                              random_data, random_data_len);
+               }
                spin_unlock_irqrestore(&base_crng.lock, flags);
                if (!ready)
                        return;
        }
 
        /*
-        * If the base_crng is old enough, we try to reseed, which in turn
-        * bumps the generation counter that we check below.
+        * If the base_crng is old enough, we reseed, which in turn bumps the
+        * generation counter that we check below.
         */
        if (unlikely(crng_has_old_seed()))
-               crng_reseed(false);
+               crng_reseed();
 
        local_lock_irqsave(&crngs.lock, flags);
        crng = raw_cpu_ptr(&crngs);
@@ -433,50 +398,6 @@ static void crng_make_state(u32 chacha_state[CHACHA_STATE_WORDS],
        local_unlock_irqrestore(&crngs.lock, flags);
 }
 
-/*
- * This function is for crng_init == 0 only. It loads entropy directly
- * into the crng's key, without going through the input pool. It is,
- * generally speaking, not very safe, but we use this only at early
- * boot time when it's better to have something there rather than
- * nothing.
- *
- * If account is set, then the crng_init_cnt counter is incremented.
- * This shouldn't be set by functions like add_device_randomness(),
- * where we can't trust the buffer passed to it is guaranteed to be
- * unpredictable (so it might not have any entropy at all).
- */
-static void crng_pre_init_inject(const void *input, size_t len, bool account)
-{
-       static int crng_init_cnt = 0;
-       struct blake2s_state hash;
-       unsigned long flags;
-
-       blake2s_init(&hash, sizeof(base_crng.key));
-
-       spin_lock_irqsave(&base_crng.lock, flags);
-       if (crng_init != 0) {
-               spin_unlock_irqrestore(&base_crng.lock, flags);
-               return;
-       }
-
-       blake2s_update(&hash, base_crng.key, sizeof(base_crng.key));
-       blake2s_update(&hash, input, len);
-       blake2s_final(&hash, base_crng.key);
-
-       if (account) {
-               crng_init_cnt += min_t(size_t, len, CRNG_INIT_CNT_THRESH - crng_init_cnt);
-               if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
-                       ++base_crng.generation;
-                       crng_init = 1;
-               }
-       }
-
-       spin_unlock_irqrestore(&base_crng.lock, flags);
-
-       if (crng_init == 1)
-               pr_notice("fast init done\n");
-}
-
 static void _get_random_bytes(void *buf, size_t nbytes)
 {
        u32 chacha_state[CHACHA_STATE_WORDS];
@@ -521,9 +442,7 @@ static void _get_random_bytes(void *buf, size_t nbytes)
  */
 void get_random_bytes(void *buf, size_t nbytes)
 {
-       static void *previous;
-
-       warn_unseeded_randomness(&previous);
+       warn_unseeded_randomness();
        _get_random_bytes(buf, nbytes);
 }
 EXPORT_SYMBOL(get_random_bytes);
@@ -619,10 +538,14 @@ u64 get_random_u64(void)
        u64 ret;
        unsigned long flags;
        struct batched_entropy *batch;
-       static void *previous;
        unsigned long next_gen;
 
-       warn_unseeded_randomness(&previous);
+       warn_unseeded_randomness();
+
+       if  (!crng_ready()) {
+               _get_random_bytes(&ret, sizeof(ret));
+               return ret;
+       }
 
        local_lock_irqsave(&batched_entropy_u64.lock, flags);
        batch = raw_cpu_ptr(&batched_entropy_u64);
@@ -653,10 +576,14 @@ u32 get_random_u32(void)
        u32 ret;
        unsigned long flags;
        struct batched_entropy *batch;
-       static void *previous;
        unsigned long next_gen;
 
-       warn_unseeded_randomness(&previous);
+       warn_unseeded_randomness();
+
+       if  (!crng_ready()) {
+               _get_random_bytes(&ret, sizeof(ret));
+               return ret;
+       }
 
        local_lock_irqsave(&batched_entropy_u32.lock, flags);
        batch = raw_cpu_ptr(&batched_entropy_u32);
@@ -766,29 +693,24 @@ EXPORT_SYMBOL(get_random_bytes_arch);
  *
  * After which, if added entropy should be credited:
  *
- *     static void credit_entropy_bits(size_t nbits)
+ *     static void credit_init_bits(size_t nbits)
  *
- * Finally, extract entropy via these two, with the latter one
- * setting the entropy count to zero and extracting only if there
- * is POOL_MIN_BITS entropy credited prior or force is true:
+ * Finally, extract entropy via:
  *
  *     static void extract_entropy(void *buf, size_t nbytes)
- *     static bool drain_entropy(void *buf, size_t nbytes, bool force)
  *
  **********************************************************************/
 
 enum {
        POOL_BITS = BLAKE2S_HASH_SIZE * 8,
-       POOL_MIN_BITS = POOL_BITS /* No point in settling for less. */
+       POOL_READY_BITS = POOL_BITS, /* When crng_init->CRNG_READY */
+       POOL_EARLY_BITS = POOL_READY_BITS / 2 /* When crng_init->CRNG_EARLY */
 };
 
-/* For notifying userspace should write into /dev/random. */
-static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
-
 static struct {
        struct blake2s_state hash;
        spinlock_t lock;
-       unsigned int entropy_count;
+       unsigned int init_bits;
 } input_pool = {
        .hash.h = { BLAKE2S_IV0 ^ (0x01010000 | BLAKE2S_HASH_SIZE),
                    BLAKE2S_IV1, BLAKE2S_IV2, BLAKE2S_IV3, BLAKE2S_IV4,
@@ -803,9 +725,9 @@ static void _mix_pool_bytes(const void *in, size_t nbytes)
 }
 
 /*
- * This function adds bytes into the entropy "pool".  It does not
- * update the entropy estimate.  The caller should call
- * credit_entropy_bits if this is appropriate.
+ * This function adds bytes into the input pool. It does not
+ * update the initialization bit counter; the caller should call
+ * credit_init_bits if this is appropriate.
  */
 static void mix_pool_bytes(const void *in, size_t nbytes)
 {
@@ -816,24 +738,6 @@ static void mix_pool_bytes(const void *in, size_t nbytes)
        spin_unlock_irqrestore(&input_pool.lock, flags);
 }
 
-static void credit_entropy_bits(size_t nbits)
-{
-       unsigned int entropy_count, orig, add;
-
-       if (!nbits)
-               return;
-
-       add = min_t(size_t, nbits, POOL_BITS);
-
-       do {
-               orig = READ_ONCE(input_pool.entropy_count);
-               entropy_count = min_t(unsigned int, POOL_BITS, orig + add);
-       } while (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig);
-
-       if (!crng_ready() && entropy_count >= POOL_MIN_BITS)
-               crng_reseed(false);
-}
-
 /*
  * This is an HKDF-like construction for using the hashed collected entropy
  * as a PRF key, that's then expanded block-by-block.
@@ -880,23 +784,39 @@ static void extract_entropy(void *buf, size_t nbytes)
        memzero_explicit(&block, sizeof(block));
 }
 
-/*
- * First we make sure we have POOL_MIN_BITS of entropy in the pool unless force
- * is true, and then we set the entropy count to zero (but don't actually touch
- * any data). Only then can we extract a new key with extract_entropy().
- */
-static bool drain_entropy(void *buf, size_t nbytes, bool force)
+static void credit_init_bits(size_t nbits)
 {
-       unsigned int entropy_count;
+       unsigned int new, orig, add;
+       unsigned long flags;
+
+       if (crng_ready() || !nbits)
+               return;
+
+       add = min_t(size_t, nbits, POOL_BITS);
+
        do {
-               entropy_count = READ_ONCE(input_pool.entropy_count);
-               if (!force && entropy_count < POOL_MIN_BITS)
-                       return false;
-       } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
-       extract_entropy(buf, nbytes);
-       wake_up_interruptible(&random_write_wait);
-       kill_fasync(&fasync, SIGIO, POLL_OUT);
-       return true;
+               orig = READ_ONCE(input_pool.init_bits);
+               new = min_t(unsigned int, POOL_BITS, orig + add);
+       } while (cmpxchg(&input_pool.init_bits, orig, new) != orig);
+
+       if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
+               crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
+               process_random_ready_list();
+               wake_up_interruptible(&crng_init_wait);
+               kill_fasync(&fasync, SIGIO, POLL_IN);
+               pr_notice("crng init done\n");
+               if (urandom_warning.missed)
+                       pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
+                                 urandom_warning.missed);
+       } else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) {
+               spin_lock_irqsave(&base_crng.lock, flags);
+               /* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */
+               if (crng_init == CRNG_EMPTY) {
+                       extract_entropy(base_crng.key, sizeof(base_crng.key));
+                       crng_init = CRNG_EARLY;
+               }
+               spin_unlock_irqrestore(&base_crng.lock, flags);
+       }
 }
 
 
@@ -908,14 +828,14 @@ static bool drain_entropy(void *buf, size_t nbytes, bool force)
  * the above entropy accumulation routines:
  *
  *     void add_device_randomness(const void *buf, size_t size);
- *     void add_input_randomness(unsigned int type, unsigned int code,
- *                               unsigned int value);
- *     void add_disk_randomness(struct gendisk *disk);
  *     void add_hwgenerator_randomness(const void *buffer, size_t count,
  *                                     size_t entropy);
  *     void add_bootloader_randomness(const void *buf, size_t size);
  *     void add_vmfork_randomness(const void *unique_vm_id, size_t size);
  *     void add_interrupt_randomness(int irq);
+ *     void add_input_randomness(unsigned int type, unsigned int code,
+ *                               unsigned int value);
+ *     void add_disk_randomness(struct gendisk *disk);
  *
  * add_device_randomness() adds data to the input pool that
  * is likely to differ between two devices (or possibly even per boot).
@@ -925,26 +845,13 @@ static bool drain_entropy(void *buf, size_t nbytes, bool force)
  * that might otherwise be identical and have very little entropy
  * available to them (particularly common in the embedded world).
  *
- * add_input_randomness() uses the input layer interrupt timing, as well
- * as the event type information from the hardware.
- *
- * add_disk_randomness() uses what amounts to the seek time of block
- * layer request events, on a per-disk_devt basis, as input to the
- * entropy pool. Note that high-speed solid state drives with very low
- * seek times do not make for good sources of entropy, as their seek
- * times are usually fairly consistent.
- *
- * The above two routines try to estimate how many bits of entropy
- * to credit. They do this by keeping track of the first and second
- * order deltas of the event timings.
- *
  * add_hwgenerator_randomness() is for true hardware RNGs, and will credit
  * entropy as specified by the caller. If the entropy pool is full it will
  * block until more entropy is needed.
  *
- * add_bootloader_randomness() is the same as add_hwgenerator_randomness() or
- * add_device_randomness(), depending on whether or not the configuration
- * option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
+ * add_bootloader_randomness() is called by bootloader drivers, such as EFI
+ * and device tree, and credits its input depending on whether or not the
+ * configuration option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
  *
  * add_vmfork_randomness() adds a unique (but not necessarily secret) ID
  * representing the current instance of a VM to the pool, without crediting,
@@ -955,6 +862,19 @@ static bool drain_entropy(void *buf, size_t nbytes, bool force)
  * as inputs, it feeds the input pool roughly once a second or after 64
  * interrupts, crediting 1 bit of entropy for whichever comes first.
  *
+ * add_input_randomness() uses the input layer interrupt timing, as well
+ * as the event type information from the hardware.
+ *
+ * add_disk_randomness() uses what amounts to the seek time of block
+ * layer request events, on a per-disk_devt basis, as input to the
+ * entropy pool. Note that high-speed solid state drives with very low
+ * seek times do not make for good sources of entropy, as their seek
+ * times are usually fairly consistent.
+ *
+ * The last two routines try to estimate how many bits of entropy
+ * to credit. They do this by keeping track of the first and second
+ * order deltas of the event timings.
+ *
  **********************************************************************/
 
 static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
@@ -970,18 +890,45 @@ static int __init parse_trust_bootloader(char *arg)
 early_param("random.trust_cpu", parse_trust_cpu);
 early_param("random.trust_bootloader", parse_trust_bootloader);
 
+static int random_pm_notification(struct notifier_block *nb, unsigned long action, void *data)
+{
+       unsigned long flags, entropy = random_get_entropy();
+
+       /*
+        * Encode a representation of how long the system has been suspended,
+        * in a way that is distinct from prior system suspends.
+        */
+       ktime_t stamps[] = { ktime_get(), ktime_get_boottime(), ktime_get_real() };
+
+       spin_lock_irqsave(&input_pool.lock, flags);
+       _mix_pool_bytes(&action, sizeof(action));
+       _mix_pool_bytes(stamps, sizeof(stamps));
+       _mix_pool_bytes(&entropy, sizeof(entropy));
+       spin_unlock_irqrestore(&input_pool.lock, flags);
+
+       if (crng_ready() && (action == PM_RESTORE_PREPARE ||
+           (action == PM_POST_SUSPEND &&
+            !IS_ENABLED(CONFIG_PM_AUTOSLEEP) && !IS_ENABLED(CONFIG_ANDROID)))) {
+               crng_reseed();
+               pr_notice("crng reseeded on system resumption\n");
+       }
+       return 0;
+}
+
+static struct notifier_block pm_notifier = { .notifier_call = random_pm_notification };
+
 /*
  * The first collection of entropy occurs at system boot while interrupts
- * are still turned off. Here we push in RDSEED, a timestamp, and utsname().
- * Depending on the above configuration knob, RDSEED may be considered
- * sufficient for initialization. Note that much earlier setup may already
- * have pushed entropy into the input pool by the time we get here.
+ * are still turned off. Here we push in latent entropy, RDSEED, a timestamp,
+ * utsname(), and the command line. Depending on the above configuration knob,
+ * RDSEED may be considered sufficient for initialization. Note that much
+ * earlier setup may already have pushed entropy into the input pool by the
+ * time we get here.
  */
-int __init rand_initialize(void)
+int __init random_init(const char *command_line)
 {
-       size_t i;
        ktime_t now = ktime_get_real();
-       bool arch_init = true;
+       unsigned int i, arch_bytes;
        unsigned long rv;
 
 #if defined(LATENT_ENTROPY_PLUGIN)
@@ -989,29 +936,29 @@ int __init rand_initialize(void)
        _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
 #endif
 
-       for (i = 0; i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
+       for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE;
+            i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
                if (!arch_get_random_seed_long_early(&rv) &&
                    !arch_get_random_long_early(&rv)) {
                        rv = random_get_entropy();
-                       arch_init = false;
+                       arch_bytes -= sizeof(rv);
                }
                _mix_pool_bytes(&rv, sizeof(rv));
        }
        _mix_pool_bytes(&now, sizeof(now));
        _mix_pool_bytes(utsname(), sizeof(*(utsname())));
+       _mix_pool_bytes(command_line, strlen(command_line));
+       add_latent_entropy();
 
-       extract_entropy(base_crng.key, sizeof(base_crng.key));
-       ++base_crng.generation;
+       if (crng_ready())
+               crng_reseed();
+       else if (trust_cpu)
+               credit_init_bits(arch_bytes * 8);
 
-       if (arch_init && trust_cpu && !crng_ready()) {
-               crng_init = 2;
-               pr_notice("crng init done (trusting CPU's manufacturer)\n");
-       }
+       WARN_ON(register_pm_notifier(&pm_notifier));
 
-       if (ratelimit_disable) {
-               urandom_warning.interval = 0;
-               unseeded_warning.interval = 0;
-       }
+       WARN(!random_get_entropy(), "Missing cycle counter and fallback timer; RNG "
+                                   "entropy collection will consequently suffer.");
        return 0;
 }
 
@@ -1025,121 +972,16 @@ int __init rand_initialize(void)
  */
 void add_device_randomness(const void *buf, size_t size)
 {
-       unsigned long cycles = random_get_entropy();
-       unsigned long flags, now = jiffies;
-
-       if (crng_init == 0 && size)
-               crng_pre_init_inject(buf, size, false);
+       unsigned long entropy = random_get_entropy();
+       unsigned long flags;
 
        spin_lock_irqsave(&input_pool.lock, flags);
-       _mix_pool_bytes(&cycles, sizeof(cycles));
-       _mix_pool_bytes(&now, sizeof(now));
+       _mix_pool_bytes(&entropy, sizeof(entropy));
        _mix_pool_bytes(buf, size);
        spin_unlock_irqrestore(&input_pool.lock, flags);
 }
 EXPORT_SYMBOL(add_device_randomness);
 
-/* There is one of these per entropy source */
-struct timer_rand_state {
-       unsigned long last_time;
-       long last_delta, last_delta2;
-};
-
-/*
- * This function adds entropy to the entropy "pool" by using timing
- * delays.  It uses the timer_rand_state structure to make an estimate
- * of how many bits of entropy this call has added to the pool.
- *
- * The number "num" is also added to the pool - it should somehow describe
- * the type of event which just happened.  This is currently 0-255 for
- * keyboard scan codes, and 256 upwards for interrupts.
- */
-static void add_timer_randomness(struct timer_rand_state *state, unsigned int num)
-{
-       unsigned long cycles = random_get_entropy(), now = jiffies, flags;
-       long delta, delta2, delta3;
-
-       spin_lock_irqsave(&input_pool.lock, flags);
-       _mix_pool_bytes(&cycles, sizeof(cycles));
-       _mix_pool_bytes(&now, sizeof(now));
-       _mix_pool_bytes(&num, sizeof(num));
-       spin_unlock_irqrestore(&input_pool.lock, flags);
-
-       /*
-        * Calculate number of bits of randomness we probably added.
-        * We take into account the first, second and third-order deltas
-        * in order to make our estimate.
-        */
-       delta = now - READ_ONCE(state->last_time);
-       WRITE_ONCE(state->last_time, now);
-
-       delta2 = delta - READ_ONCE(state->last_delta);
-       WRITE_ONCE(state->last_delta, delta);
-
-       delta3 = delta2 - READ_ONCE(state->last_delta2);
-       WRITE_ONCE(state->last_delta2, delta2);
-
-       if (delta < 0)
-               delta = -delta;
-       if (delta2 < 0)
-               delta2 = -delta2;
-       if (delta3 < 0)
-               delta3 = -delta3;
-       if (delta > delta2)
-               delta = delta2;
-       if (delta > delta3)
-               delta = delta3;
-
-       /*
-        * delta is now minimum absolute delta.
-        * Round down by 1 bit on general principles,
-        * and limit entropy estimate to 12 bits.
-        */
-       credit_entropy_bits(min_t(unsigned int, fls(delta >> 1), 11));
-}
-
-void add_input_randomness(unsigned int type, unsigned int code,
-                         unsigned int value)
-{
-       static unsigned char last_value;
-       static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES };
-
-       /* Ignore autorepeat and the like. */
-       if (value == last_value)
-               return;
-
-       last_value = value;
-       add_timer_randomness(&input_timer_state,
-                            (type << 4) ^ code ^ (code >> 4) ^ value);
-}
-EXPORT_SYMBOL_GPL(add_input_randomness);
-
-#ifdef CONFIG_BLOCK
-void add_disk_randomness(struct gendisk *disk)
-{
-       if (!disk || !disk->random)
-               return;
-       /* First major is 1, so we get >= 0x200 here. */
-       add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
-}
-EXPORT_SYMBOL_GPL(add_disk_randomness);
-
-void rand_initialize_disk(struct gendisk *disk)
-{
-       struct timer_rand_state *state;
-
-       /*
-        * If kzalloc returns null, we just won't use that entropy
-        * source.
-        */
-       state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
-       if (state) {
-               state->last_time = INITIAL_JIFFIES;
-               disk->random = state;
-       }
-}
-#endif
-
 /*
  * Interface for in-kernel drivers of true hardware RNGs.
  * Those devices may produce endless random bits and will be throttled
@@ -1148,39 +990,27 @@ void rand_initialize_disk(struct gendisk *disk)
 void add_hwgenerator_randomness(const void *buffer, size_t count,
                                size_t entropy)
 {
-       if (unlikely(crng_init == 0 && entropy < POOL_MIN_BITS)) {
-               crng_pre_init_inject(buffer, count, true);
-               mix_pool_bytes(buffer, count);
-               return;
-       }
+       mix_pool_bytes(buffer, count);
+       credit_init_bits(entropy);
 
        /*
-        * Throttle writing if we're above the trickle threshold.
-        * We'll be woken up again once below POOL_MIN_BITS, when
-        * the calling thread is about to terminate, or once
-        * CRNG_RESEED_INTERVAL has elapsed.
+        * Throttle writing to once every CRNG_RESEED_INTERVAL, unless
+        * we're not yet initialized.
         */
-       wait_event_interruptible_timeout(random_write_wait,
-                       !system_wq || kthread_should_stop() ||
-                       input_pool.entropy_count < POOL_MIN_BITS,
-                       CRNG_RESEED_INTERVAL);
-       mix_pool_bytes(buffer, count);
-       credit_entropy_bits(entropy);
+       if (!kthread_should_stop() && crng_ready())
+               schedule_timeout_interruptible(CRNG_RESEED_INTERVAL);
 }
 EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
 
 /*
- * Handle random seed passed by bootloader.
- * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
- * it would be regarded as device data.
- * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
+ * Handle random seed passed by bootloader, and credit it if
+ * CONFIG_RANDOM_TRUST_BOOTLOADER is set.
  */
 void add_bootloader_randomness(const void *buf, size_t size)
 {
+       mix_pool_bytes(buf, size);
        if (trust_bootloader)
-               add_hwgenerator_randomness(buf, size, size * 8);
-       else
-               add_device_randomness(buf, size);
+               credit_init_bits(size * 8);
 }
 EXPORT_SYMBOL_GPL(add_bootloader_randomness);
 
@@ -1196,7 +1026,7 @@ void add_vmfork_randomness(const void *unique_vm_id, size_t size)
 {
        add_device_randomness(unique_vm_id, size);
        if (crng_ready()) {
-               crng_reseed(true);
+               crng_reseed();
                pr_notice("crng reseeded due to virtual machine fork\n");
        }
        blocking_notifier_call_chain(&vmfork_chain, 0, NULL);
@@ -1223,17 +1053,15 @@ struct fast_pool {
        unsigned long pool[4];
        unsigned long last;
        unsigned int count;
-       u16 reg_idx;
 };
 
 static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
 #ifdef CONFIG_64BIT
-       /* SipHash constants */
-       .pool = { 0x736f6d6570736575UL, 0x646f72616e646f6dUL,
-                 0x6c7967656e657261UL, 0x7465646279746573UL }
+#define FASTMIX_PERM SIPHASH_PERMUTATION
+       .pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 }
 #else
-       /* HalfSipHash constants */
-       .pool = { 0, 0, 0x6c796765U, 0x74656462U }
+#define FASTMIX_PERM HSIPHASH_PERMUTATION
+       .pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 }
 #endif
 };
 
@@ -1241,27 +1069,16 @@ static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
  * This is [Half]SipHash-1-x, starting from an empty key. Because
  * the key is fixed, it assumes that its inputs are non-malicious,
  * and therefore this has no security on its own. s represents the
- * 128 or 256-bit SipHash state, while v represents a 128-bit input.
+ * four-word SipHash state, while v represents a two-word input.
  */
-static void fast_mix(unsigned long s[4], const unsigned long *v)
+static void fast_mix(unsigned long s[4], unsigned long v1, unsigned long v2)
 {
-       size_t i;
-
-       for (i = 0; i < 16 / sizeof(long); ++i) {
-               s[3] ^= v[i];
-#ifdef CONFIG_64BIT
-               s[0] += s[1]; s[1] = rol64(s[1], 13); s[1] ^= s[0]; s[0] = rol64(s[0], 32);
-               s[2] += s[3]; s[3] = rol64(s[3], 16); s[3] ^= s[2];
-               s[0] += s[3]; s[3] = rol64(s[3], 21); s[3] ^= s[0];
-               s[2] += s[1]; s[1] = rol64(s[1], 17); s[1] ^= s[2]; s[2] = rol64(s[2], 32);
-#else
-               s[0] += s[1]; s[1] = rol32(s[1],  5); s[1] ^= s[0]; s[0] = rol32(s[0], 16);
-               s[2] += s[3]; s[3] = rol32(s[3],  8); s[3] ^= s[2];
-               s[0] += s[3]; s[3] = rol32(s[3],  7); s[3] ^= s[0];
-               s[2] += s[1]; s[1] = rol32(s[1], 13); s[1] ^= s[2]; s[2] = rol32(s[2], 16);
-#endif
-               s[0] ^= v[i];
-       }
+       s[3] ^= v1;
+       FASTMIX_PERM(s[0], s[1], s[2], s[3]);
+       s[0] ^= v1;
+       s[3] ^= v2;
+       FASTMIX_PERM(s[0], s[1], s[2], s[3]);
+       s[0] ^= v2;
 }
 
 #ifdef CONFIG_SMP
@@ -1287,33 +1104,18 @@ int random_online_cpu(unsigned int cpu)
 }
 #endif
 
-static unsigned long get_reg(struct fast_pool *f, struct pt_regs *regs)
-{
-       unsigned long *ptr = (unsigned long *)regs;
-       unsigned int idx;
-
-       if (regs == NULL)
-               return 0;
-       idx = READ_ONCE(f->reg_idx);
-       if (idx >= sizeof(struct pt_regs) / sizeof(unsigned long))
-               idx = 0;
-       ptr += idx++;
-       WRITE_ONCE(f->reg_idx, idx);
-       return *ptr;
-}
-
 static void mix_interrupt_randomness(struct work_struct *work)
 {
        struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
        /*
-        * The size of the copied stack pool is explicitly 16 bytes so that we
-        * tax mix_pool_byte()'s compression function the same amount on all
-        * platforms. This means on 64-bit we copy half the pool into this,
-        * while on 32-bit we copy all of it. The entropy is supposed to be
-        * sufficiently dispersed between bits that in the sponge-like
-        * half case, on average we don't wind up "losing" some.
+        * The size of the copied stack pool is explicitly 2 longs so that we
+        * only ever ingest half of the siphash output each time, retaining
+        * the other half as the next "key" that carries over. The entropy is
+        * supposed to be sufficiently dispersed between bits so on average
+        * we don't wind up "losing" some.
         */
-       u8 pool[16];
+       unsigned long pool[2];
+       unsigned int count;
 
        /* Check to see if we're running on the wrong CPU due to hotplug. */
        local_irq_disable();
@@ -1327,17 +1129,13 @@ static void mix_interrupt_randomness(struct work_struct *work)
         * consistent view, before we reenable irqs again.
         */
        memcpy(pool, fast_pool->pool, sizeof(pool));
+       count = fast_pool->count;
        fast_pool->count = 0;
        fast_pool->last = jiffies;
        local_irq_enable();
 
-       if (unlikely(crng_init == 0)) {
-               crng_pre_init_inject(pool, sizeof(pool), true);
-               mix_pool_bytes(pool, sizeof(pool));
-       } else {
-               mix_pool_bytes(pool, sizeof(pool));
-               credit_entropy_bits(1);
-       }
+       mix_pool_bytes(pool, sizeof(pool));
+       credit_init_bits(max(1u, (count & U16_MAX) / 64));
 
        memzero_explicit(pool, sizeof(pool));
 }
@@ -1345,37 +1143,19 @@ static void mix_interrupt_randomness(struct work_struct *work)
 void add_interrupt_randomness(int irq)
 {
        enum { MIX_INFLIGHT = 1U << 31 };
-       unsigned long cycles = random_get_entropy(), now = jiffies;
+       unsigned long entropy = random_get_entropy();
        struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
        struct pt_regs *regs = get_irq_regs();
        unsigned int new_count;
-       union {
-               u32 u32[4];
-               u64 u64[2];
-               unsigned long longs[16 / sizeof(long)];
-       } irq_data;
 
-       if (cycles == 0)
-               cycles = get_reg(fast_pool, regs);
-
-       if (sizeof(unsigned long) == 8) {
-               irq_data.u64[0] = cycles ^ rol64(now, 32) ^ irq;
-               irq_data.u64[1] = regs ? instruction_pointer(regs) : _RET_IP_;
-       } else {
-               irq_data.u32[0] = cycles ^ irq;
-               irq_data.u32[1] = now;
-               irq_data.u32[2] = regs ? instruction_pointer(regs) : _RET_IP_;
-               irq_data.u32[3] = get_reg(fast_pool, regs);
-       }
-
-       fast_mix(fast_pool->pool, irq_data.longs);
+       fast_mix(fast_pool->pool, entropy,
+                (regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq));
        new_count = ++fast_pool->count;
 
        if (new_count & MIX_INFLIGHT)
                return;
 
-       if (new_count < 64 && (!time_after(now, fast_pool->last + HZ) ||
-                              unlikely(crng_init == 0)))
+       if (new_count < 64 && !time_is_before_jiffies(fast_pool->last + HZ))
                return;
 
        if (unlikely(!fast_pool->mix.func))
@@ -1385,6 +1165,133 @@ void add_interrupt_randomness(int irq)
 }
 EXPORT_SYMBOL_GPL(add_interrupt_randomness);
 
+/* There is one of these per entropy source */
+struct timer_rand_state {
+       unsigned long last_time;
+       long last_delta, last_delta2;
+};
+
+/*
+ * This function adds entropy to the entropy "pool" by using timing
+ * delays. It uses the timer_rand_state structure to make an estimate
+ * of how many bits of entropy this call has added to the pool. The
+ * value "num" is also added to the pool; it should somehow describe
+ * the type of event that just happened.
+ */
+static void add_timer_randomness(struct timer_rand_state *state, unsigned int num)
+{
+       unsigned long entropy = random_get_entropy(), now = jiffies, flags;
+       long delta, delta2, delta3;
+       unsigned int bits;
+
+       /*
+        * If we're in a hard IRQ, add_interrupt_randomness() will be called
+        * sometime after, so mix into the fast pool.
+        */
+       if (in_hardirq()) {
+               fast_mix(this_cpu_ptr(&irq_randomness)->pool, entropy, num);
+       } else {
+               spin_lock_irqsave(&input_pool.lock, flags);
+               _mix_pool_bytes(&entropy, sizeof(entropy));
+               _mix_pool_bytes(&num, sizeof(num));
+               spin_unlock_irqrestore(&input_pool.lock, flags);
+       }
+
+       if (crng_ready())
+               return;
+
+       /*
+        * Calculate number of bits of randomness we probably added.
+        * We take into account the first, second and third-order deltas
+        * in order to make our estimate.
+        */
+       delta = now - READ_ONCE(state->last_time);
+       WRITE_ONCE(state->last_time, now);
+
+       delta2 = delta - READ_ONCE(state->last_delta);
+       WRITE_ONCE(state->last_delta, delta);
+
+       delta3 = delta2 - READ_ONCE(state->last_delta2);
+       WRITE_ONCE(state->last_delta2, delta2);
+
+       if (delta < 0)
+               delta = -delta;
+       if (delta2 < 0)
+               delta2 = -delta2;
+       if (delta3 < 0)
+               delta3 = -delta3;
+       if (delta > delta2)
+               delta = delta2;
+       if (delta > delta3)
+               delta = delta3;
+
+       /*
+        * delta is now minimum absolute delta. Round down by 1 bit
+        * on general principles, and limit entropy estimate to 11 bits.
+        */
+       bits = min(fls(delta >> 1), 11);
+
+       /*
+        * As mentioned above, if we're in a hard IRQ, add_interrupt_randomness()
+        * will run after this, which uses a different crediting scheme of 1 bit
+        * per every 64 interrupts. In order to let that function do accounting
+        * close to the one in this function, we credit a full 64/64 bit per bit,
+        * and then subtract one to account for the extra one added.
+        */
+       if (in_hardirq())
+               this_cpu_ptr(&irq_randomness)->count += max(1u, bits * 64) - 1;
+       else
+               credit_init_bits(bits);
+}
+
+void add_input_randomness(unsigned int type, unsigned int code,
+                         unsigned int value)
+{
+       static unsigned char last_value;
+       static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES };
+
+       /* Ignore autorepeat and the like. */
+       if (value == last_value)
+               return;
+
+       last_value = value;
+       add_timer_randomness(&input_timer_state,
+                            (type << 4) ^ code ^ (code >> 4) ^ value);
+}
+EXPORT_SYMBOL_GPL(add_input_randomness);
+
+#ifdef CONFIG_BLOCK
+void add_disk_randomness(struct gendisk *disk)
+{
+       if (!disk || !disk->random)
+               return;
+       /* First major is 1, so we get >= 0x200 here. */
+       add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
+}
+EXPORT_SYMBOL_GPL(add_disk_randomness);
+
+void rand_initialize_disk(struct gendisk *disk)
+{
+       struct timer_rand_state *state;
+
+       /*
+        * If kzalloc returns null, we just won't use that entropy
+        * source.
+        */
+       state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
+       if (state) {
+               state->last_time = INITIAL_JIFFIES;
+               disk->random = state;
+       }
+}
+#endif
+
+struct entropy_timer_state {
+       unsigned long entropy;
+       struct timer_list timer;
+       unsigned int samples, samples_per_bit;
+};
+
 /*
  * Each time the timer fires, we expect that we got an unpredictable
  * jump in the cycle counter. Even if the timer is running on another
@@ -1398,9 +1305,14 @@ EXPORT_SYMBOL_GPL(add_interrupt_randomness);
  *
  * So the re-arming always happens in the entropy loop itself.
  */
-static void entropy_timer(struct timer_list *t)
+static void entropy_timer(struct timer_list *timer)
 {
-       credit_entropy_bits(1);
+       struct entropy_timer_state *state = container_of(timer, struct entropy_timer_state, timer);
+
+       if (++state->samples == state->samples_per_bit) {
+               credit_init_bits(1);
+               state->samples = 0;
+       }
 }
 
 /*
@@ -1409,29 +1321,34 @@ static void entropy_timer(struct timer_list *t)
  */
 static void try_to_generate_entropy(void)
 {
-       struct {
-               unsigned long cycles;
-               struct timer_list timer;
-       } stack;
-
-       stack.cycles = random_get_entropy();
-
-       /* Slow counter - or none. Don't even bother */
-       if (stack.cycles == random_get_entropy())
+       enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = 32 };
+       struct entropy_timer_state stack;
+       unsigned int i, num_different = 0;
+       unsigned long last = random_get_entropy();
+
+       for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) {
+               stack.entropy = random_get_entropy();
+               if (stack.entropy != last)
+                       ++num_different;
+               last = stack.entropy;
+       }
+       stack.samples_per_bit = DIV_ROUND_UP(NUM_TRIAL_SAMPLES, num_different + 1);
+       if (stack.samples_per_bit > MAX_SAMPLES_PER_BIT)
                return;
 
+       stack.samples = 0;
        timer_setup_on_stack(&stack.timer, entropy_timer, 0);
        while (!crng_ready() && !signal_pending(current)) {
                if (!timer_pending(&stack.timer))
                        mod_timer(&stack.timer, jiffies + 1);
-               mix_pool_bytes(&stack.cycles, sizeof(stack.cycles));
+               mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
                schedule();
-               stack.cycles = random_get_entropy();
+               stack.entropy = random_get_entropy();
        }
 
        del_timer_sync(&stack.timer);
        destroy_timer_on_stack(&stack.timer);
-       mix_pool_bytes(&stack.cycles, sizeof(stack.cycles));
+       mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
 }
 
 
@@ -1493,16 +1410,8 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
 
 static __poll_t random_poll(struct file *file, poll_table *wait)
 {
-       __poll_t mask;
-
        poll_wait(file, &crng_init_wait, wait);
-       poll_wait(file, &random_write_wait, wait);
-       mask = 0;
-       if (crng_ready())
-               mask |= EPOLLIN | EPOLLRDNORM;
-       if (input_pool.entropy_count < POOL_MIN_BITS)
-               mask |= EPOLLOUT | EPOLLWRNORM;
-       return mask;
+       return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
 }
 
 static int write_pool(const char __user *ubuf, size_t count)
@@ -1552,11 +1461,14 @@ static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
        if (!crng_ready())
                try_to_generate_entropy();
 
-       if (!crng_ready() && maxwarn > 0) {
-               maxwarn--;
-               if (__ratelimit(&urandom_warning))
+       if (!crng_ready()) {
+               if (!ratelimit_disable && maxwarn <= 0)
+                       ++urandom_warning.missed;
+               else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
+                       --maxwarn;
                        pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
                                  current->comm, nbytes);
+               }
        }
 
        return get_random_bytes_user(buf, nbytes);
@@ -1582,7 +1494,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
        switch (cmd) {
        case RNDGETENTCNT:
                /* Inherently racy, no point locking. */
-               if (put_user(input_pool.entropy_count, p))
+               if (put_user(input_pool.init_bits, p))
                        return -EFAULT;
                return 0;
        case RNDADDTOENTCNT:
@@ -1592,7 +1504,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                        return -EFAULT;
                if (ent_count < 0)
                        return -EINVAL;
-               credit_entropy_bits(ent_count);
+               credit_init_bits(ent_count);
                return 0;
        case RNDADDENTROPY:
                if (!capable(CAP_SYS_ADMIN))
@@ -1606,27 +1518,20 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                retval = write_pool((const char __user *)p, size);
                if (retval < 0)
                        return retval;
-               credit_entropy_bits(ent_count);
+               credit_init_bits(ent_count);
                return 0;
        case RNDZAPENTCNT:
        case RNDCLEARPOOL:
-               /*
-                * Clear the entropy pool counters. We no longer clear
-                * the entropy pool, as that's silly.
-                */
+               /* No longer has any effect. */
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (xchg(&input_pool.entropy_count, 0) >= POOL_MIN_BITS) {
-                       wake_up_interruptible(&random_write_wait);
-                       kill_fasync(&fasync, SIGIO, POLL_OUT);
-               }
                return 0;
        case RNDRESEEDCRNG:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
                if (!crng_ready())
                        return -ENODATA;
-               crng_reseed(false);
+               crng_reseed();
                return 0;
        default:
                return -EINVAL;
@@ -1678,7 +1583,7 @@ const struct file_operations urandom_fops = {
  *
  * - write_wakeup_threshold - the amount of entropy in the input pool
  *   below which write polls to /dev/random will unblock, requesting
- *   more entropy, tied to the POOL_MIN_BITS constant. It is writable
+ *   more entropy, tied to the POOL_READY_BITS constant. It is writable
  *   to avoid breaking old userspaces, but writing to it does not
  *   change any behavior of the RNG.
  *
@@ -1693,7 +1598,7 @@ const struct file_operations urandom_fops = {
 #include <linux/sysctl.h>
 
 static int sysctl_random_min_urandom_seed = CRNG_RESEED_INTERVAL / HZ;
-static int sysctl_random_write_wakeup_bits = POOL_MIN_BITS;
+static int sysctl_random_write_wakeup_bits = POOL_READY_BITS;
 static int sysctl_poolsize = POOL_BITS;
 static u8 sysctl_bootid[UUID_SIZE];
 
@@ -1749,7 +1654,7 @@ static struct ctl_table random_table[] = {
        },
        {
                .procname       = "entropy_avail",
-               .data           = &input_pool.entropy_count,
+               .data           = &input_pool.init_bits,
                .maxlen         = sizeof(int),
                .mode           = 0444,
                .proc_handler   = proc_dointvec,
@@ -1783,8 +1688,8 @@ static struct ctl_table random_table[] = {
 };
 
 /*
- * rand_initialize() is called before sysctl_init(),
- * so we cannot call register_sysctl_init() in rand_initialize()
+ * random_init() is called before sysctl_init(),
+ * so we cannot call register_sysctl_init() in random_init()
  */
 static int __init random_sysctls_init(void)
 {