diff options
Diffstat (limited to 'drivers/char/random.c')
| -rw-r--r-- | drivers/char/random.c | 52 |
1 files changed, 16 insertions, 36 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 84c576ec20e9..f126bd2f69fe 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -404,17 +404,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); | |||
| 404 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 404 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
| 405 | static struct fasync_struct *fasync; | 405 | static struct fasync_struct *fasync; |
| 406 | 406 | ||
| 407 | static bool debug; | ||
| 408 | module_param(debug, bool, 0644); | ||
| 409 | #define DEBUG_ENT(fmt, arg...) do { \ | ||
| 410 | if (debug) \ | ||
| 411 | printk(KERN_DEBUG "random %04d %04d %04d: " \ | ||
| 412 | fmt,\ | ||
| 413 | input_pool.entropy_count,\ | ||
| 414 | blocking_pool.entropy_count,\ | ||
| 415 | nonblocking_pool.entropy_count,\ | ||
| 416 | ## arg); } while (0) | ||
| 417 | |||
| 418 | /********************************************************************** | 407 | /********************************************************************** |
| 419 | * | 408 | * |
| 420 | * OS independent entropy store. Here are the functions which handle | 409 | * OS independent entropy store. Here are the functions which handle |
| @@ -612,7 +601,6 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) | |||
| 612 | if (!nbits) | 601 | if (!nbits) |
| 613 | return; | 602 | return; |
| 614 | 603 | ||
| 615 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); | ||
| 616 | retry: | 604 | retry: |
| 617 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 605 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
| 618 | if (nfrac < 0) { | 606 | if (nfrac < 0) { |
| @@ -655,7 +643,9 @@ retry: | |||
| 655 | } | 643 | } |
| 656 | 644 | ||
| 657 | if (entropy_count < 0) { | 645 | if (entropy_count < 0) { |
| 658 | DEBUG_ENT("negative entropy/overflow\n"); | 646 | pr_warn("random: negative entropy/overflow: pool %s count %d\n", |
| 647 | r->name, entropy_count); | ||
| 648 | WARN_ON(1); | ||
| 659 | entropy_count = 0; | 649 | entropy_count = 0; |
| 660 | } else if (entropy_count > pool_size) | 650 | } else if (entropy_count > pool_size) |
| 661 | entropy_count = pool_size; | 651 | entropy_count = pool_size; |
| @@ -832,10 +822,10 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
| 832 | if (value == last_value) | 822 | if (value == last_value) |
| 833 | return; | 823 | return; |
| 834 | 824 | ||
| 835 | DEBUG_ENT("input event\n"); | ||
| 836 | last_value = value; | 825 | last_value = value; |
| 837 | add_timer_randomness(&input_timer_state, | 826 | add_timer_randomness(&input_timer_state, |
| 838 | (type << 4) ^ code ^ (code >> 4) ^ value); | 827 | (type << 4) ^ code ^ (code >> 4) ^ value); |
| 828 | trace_add_input_randomness(ENTROPY_BITS(&input_pool)); | ||
| 839 | } | 829 | } |
| 840 | EXPORT_SYMBOL_GPL(add_input_randomness); | 830 | EXPORT_SYMBOL_GPL(add_input_randomness); |
| 841 | 831 | ||
| @@ -890,10 +880,8 @@ void add_disk_randomness(struct gendisk *disk) | |||
| 890 | if (!disk || !disk->random) | 880 | if (!disk || !disk->random) |
| 891 | return; | 881 | return; |
| 892 | /* first major is 1, so we get >= 0x200 here */ | 882 | /* first major is 1, so we get >= 0x200 here */ |
| 893 | DEBUG_ENT("disk event %d:%d\n", | ||
| 894 | MAJOR(disk_devt(disk)), MINOR(disk_devt(disk))); | ||
| 895 | |||
| 896 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); | 883 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); |
| 884 | trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool)); | ||
| 897 | } | 885 | } |
| 898 | #endif | 886 | #endif |
| 899 | 887 | ||
| @@ -941,10 +929,8 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
| 941 | /* but never more than the buffer size */ | 929 | /* but never more than the buffer size */ |
| 942 | bytes = min_t(int, bytes, sizeof(tmp)); | 930 | bytes = min_t(int, bytes, sizeof(tmp)); |
| 943 | 931 | ||
| 944 | DEBUG_ENT("going to reseed %s with %d bits (%zu of %d requested)\n", | 932 | trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, |
| 945 | r->name, bytes * 8, nbytes * 8, | 933 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); |
| 946 | r->entropy_count >> ENTROPY_SHIFT); | ||
| 947 | |||
| 948 | bytes = extract_entropy(r->pull, tmp, bytes, | 934 | bytes = extract_entropy(r->pull, tmp, bytes, |
| 949 | random_read_wakeup_thresh / 8, rsvd); | 935 | random_read_wakeup_thresh / 8, rsvd); |
| 950 | mix_pool_bytes(r, tmp, bytes, NULL); | 936 | mix_pool_bytes(r, tmp, bytes, NULL); |
| @@ -992,8 +978,6 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
| 992 | spin_lock_irqsave(&r->lock, flags); | 978 | spin_lock_irqsave(&r->lock, flags); |
| 993 | 979 | ||
| 994 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); | 980 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); |
| 995 | DEBUG_ENT("trying to extract %zu bits from %s\n", | ||
| 996 | nbytes * 8, r->name); | ||
| 997 | 981 | ||
| 998 | /* Can we pull enough? */ | 982 | /* Can we pull enough? */ |
| 999 | retry: | 983 | retry: |
| @@ -1019,12 +1003,9 @@ retry: | |||
| 1019 | < random_write_wakeup_thresh) | 1003 | < random_write_wakeup_thresh) |
| 1020 | wakeup_write = 1; | 1004 | wakeup_write = 1; |
| 1021 | } | 1005 | } |
| 1022 | |||
| 1023 | DEBUG_ENT("debiting %zu entropy credits from %s%s\n", | ||
| 1024 | ibytes * 8, r->name, r->limit ? "" : " (unlimited)"); | ||
| 1025 | |||
| 1026 | spin_unlock_irqrestore(&r->lock, flags); | 1006 | spin_unlock_irqrestore(&r->lock, flags); |
| 1027 | 1007 | ||
| 1008 | trace_debit_entropy(r->name, 8 * ibytes); | ||
| 1028 | if (wakeup_write) { | 1009 | if (wakeup_write) { |
| 1029 | wake_up_interruptible(&random_write_wait); | 1010 | wake_up_interruptible(&random_write_wait); |
| 1030 | kill_fasync(&fasync, SIGIO, POLL_OUT); | 1011 | kill_fasync(&fasync, SIGIO, POLL_OUT); |
| @@ -1303,8 +1284,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
| 1303 | if (n > SEC_XFER_SIZE) | 1284 | if (n > SEC_XFER_SIZE) |
| 1304 | n = SEC_XFER_SIZE; | 1285 | n = SEC_XFER_SIZE; |
| 1305 | 1286 | ||
| 1306 | DEBUG_ENT("reading %zu bits\n", n*8); | ||
| 1307 | |||
| 1308 | n = extract_entropy_user(&blocking_pool, buf, n); | 1287 | n = extract_entropy_user(&blocking_pool, buf, n); |
| 1309 | 1288 | ||
| 1310 | if (n < 0) { | 1289 | if (n < 0) { |
| @@ -1312,8 +1291,9 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
| 1312 | break; | 1291 | break; |
| 1313 | } | 1292 | } |
| 1314 | 1293 | ||
| 1315 | DEBUG_ENT("read got %zd bits (%zd still needed)\n", | 1294 | trace_random_read(n*8, (nbytes-n)*8, |
| 1316 | n*8, (nbytes-n)*8); | 1295 | ENTROPY_BITS(&blocking_pool), |
| 1296 | ENTROPY_BITS(&input_pool)); | ||
| 1317 | 1297 | ||
| 1318 | if (n == 0) { | 1298 | if (n == 0) { |
| 1319 | if (file->f_flags & O_NONBLOCK) { | 1299 | if (file->f_flags & O_NONBLOCK) { |
| @@ -1321,14 +1301,10 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
| 1321 | break; | 1301 | break; |
| 1322 | } | 1302 | } |
| 1323 | 1303 | ||
| 1324 | DEBUG_ENT("sleeping?\n"); | ||
| 1325 | |||
| 1326 | wait_event_interruptible(random_read_wait, | 1304 | wait_event_interruptible(random_read_wait, |
| 1327 | ENTROPY_BITS(&input_pool) >= | 1305 | ENTROPY_BITS(&input_pool) >= |
| 1328 | random_read_wakeup_thresh); | 1306 | random_read_wakeup_thresh); |
| 1329 | 1307 | ||
| 1330 | DEBUG_ENT("awake\n"); | ||
| 1331 | |||
| 1332 | if (signal_pending(current)) { | 1308 | if (signal_pending(current)) { |
| 1333 | retval = -ERESTARTSYS; | 1309 | retval = -ERESTARTSYS; |
| 1334 | break; | 1310 | break; |
| @@ -1350,7 +1326,11 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
| 1350 | static ssize_t | 1326 | static ssize_t |
| 1351 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 1327 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
| 1352 | { | 1328 | { |
| 1353 | return extract_entropy_user(&nonblocking_pool, buf, nbytes); | 1329 | int ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); |
| 1330 | |||
| 1331 | trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool), | ||
| 1332 | ENTROPY_BITS(&input_pool)); | ||
| 1333 | return ret; | ||
| 1354 | } | 1334 | } |
| 1355 | 1335 | ||
| 1356 | static unsigned int | 1336 | static unsigned int |
