diff options
| -rw-r--r-- | drivers/char/random.c | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 914b1575df8f..aa22fe551c2a 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -551,9 +551,8 @@ static void mix_pool_bytes(struct entropy_store *r, const void *in, | |||
| 551 | struct fast_pool { | 551 | struct fast_pool { |
| 552 | __u32 pool[4]; | 552 | __u32 pool[4]; |
| 553 | unsigned long last; | 553 | unsigned long last; |
| 554 | unsigned short reg_idx; | ||
| 554 | unsigned char count; | 555 | unsigned char count; |
| 555 | unsigned char notimer_count; | ||
| 556 | unsigned char rotate; | ||
| 557 | }; | 556 | }; |
| 558 | 557 | ||
| 559 | /* | 558 | /* |
| @@ -857,6 +856,17 @@ static void add_interrupt_bench(cycles_t start) | |||
| 857 | #define add_interrupt_bench(x) | 856 | #define add_interrupt_bench(x) |
| 858 | #endif | 857 | #endif |
| 859 | 858 | ||
| 859 | static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) | ||
| 860 | { | ||
| 861 | __u32 *ptr = (__u32 *) regs; | ||
| 862 | |||
| 863 | if (regs == NULL) | ||
| 864 | return 0; | ||
| 865 | if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) | ||
| 866 | f->reg_idx = 0; | ||
| 867 | return *(ptr + f->reg_idx++); | ||
| 868 | } | ||
| 869 | |||
| 860 | void add_interrupt_randomness(int irq, int irq_flags) | 870 | void add_interrupt_randomness(int irq, int irq_flags) |
| 861 | { | 871 | { |
| 862 | struct entropy_store *r; | 872 | struct entropy_store *r; |
| @@ -869,28 +879,23 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
| 869 | unsigned long seed; | 879 | unsigned long seed; |
| 870 | int credit = 0; | 880 | int credit = 0; |
| 871 | 881 | ||
| 882 | if (cycles == 0) | ||
| 883 | cycles = get_reg(fast_pool, regs); | ||
| 872 | c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; | 884 | c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; |
| 873 | j_high = (sizeof(now) > 4) ? now >> 32 : 0; | 885 | j_high = (sizeof(now) > 4) ? now >> 32 : 0; |
| 874 | fast_pool->pool[0] ^= cycles ^ j_high ^ irq; | 886 | fast_pool->pool[0] ^= cycles ^ j_high ^ irq; |
| 875 | fast_pool->pool[1] ^= now ^ c_high; | 887 | fast_pool->pool[1] ^= now ^ c_high; |
| 876 | ip = regs ? instruction_pointer(regs) : _RET_IP_; | 888 | ip = regs ? instruction_pointer(regs) : _RET_IP_; |
| 877 | fast_pool->pool[2] ^= ip; | 889 | fast_pool->pool[2] ^= ip; |
| 878 | fast_pool->pool[3] ^= ip >> 32; | 890 | fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 : |
| 891 | get_reg(fast_pool, regs); | ||
| 879 | 892 | ||
| 880 | fast_mix(fast_pool); | 893 | fast_mix(fast_pool); |
| 881 | if ((irq_flags & __IRQF_TIMER) == 0) | ||
| 882 | fast_pool->notimer_count++; | ||
| 883 | add_interrupt_bench(cycles); | 894 | add_interrupt_bench(cycles); |
| 884 | 895 | ||
| 885 | if (cycles) { | 896 | if ((fast_pool->count < 64) && |
| 886 | if ((fast_pool->count < 64) && | 897 | !time_after(now, fast_pool->last + HZ)) |
| 887 | !time_after(now, fast_pool->last + HZ)) | 898 | return; |
| 888 | return; | ||
| 889 | } else { | ||
| 890 | /* CPU does not have a cycle counting register :-( */ | ||
| 891 | if (fast_pool->count < 64) | ||
| 892 | return; | ||
| 893 | } | ||
| 894 | 899 | ||
| 895 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; | 900 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; |
| 896 | if (!spin_trylock(&r->lock)) | 901 | if (!spin_trylock(&r->lock)) |
| @@ -910,18 +915,10 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
| 910 | } | 915 | } |
| 911 | spin_unlock(&r->lock); | 916 | spin_unlock(&r->lock); |
| 912 | 917 | ||
| 913 | /* | 918 | fast_pool->count = 0; |
| 914 | * If we have a valid cycle counter or if the majority of | ||
| 915 | * interrupts collected were non-timer interrupts, then give | ||
| 916 | * an entropy credit of 1 bit. Yes, this is being very | ||
| 917 | * conservative. | ||
| 918 | */ | ||
| 919 | if (cycles || (fast_pool->notimer_count >= 32)) | ||
| 920 | credit++; | ||
| 921 | |||
| 922 | fast_pool->count = fast_pool->notimer_count = 0; | ||
| 923 | 919 | ||
| 924 | credit_entropy_bits(r, credit); | 920 | /* award one bit for the contents of the fast pool */ |
| 921 | credit_entropy_bits(r, credit + 1); | ||
| 925 | } | 922 | } |
| 926 | 923 | ||
| 927 | #ifdef CONFIG_BLOCK | 924 | #ifdef CONFIG_BLOCK |
