aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/random.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 47ac7cd20fb1..e247c45b2772 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -470,7 +470,6 @@ struct entropy_store {
470 unsigned short add_ptr; 470 unsigned short add_ptr;
471 unsigned short input_rotate; 471 unsigned short input_rotate;
472 int entropy_count; 472 int entropy_count;
473 int entropy_total;
474 unsigned int initialized:1; 473 unsigned int initialized:1;
475 unsigned int last_data_init:1; 474 unsigned int last_data_init:1;
476 __u8 last_data[EXTRACT_SIZE]; 475 __u8 last_data[EXTRACT_SIZE];
@@ -643,7 +642,7 @@ static void process_random_ready_list(void)
643 */ 642 */
644static void credit_entropy_bits(struct entropy_store *r, int nbits) 643static void credit_entropy_bits(struct entropy_store *r, int nbits)
645{ 644{
646 int entropy_count, orig; 645 int entropy_count, orig, has_initialized = 0;
647 const int pool_size = r->poolinfo->poolfracbits; 646 const int pool_size = r->poolinfo->poolfracbits;
648 int nfrac = nbits << ENTROPY_SHIFT; 647 int nfrac = nbits << ENTROPY_SHIFT;
649 648
@@ -698,23 +697,25 @@ retry:
698 entropy_count = 0; 697 entropy_count = 0;
699 } else if (entropy_count > pool_size) 698 } else if (entropy_count > pool_size)
700 entropy_count = pool_size; 699 entropy_count = pool_size;
700 if ((r == &blocking_pool) && !r->initialized &&
701 (entropy_count >> ENTROPY_SHIFT) > 128)
702 has_initialized = 1;
701 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) 703 if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
702 goto retry; 704 goto retry;
703 705
704 r->entropy_total += nbits; 706 if (has_initialized)
705 if (!r->initialized && r->entropy_total > 128) {
706 r->initialized = 1; 707 r->initialized = 1;
707 r->entropy_total = 0;
708 }
709 708
710 trace_credit_entropy_bits(r->name, nbits, 709 trace_credit_entropy_bits(r->name, nbits,
711 entropy_count >> ENTROPY_SHIFT, 710 entropy_count >> ENTROPY_SHIFT, _RET_IP_);
712 r->entropy_total, _RET_IP_);
713 711
714 if (r == &input_pool) { 712 if (r == &input_pool) {
715 int entropy_bits = entropy_count >> ENTROPY_SHIFT; 713 int entropy_bits = entropy_count >> ENTROPY_SHIFT;
714 struct entropy_store *other = &blocking_pool;
716 715
717 if (crng_init < 2 && entropy_bits >= 128) { 716 if (crng_init < 2) {
717 if (entropy_bits < 128)
718 return;
718 crng_reseed(&primary_crng, r); 719 crng_reseed(&primary_crng, r);
719 entropy_bits = r->entropy_count >> ENTROPY_SHIFT; 720 entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
720 } 721 }
@@ -725,20 +726,14 @@ retry:
725 wake_up_interruptible(&random_read_wait); 726 wake_up_interruptible(&random_read_wait);
726 kill_fasync(&fasync, SIGIO, POLL_IN); 727 kill_fasync(&fasync, SIGIO, POLL_IN);
727 } 728 }
728 /* If the input pool is getting full, send some 729 /* If the input pool is getting full, and the blocking
729 * entropy to the blocking pool until it is 75% full. 730 * pool has room, send some entropy to the blocking
731 * pool.
730 */ 732 */
731 if (entropy_bits > random_write_wakeup_bits && 733 if (!work_pending(&other->push_work) &&
732 r->initialized && 734 (ENTROPY_BITS(r) > 6 * r->poolinfo->poolbytes) &&
733 r->entropy_total >= 2*random_read_wakeup_bits) { 735 (ENTROPY_BITS(other) <= 6 * other->poolinfo->poolbytes))
734 struct entropy_store *other = &blocking_pool; 736 schedule_work(&other->push_work);
735
736 if (other->entropy_count <=
737 3 * other->poolinfo->poolfracbits / 4) {
738 schedule_work(&other->push_work);
739 r->entropy_total = 0;
740 }
741 }
742 } 737 }
743} 738}
744 739
@@ -1553,6 +1548,11 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
1553 int large_request = (nbytes > 256); 1548 int large_request = (nbytes > 256);
1554 1549
1555 trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); 1550 trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
1551 if (!r->initialized && r->pull) {
1552 xfer_secondary_pool(r, ENTROPY_BITS(r->pull)/8);
1553 if (!r->initialized)
1554 return 0;
1555 }
1556 xfer_secondary_pool(r, nbytes); 1556 xfer_secondary_pool(r, nbytes);
1557 nbytes = account(r, nbytes, 0, 0); 1557 nbytes = account(r, nbytes, 0, 0);
1558 1558