aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2014-06-10 22:46:37 -0400
committerTheodore Ts'o <tytso@mit.edu>2014-07-15 04:49:39 -0400
commit91fcb532efe366d79b93a3c8c368b9dca6176a55 (patch)
tree3d2f571973e695ab5334abbaadbcad3a64152188 /drivers/char
parent1795cd9b3a91d4b5473c97f491d63892442212ab (diff)
random: always update the entropy pool under the spinlock
Instead of using lockless techniques introduced in commit 902c098a3663, use spin_trylock to try to grab entropy pool's lock. If we can't get the lock, then just try again on the next interrupt. Based on discussions with George Spelvin. Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: George Spelvin <linux@horizon.com>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/random.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0a7ac0a7b252..922a2e4089f9 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -495,9 +495,8 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in,
495 tap4 = r->poolinfo->tap4; 495 tap4 = r->poolinfo->tap4;
496 tap5 = r->poolinfo->tap5; 496 tap5 = r->poolinfo->tap5;
497 497
498 smp_rmb(); 498 input_rotate = r->input_rotate;
499 input_rotate = ACCESS_ONCE(r->input_rotate); 499 i = r->add_ptr;
500 i = ACCESS_ONCE(r->add_ptr);
501 500
502 /* mix one byte at a time to simplify size handling and churn faster */ 501 /* mix one byte at a time to simplify size handling and churn faster */
503 while (nbytes--) { 502 while (nbytes--) {
@@ -524,9 +523,8 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in,
524 input_rotate = (input_rotate + (i ? 7 : 14)) & 31; 523 input_rotate = (input_rotate + (i ? 7 : 14)) & 31;
525 } 524 }
526 525
527 ACCESS_ONCE(r->input_rotate) = input_rotate; 526 r->input_rotate = input_rotate;
528 ACCESS_ONCE(r->add_ptr) = i; 527 r->add_ptr = i;
529 smp_wmb();
530 528
531 if (out) 529 if (out)
532 for (j = 0; j < 16; j++) 530 for (j = 0; j < 16; j++)
@@ -845,7 +843,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
845 __u32 input[4], c_high, j_high; 843 __u32 input[4], c_high, j_high;
846 __u64 ip; 844 __u64 ip;
847 unsigned long seed; 845 unsigned long seed;
848 int credit; 846 int credit = 0;
849 847
850 c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; 848 c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
851 j_high = (sizeof(now) > 4) ? now >> 32 : 0; 849 j_high = (sizeof(now) > 4) ? now >> 32 : 0;
@@ -860,36 +858,40 @@ void add_interrupt_randomness(int irq, int irq_flags)
860 if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ)) 858 if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ))
861 return; 859 return;
862 860
863 fast_pool->last = now;
864
865 r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; 861 r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
862 if (!spin_trylock(&r->lock)) {
863 fast_pool->count--;
864 return;
865 }
866 fast_pool->last = now;
866 __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL); 867 __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
867 868
868 /* 869 /*
870 * If we have architectural seed generator, produce a seed and
871 * add it to the pool. For the sake of paranoia count it as
872 * 50% entropic.
873 */
874 if (arch_get_random_seed_long(&seed)) {
875 __mix_pool_bytes(r, &seed, sizeof(seed), NULL);
876 credit += sizeof(seed) * 4;
877 }
878 spin_unlock(&r->lock);
879
880 /*
869 * If we don't have a valid cycle counter, and we see 881 * If we don't have a valid cycle counter, and we see
870 * back-to-back timer interrupts, then skip giving credit for 882 * back-to-back timer interrupts, then skip giving credit for
871 * any entropy, otherwise credit 1 bit. 883 * any entropy, otherwise credit 1 bit.
872 */ 884 */
873 credit = 1; 885 credit++;
874 if (cycles == 0) { 886 if (cycles == 0) {
875 if (irq_flags & __IRQF_TIMER) { 887 if (irq_flags & __IRQF_TIMER) {
876 if (fast_pool->last_timer_intr) 888 if (fast_pool->last_timer_intr)
877 credit = 0; 889 credit--;
878 fast_pool->last_timer_intr = 1; 890 fast_pool->last_timer_intr = 1;
879 } else 891 } else
880 fast_pool->last_timer_intr = 0; 892 fast_pool->last_timer_intr = 0;
881 } 893 }
882 894
883 /*
884 * If we have architectural seed generator, produce a seed and
885 * add it to the pool. For the sake of paranoia count it as
886 * 50% entropic.
887 */
888 if (arch_get_random_seed_long(&seed)) {
889 __mix_pool_bytes(r, &seed, sizeof(seed), NULL);
890 credit += sizeof(seed) * 4;
891 }
892
893 credit_entropy_bits(r, credit); 895 credit_entropy_bits(r, credit);
894} 896}
895 897