diff options
-rw-r--r-- | drivers/char/random.c | 1 | ||||
-rw-r--r-- | include/linux/random.h | 3 | ||||
-rw-r--r-- | kernel/time/timer.c | 8 | ||||
-rw-r--r-- | lib/random32.c | 2 |
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. |