Skip to content

Commit 791b50a

Browse files
Sebastian Andrzej Siewiorrostedt
Sebastian Andrzej Siewior
authored andcommitted
random: avoid preempt_disable()ed section
extract_crng() will use sleeping locks while in a preempt_disable() section due to get_cpu_var(). Work around it with local_locks. Cc: [email protected] # where it applies to Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
1 parent c6a674a commit 791b50a

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/char/random.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@
265265
#include <linux/syscalls.h>
266266
#include <linux/completion.h>
267267
#include <linux/uuid.h>
268+
#include <linux/locallock.h>
268269
#include <crypto/chacha20.h>
269270

270271
#include <asm/processor.h>
@@ -2188,6 +2189,7 @@ static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_
21882189
* at any point prior.
21892190
*/
21902191
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
2192+
static DEFINE_LOCAL_IRQ_LOCK(batched_entropy_u64_lock);
21912193
u64 get_random_u64(void)
21922194
{
21932195
u64 ret;
@@ -2208,7 +2210,7 @@ u64 get_random_u64(void)
22082210
warn_unseeded_randomness(&previous);
22092211

22102212
use_lock = READ_ONCE(crng_init) < 2;
2211-
batch = &get_cpu_var(batched_entropy_u64);
2213+
batch = &get_locked_var(batched_entropy_u64_lock, batched_entropy_u64);
22122214
if (use_lock)
22132215
read_lock_irqsave(&batched_entropy_reset_lock, flags);
22142216
if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
@@ -2218,12 +2220,13 @@ u64 get_random_u64(void)
22182220
ret = batch->entropy_u64[batch->position++];
22192221
if (use_lock)
22202222
read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
2221-
put_cpu_var(batched_entropy_u64);
2223+
put_locked_var(batched_entropy_u64_lock, batched_entropy_u64);
22222224
return ret;
22232225
}
22242226
EXPORT_SYMBOL(get_random_u64);
22252227

22262228
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
2229+
static DEFINE_LOCAL_IRQ_LOCK(batched_entropy_u32_lock);
22272230
u32 get_random_u32(void)
22282231
{
22292232
u32 ret;
@@ -2238,7 +2241,7 @@ u32 get_random_u32(void)
22382241
warn_unseeded_randomness(&previous);
22392242

22402243
use_lock = READ_ONCE(crng_init) < 2;
2241-
batch = &get_cpu_var(batched_entropy_u32);
2244+
batch = &get_locked_var(batched_entropy_u32_lock, batched_entropy_u32);
22422245
if (use_lock)
22432246
read_lock_irqsave(&batched_entropy_reset_lock, flags);
22442247
if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
@@ -2248,7 +2251,7 @@ u32 get_random_u32(void)
22482251
ret = batch->entropy_u32[batch->position++];
22492252
if (use_lock)
22502253
read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
2251-
put_cpu_var(batched_entropy_u32);
2254+
put_locked_var(batched_entropy_u32_lock, batched_entropy_u32);
22522255
return ret;
22532256
}
22542257
EXPORT_SYMBOL(get_random_u32);

0 commit comments

Comments
 (0)