summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/random.c1
-rw-r--r--include/linux/random.h3
-rw-r--r--kernel/time/timer.c8
-rw-r--r--lib/random32.c2
4 files changed, 13 insertions, 1 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 661ed5ec546e..7bb1e423eb19 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -923,6 +923,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
fast_mix(fast_pool);
add_interrupt_bench(cycles);
+ this_cpu_add(net_rand_state.s1, fast_pool->pool[cycles & 3]);
if ((fast_pool->count < 64) &&
!time_after(now, fast_pool->last + HZ))
diff --git a/include/linux/random.h b/include/linux/random.h
index 9c29122037f9..fb9e3798f771 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -8,6 +8,7 @@
#include <linux/list.h>
#include <linux/once.h>
+#include <linux/percpu.h>
#include <uapi/linux/random.h>
@@ -46,6 +47,8 @@ struct rnd_state {
__u32 s1, s2, s3, s4;
};
+DECLARE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy;
+
u32 prandom_u32_state(struct rnd_state *state);
void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state);
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 3d7588a2e97c..43bee4993187 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -42,6 +42,7 @@
#include <linux/sched/sysctl.h>
#include <linux/slab.h>
#include <linux/compat.h>
+#include <linux/random.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -1431,6 +1432,13 @@ void update_process_times(int user_tick)
#endif
scheduler_tick();
run_posix_cpu_timers(p);
+
+ /* The current CPU might make use of net randoms without receiving IRQs
+ * to renew them often enough. Let's update the net_rand_state from a
+ * non-constant value that's not affine to the number of calls to make
+ * sure it's updated when there's some activity (we don't care in idle).
+ */
+ this_cpu_add(net_rand_state.s1, rol32(jiffies, 24) + user_tick);
}
/*
diff --git a/lib/random32.c b/lib/random32.c
index 12111910ccd0..8072ccd9eed5 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -47,7 +47,7 @@ static inline void prandom_state_selftest(void)
}
#endif
-static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
+DEFINE_PER_CPU(struct rnd_state, net_rand_state);
/**
* prandom_u32_state - seeded pseudo-random number generator.