if (!r->initialized && nbits > 0) {
r->entropy_total += nbits;
- if (r->entropy_total > 128)
+ if (r->entropy_total > 128) {
r->initialized = 1;
+ if (r == &nonblocking_pool)
+ prandom_reseed_late();
+ }
}
trace_credit_entropy_bits(r->name, nbits, entropy_count,
u32 prandom_u32(void);
void prandom_bytes(void *buf, int nbytes);
void prandom_seed(u32 seed);
+void prandom_reseed_late(void);
u32 prandom_u32_state(struct rnd_state *);
void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
* Generate better values after random number generator
* is fully initialized.
*/
-static int __init prandom_reseed(void)
+static void __prandom_reseed(bool late)
{
int i;
+ unsigned long flags;
+ static bool latch = false;
+ static DEFINE_SPINLOCK(lock);
+
+ /* only allow initial seeding (late == false) once */
+ spin_lock_irqsave(&lock, flags);
+ if (latch && !late)
+ goto out;
+ latch = true;
for_each_possible_cpu(i) {
struct rnd_state *state = &per_cpu(net_rand_state,i);
/* mix it in */
prandom_u32_state(state);
}
+out:
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+void prandom_reseed_late(void)
+{
+ __prandom_reseed(true);
+}
+
+static int __init prandom_reseed(void)
+{
+ __prandom_reseed(false);
prandom_start_seed_timer();
return 0;
}