From a6a4d97f0d7686f94a11193d82286e25d53266bb Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Wed, 19 Feb 2025 22:00:31 +0100 Subject: [PATCH 1/8] random: add missing words in function comments s/good as/as good as/ Signed-off-by: Thorsten Blum Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index b8b24b6ed3fe..654b1fda52f0 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -427,7 +427,7 @@ static void _get_random_bytes(void *buf, size_t len) /* * This returns random bytes in arbitrary quantities. The quality of the - * random bytes is good as /dev/urandom. In order to ensure that the + * random bytes is as good as /dev/urandom. In order to ensure that the * randomness provided by this function is okay, the function * wait_for_random_bytes() should be called and return 0 at least once * at any point prior. @@ -491,7 +491,7 @@ out_zero_chacha: /* * Batched entropy returns random integers. The quality of the random - * number is good as /dev/urandom. In order to ensure that the randomness + * number is as good as /dev/urandom. In order to ensure that the randomness * provided by this function is okay, the function wait_for_random_bytes() * should be called and return 0 at least once at any point prior. */ From 8c0cf6542e040831ffa05221d8222dd650314a36 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Tue, 11 Feb 2025 07:33:31 +0100 Subject: [PATCH 2/8] media: vivid: use prandom This is part of a prandom cleanup, which removes next_pseudo_random32 and replaces it with the standard PRNG. Signed-off-by: Markus Theil Reviewed-by: Krzysztof Karas Signed-off-by: Jason A. Donenfeld --- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index 8b3162e82032..b95f06a9b5ae 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -302,8 +302,10 @@ void vivid_update_quality(struct vivid_dev *dev) */ freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16); if (freq_modulus > 2 * 16) { + struct rnd_state prng; + prandom_seed_state(&prng, dev->tv_freq ^ 0x55); tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, - next_pseudo_random32(dev->tv_freq ^ 0x55) & 0x3f); + prandom_u32_state(&prng) & 0x3f); return; } if (freq_modulus < 12 /*0.75 * 16*/ || freq_modulus > 20 /*1.25 * 16*/) From 3c0c81de525d2a2718e23754a5795483167904ac Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Tue, 11 Feb 2025 07:33:32 +0100 Subject: [PATCH 3/8] prandom: remove next_pseudo_random32 next_pseudo_random32 implements a LCG with known bad statistical properties and was only used in two pieces of testing code. With no remaining users now, remove it. Signed-off-by: Markus Theil Reviewed-by: Krzysztof Karas Signed-off-by: Jason A. Donenfeld --- include/linux/prandom.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/linux/prandom.h b/include/linux/prandom.h index f2ed5b72b3d6..ff7dcc3fa105 100644 --- a/include/linux/prandom.h +++ b/include/linux/prandom.h @@ -47,10 +47,4 @@ static inline void prandom_seed_state(struct rnd_state *state, u64 seed) state->s4 = __seed(i, 128U); } -/* Pseudo random number generator from numerical recipes. */ -static inline u32 next_pseudo_random32(u32 seed) -{ - return seed * 1664525 + 1013904223; -} - #endif From 5d49f1a5bd358d24e5f88b23b46da833de1dbec8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Jun 2025 11:27:08 +0200 Subject: [PATCH 4/8] random: use offstack cpumask when necessary The entropy generation function keeps a local cpu mask on the stack, which can trigger warnings in configurations with a large number of CPUs: drivers/char/random.c:1292:20: error: stack frame size (1288) exceeds limit (1280) in 'try_to_generate_entropy' [-Werror,-Wframe-larger-than] Use the cpumask interface to dynamically allocate it in those configurations. Fixes: 1c21fe00eda7 ("random: spread out jitter callback to different CPUs") Signed-off-by: Arnd Bergmann Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 654b1fda52f0..d45383d57919 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1296,6 +1296,7 @@ static void __cold try_to_generate_entropy(void) struct entropy_timer_state *stack = PTR_ALIGN((void *)stack_bytes, SMP_CACHE_BYTES); unsigned int i, num_different = 0; unsigned long last = random_get_entropy(); + cpumask_var_t timer_cpus; int cpu = -1; for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) { @@ -1310,13 +1311,15 @@ static void __cold try_to_generate_entropy(void) atomic_set(&stack->samples, 0); timer_setup_on_stack(&stack->timer, entropy_timer, 0); + if (!alloc_cpumask_var(&timer_cpus, GFP_KERNEL)) + goto out; + while (!crng_ready() && !signal_pending(current)) { /* * Check !timer_pending() and then ensure that any previous callback has finished * executing by checking timer_delete_sync_try(), before queueing the next one. */ if (!timer_pending(&stack->timer) && timer_delete_sync_try(&stack->timer) >= 0) { - struct cpumask timer_cpus; unsigned int num_cpus; /* @@ -1326,19 +1329,19 @@ static void __cold try_to_generate_entropy(void) preempt_disable(); /* Only schedule callbacks on timer CPUs that are online. */ - cpumask_and(&timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); - num_cpus = cpumask_weight(&timer_cpus); + cpumask_and(timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); + num_cpus = cpumask_weight(timer_cpus); /* In very bizarre case of misconfiguration, fallback to all online. */ if (unlikely(num_cpus == 0)) { - timer_cpus = *cpu_online_mask; - num_cpus = cpumask_weight(&timer_cpus); + *timer_cpus = *cpu_online_mask; + num_cpus = cpumask_weight(timer_cpus); } /* Basic CPU round-robin, which avoids the current CPU. */ do { - cpu = cpumask_next(cpu, &timer_cpus); + cpu = cpumask_next(cpu, timer_cpus); if (cpu >= nr_cpu_ids) - cpu = cpumask_first(&timer_cpus); + cpu = cpumask_first(timer_cpus); } while (cpu == smp_processor_id() && num_cpus > 1); /* Expiring the timer at `jiffies` means it's the next tick. */ @@ -1354,6 +1357,8 @@ static void __cold try_to_generate_entropy(void) } mix_pool_bytes(&stack->entropy, sizeof(stack->entropy)); + free_cpumask_var(timer_cpus); +out: timer_delete_sync(&stack->timer); timer_destroy_on_stack(&stack->timer); } From aba5f969f886d298c7fc777538a12b52095203ab Mon Sep 17 00:00:00 2001 From: Marco Crivellari Date: Thu, 30 Oct 2025 16:57:28 +0100 Subject: [PATCH 5/8] random: replace use of system_unbound_wq with system_dfl_wq system_unbound_wq has been renamed to system_dfl_wq in 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq"), so update random.c's usage of it system_unbound_wq to reflect the new change. The old system_unbound_wq is slated for removal in the next few cycles. Suggested-by: Tejun Heo Signed-off-by: Marco Crivellari Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index d45383d57919..6873ec481d73 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -259,8 +259,8 @@ static void crng_reseed(struct work_struct *work) u8 key[CHACHA_KEY_SIZE]; /* Immediately schedule the next reseeding, so that it fires sooner rather than later. */ - if (likely(system_unbound_wq)) - queue_delayed_work(system_unbound_wq, &next_reseed, crng_reseed_interval()); + if (likely(system_dfl_wq)) + queue_delayed_work(system_dfl_wq, &next_reseed, crng_reseed_interval()); extract_entropy(key, sizeof(key)); @@ -741,8 +741,8 @@ static void __cold _credit_init_bits(size_t bits) if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { crng_reseed(NULL); /* Sets crng_init to CRNG_READY under base_crng.lock. */ - if (static_key_initialized && system_unbound_wq) - queue_work(system_unbound_wq, &set_ready); + if (static_key_initialized && system_dfl_wq) + queue_work(system_dfl_wq, &set_ready); atomic_notifier_call_chain(&random_ready_notifier, 0, NULL); #ifdef CONFIG_VDSO_GETRANDOM WRITE_ONCE(vdso_k_rng_data->is_ready, true); From 933ecf591275e850a46b28c6016d2688b92e23f6 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 1 Nov 2025 21:19:41 -0700 Subject: [PATCH 6/8] random: remove unused get_random_var_wait functions None of these functions are used, so remove them. This renders the two bugs moot: - get_random_u64_wait() used the wrong pointer type, making it provide only 32 bits. - The '#undef' directive used the wrong identifier, leaving the helper macro defined. Signed-off-by: Eric Biggers Signed-off-by: Jason A. Donenfeld --- include/linux/random.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/include/linux/random.h b/include/linux/random.h index 333cecfca93f..8a8064dc3970 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -130,21 +130,6 @@ static inline int get_random_bytes_wait(void *buf, size_t nbytes) return ret; } -#define declare_get_random_var_wait(name, ret_type) \ - static inline int get_random_ ## name ## _wait(ret_type *out) { \ - int ret = wait_for_random_bytes(); \ - if (unlikely(ret)) \ - return ret; \ - *out = get_random_ ## name(); \ - return 0; \ - } -declare_get_random_var_wait(u8, u8) -declare_get_random_var_wait(u16, u16) -declare_get_random_var_wait(u32, u32) -declare_get_random_var_wait(u64, u32) -declare_get_random_var_wait(long, unsigned long) -#undef declare_get_random_var - #ifdef CONFIG_SMP int random_prepare_cpu(unsigned int cpu); int random_online_cpu(unsigned int cpu); From 2db833312d7e6ae22111a6fd3e733b2a14986a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 11 Nov 2025 01:13:06 +0100 Subject: [PATCH 7/8] random: drop check for static_key_initialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit e871abcda3b6 ("random: handle creditable entropy from atomic process context") added the use of workqueues, which meant testing whether the workqueue is valid, but it did not remove the existing check of whether static keys have been initialized. This static key check is unnecessary because workqueues are initialized long after it. And semantically it doesn't make much sense either, because it's not really directly calling a static key function in the condition. Remove the now unnecessary check. Signed-off-by: Thomas Weißschuh [Jason: rewrite commit message with different explanation, rebase on random.git, and update code comment.] Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 6873ec481d73..2c7195c942c3 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -741,7 +741,7 @@ static void __cold _credit_init_bits(size_t bits) if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { crng_reseed(NULL); /* Sets crng_init to CRNG_READY under base_crng.lock. */ - if (static_key_initialized && system_dfl_wq) + if (system_dfl_wq) queue_work(system_dfl_wq, &set_ready); atomic_notifier_call_chain(&random_ready_notifier, 0, NULL); #ifdef CONFIG_VDSO_GETRANDOM @@ -915,9 +915,8 @@ void __init random_init(void) add_latent_entropy(); /* - * If we were initialized by the cpu or bootloader before jump labels - * or workqueues are initialized, then we should enable the static - * branch here, where it's guaranteed that these have been initialized. + * If we were initialized by the cpu or bootloader before workqueues + * are initialized, then we should enable the static branch here. */ if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY) crng_set_ready(NULL); From 90fb9b98fcf5e668a13676d6e8cd546b6990d002 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Nov 2025 02:54:37 +0100 Subject: [PATCH 8/8] random: complete sentence of comment Complete the sentence by adding "is set", rather than having it dangle as a sentence fragment. Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 2c7195c942c3..5a625b091e63 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -794,7 +794,7 @@ static void __cold _credit_init_bits(size_t bits) * * add_bootloader_randomness() is called by bootloader drivers, such as EFI * and device tree, and credits its input depending on whether or not the - * command line option 'random.trust_bootloader'. + * command line option '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,