Skip to content

Commit 9926c09

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 846a017 commit 9926c09

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>
@@ -2196,6 +2197,7 @@ static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_
21962197
* at any point prior.
21972198
*/
21982199
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
2200+
static DEFINE_LOCAL_IRQ_LOCK(batched_entropy_u64_lock);
21992201
u64 get_random_u64(void)
22002202
{
22012203
u64 ret;
@@ -2216,7 +2218,7 @@ u64 get_random_u64(void)
22162218
warn_unseeded_randomness(&previous);
22172219

22182220
use_lock = READ_ONCE(crng_init) < 2;
2219-
batch = &get_cpu_var(batched_entropy_u64);
2221+
batch = &get_locked_var(batched_entropy_u64_lock, batched_entropy_u64);
22202222
if (use_lock)
22212223
read_lock_irqsave(&batched_entropy_reset_lock, flags);
22222224
if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
@@ -2226,12 +2228,13 @@ u64 get_random_u64(void)
22262228
ret = batch->entropy_u64[batch->position++];
22272229
if (use_lock)
22282230
read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
2229-
put_cpu_var(batched_entropy_u64);
2231+
put_locked_var(batched_entropy_u64_lock, batched_entropy_u64);
22302232
return ret;
22312233
}
22322234
EXPORT_SYMBOL(get_random_u64);
22332235

22342236
static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
2237+
static DEFINE_LOCAL_IRQ_LOCK(batched_entropy_u32_lock);
22352238
u32 get_random_u32(void)
22362239
{
22372240
u32 ret;
@@ -2246,7 +2249,7 @@ u32 get_random_u32(void)
22462249
warn_unseeded_randomness(&previous);
22472250

22482251
use_lock = READ_ONCE(crng_init) < 2;
2249-
batch = &get_cpu_var(batched_entropy_u32);
2252+
batch = &get_locked_var(batched_entropy_u32_lock, batched_entropy_u32);
22502253
if (use_lock)
22512254
read_lock_irqsave(&batched_entropy_reset_lock, flags);
22522255
if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
@@ -2256,7 +2259,7 @@ u32 get_random_u32(void)
22562259
ret = batch->entropy_u32[batch->position++];
22572260
if (use_lock)
22582261
read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
2259-
put_cpu_var(batched_entropy_u32);
2262+
put_locked_var(batched_entropy_u32_lock, batched_entropy_u32);
22602263
return ret;
22612264
}
22622265
EXPORT_SYMBOL(get_random_u32);

0 commit comments

Comments
 (0)