diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-05-12 15:46:17 +0200 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2018-01-17 10:08:35 -0500 |
commit | 7975c54fb2af4e4fcf0ac6426318e929906f1e91 (patch) | |
tree | 59825928f03f9c87343eb2b8865a3aa113bde36d | |
parent | 70855fa44c8039f15289199f6fab8c487b218e61 (diff) | |
download | linux-rt-7975c54fb2af4e4fcf0ac6426318e929906f1e91.tar.gz |
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: stable-rt@vger.kernel.org # where it applies to
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r-- | drivers/char/random.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index acb8e7c218d1..06c4b06fcea0 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -260,6 +260,7 @@ #include <linux/irq.h> #include <linux/syscalls.h> #include <linux/completion.h> +#include <linux/locallock.h> #include <asm/processor.h> #include <asm/uaccess.h> @@ -1712,6 +1713,7 @@ int random_int_secret_init(void) static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) __aligned(sizeof(unsigned long)); +static DEFINE_LOCAL_IRQ_LOCK(hash_entropy_int_lock); /* * Get a random word for internal kernel use only. Similar to urandom but @@ -1727,12 +1729,12 @@ unsigned int get_random_int(void) if (arch_get_random_int(&ret)) return ret; - hash = get_cpu_var(get_random_int_hash); + hash = get_locked_var(hash_entropy_int_lock, get_random_int_hash); hash[0] += current->pid + jiffies + random_get_entropy(); md5_transform(hash, random_int_secret); ret = hash[0]; - put_cpu_var(get_random_int_hash); + put_locked_var(hash_entropy_int_lock, get_random_int_hash); return ret; } @@ -1749,12 +1751,12 @@ unsigned long get_random_long(void) if (arch_get_random_long(&ret)) return ret; - hash = get_cpu_var(get_random_int_hash); + hash = get_locked_var(hash_entropy_int_lock, get_random_int_hash); hash[0] += current->pid + jiffies + random_get_entropy(); md5_transform(hash, random_int_secret); ret = *(unsigned long *)hash; - put_cpu_var(get_random_int_hash); + put_locked_var(hash_entropy_int_lock, get_random_int_hash); return ret; } |