diff options
author | Theodore Ts'o <tytso@mit.edu> | 2012-07-05 10:21:01 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-07-14 20:17:46 -0400 |
commit | e6d4947b12e8ad947add1032dd754803c6004824 (patch) | |
tree | cfbfba88cf3dc1ffb01634a6eed68a220d4a13c7 /drivers/char | |
parent | 7bf2357524408b97fec58344caf7397f8140c3fd (diff) |
random: use the arch-specific rng in xfer_secondary_pool
If the CPU supports a hardware random number generator, use it in
xfer_secondary_pool(), where it will significantly improve things and
where we can afford it.
Also, remove the use of the arch-specific rng in
add_timer_randomness(), since the call is significantly slower than
get_cycles(), and we're much better off using it in
xfer_secondary_pool() anyway.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/random.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index df3358ab5b99..f67ae3e473ba 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -254,6 +254,7 @@ | |||
254 | #include <linux/cryptohash.h> | 254 | #include <linux/cryptohash.h> |
255 | #include <linux/fips.h> | 255 | #include <linux/fips.h> |
256 | #include <linux/ptrace.h> | 256 | #include <linux/ptrace.h> |
257 | #include <linux/kmemcheck.h> | ||
257 | 258 | ||
258 | #ifdef CONFIG_GENERIC_HARDIRQS | 259 | #ifdef CONFIG_GENERIC_HARDIRQS |
259 | # include <linux/irq.h> | 260 | # include <linux/irq.h> |
@@ -702,11 +703,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
702 | goto out; | 703 | goto out; |
703 | 704 | ||
704 | sample.jiffies = jiffies; | 705 | sample.jiffies = jiffies; |
705 | 706 | sample.cycles = get_cycles(); | |
706 | /* Use arch random value, fall back to cycles */ | ||
707 | if (!arch_get_random_int(&sample.cycles)) | ||
708 | sample.cycles = get_cycles(); | ||
709 | |||
710 | sample.num = num; | 707 | sample.num = num; |
711 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); | 708 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); |
712 | 709 | ||
@@ -838,7 +835,11 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
838 | */ | 835 | */ |
839 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | 836 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
840 | { | 837 | { |
841 | __u32 tmp[OUTPUT_POOL_WORDS]; | 838 | union { |
839 | __u32 tmp[OUTPUT_POOL_WORDS]; | ||
840 | long hwrand[4]; | ||
841 | } u; | ||
842 | int i; | ||
842 | 843 | ||
843 | if (r->pull && r->entropy_count < nbytes * 8 && | 844 | if (r->pull && r->entropy_count < nbytes * 8 && |
844 | r->entropy_count < r->poolinfo->POOLBITS) { | 845 | r->entropy_count < r->poolinfo->POOLBITS) { |
@@ -849,17 +850,23 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
849 | /* pull at least as many as BYTES as wakeup BITS */ | 850 | /* pull at least as many as BYTES as wakeup BITS */ |
850 | bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); | 851 | bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); |
851 | /* but never more than the buffer size */ | 852 | /* but never more than the buffer size */ |
852 | bytes = min_t(int, bytes, sizeof(tmp)); | 853 | bytes = min_t(int, bytes, sizeof(u.tmp)); |
853 | 854 | ||
854 | DEBUG_ENT("going to reseed %s with %d bits " | 855 | DEBUG_ENT("going to reseed %s with %d bits " |
855 | "(%d of %d requested)\n", | 856 | "(%d of %d requested)\n", |
856 | r->name, bytes * 8, nbytes * 8, r->entropy_count); | 857 | r->name, bytes * 8, nbytes * 8, r->entropy_count); |
857 | 858 | ||
858 | bytes = extract_entropy(r->pull, tmp, bytes, | 859 | bytes = extract_entropy(r->pull, u.tmp, bytes, |
859 | random_read_wakeup_thresh / 8, rsvd); | 860 | random_read_wakeup_thresh / 8, rsvd); |
860 | mix_pool_bytes(r, tmp, bytes, NULL); | 861 | mix_pool_bytes(r, u.tmp, bytes, NULL); |
861 | credit_entropy_bits(r, bytes*8); | 862 | credit_entropy_bits(r, bytes*8); |
862 | } | 863 | } |
864 | kmemcheck_mark_initialized(&u.hwrand, sizeof(u.hwrand)); | ||
865 | for (i = 0; i < 4; i++) | ||
866 | if (arch_get_random_long(&u.hwrand[i])) | ||
867 | break; | ||
868 | if (i) | ||
869 | mix_pool_bytes(r, &u.hwrand, sizeof(u.hwrand), 0); | ||
863 | } | 870 | } |
864 | 871 | ||
865 | /* | 872 | /* |