| From 99920968490e6dfcb49071d55376cee2094a0f4f Mon Sep 17 00:00:00 2001 |
| From: Theodore Ts'o <tytso@mit.edu> |
| Date: Thu, 5 Jul 2012 10:21:01 -0400 |
| Subject: [PATCH] random: use the arch-specific rng in xfer_secondary_pool |
| |
| commit e6d4947b12e8ad947add1032dd754803c6004824 upstream. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/char/random.c b/drivers/char/random.c |
| index f018abd..9e64e08 100644 |
| --- a/drivers/char/random.c |
| +++ b/drivers/char/random.c |
| @@ -247,6 +247,7 @@ |
| #include <linux/cryptohash.h> |
| #include <linux/fips.h> |
| #include <linux/ptrace.h> |
| +#include <linux/kmemcheck.h> |
| |
| #ifdef CONFIG_GENERIC_HARDIRQS |
| # include <linux/irq.h> |
| @@ -695,11 +696,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) |
| goto out; |
| |
| sample.jiffies = jiffies; |
| - |
| - /* Use arch random value, fall back to cycles */ |
| - if (!arch_get_random_int(&sample.cycles)) |
| - sample.cycles = get_cycles(); |
| - |
| + sample.cycles = get_cycles(); |
| sample.num = num; |
| mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); |
| |
| @@ -831,7 +828,11 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, |
| */ |
| static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
| { |
| - __u32 tmp[OUTPUT_POOL_WORDS]; |
| + union { |
| + __u32 tmp[OUTPUT_POOL_WORDS]; |
| + long hwrand[4]; |
| + } u; |
| + int i; |
| |
| if (r->pull && r->entropy_count < nbytes * 8 && |
| r->entropy_count < r->poolinfo->POOLBITS) { |
| @@ -842,17 +843,23 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
| /* pull at least as many as BYTES as wakeup BITS */ |
| bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); |
| /* but never more than the buffer size */ |
| - bytes = min_t(int, bytes, sizeof(tmp)); |
| + bytes = min_t(int, bytes, sizeof(u.tmp)); |
| |
| DEBUG_ENT("going to reseed %s with %d bits " |
| "(%d of %d requested)\n", |
| r->name, bytes * 8, nbytes * 8, r->entropy_count); |
| |
| - bytes = extract_entropy(r->pull, tmp, bytes, |
| + bytes = extract_entropy(r->pull, u.tmp, bytes, |
| random_read_wakeup_thresh / 8, rsvd); |
| - mix_pool_bytes(r, tmp, bytes, NULL); |
| + mix_pool_bytes(r, u.tmp, bytes, NULL); |
| credit_entropy_bits(r, bytes*8); |
| } |
| + kmemcheck_mark_initialized(&u.hwrand, sizeof(u.hwrand)); |
| + for (i = 0; i < 4; i++) |
| + if (arch_get_random_long(&u.hwrand[i])) |
| + break; |
| + if (i) |
| + mix_pool_bytes(r, &u.hwrand, sizeof(u.hwrand), 0); |
| } |
| |
| /* |
| -- |
| 1.7.12.rc1.1.gbce1580 |
| |