Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / drivers / char / random.c
index 29abd5f..cf69b6b 100644 (file)
@@ -722,15 +722,18 @@ retry:
        }
 }
 
-static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
+static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
 {
        const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
 
+       if (nbits < 0)
+               return -EINVAL;
+
        /* Cap the value to avoid overflows */
        nbits = min(nbits,  nbits_max);
-       nbits = max(nbits, -nbits_max);
 
        credit_entropy_bits(r, nbits);
+       return 0;
 }
 
 /*********************************************************************
@@ -941,6 +944,7 @@ void add_interrupt_randomness(int irq, int irq_flags, __u64 ip)
        /* award one bit for the contents of the fast pool */
        credit_entropy_bits(r, credit + 1);
 }
+EXPORT_SYMBOL_GPL(add_interrupt_randomness);
 
 #ifdef CONFIG_BLOCK
 void add_disk_randomness(struct gendisk *disk)
@@ -1453,12 +1457,16 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 static ssize_t
 urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
+       static int maxwarn = 10;
        int ret;
 
-       if (unlikely(nonblocking_pool.initialized == 0))
-               printk_once(KERN_NOTICE "random: %s urandom read "
-                           "with %d bits of entropy available\n",
-                           current->comm, nonblocking_pool.entropy_total);
+       if (unlikely(nonblocking_pool.initialized == 0) &&
+           maxwarn > 0) {
+               maxwarn--;
+               printk(KERN_NOTICE "random: %s: uninitialized urandom read "
+                      "(%zd bytes read, %d bits of entropy available)\n",
+                      current->comm, nbytes, nonblocking_pool.entropy_total);
+       }
 
        nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
        ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
@@ -1538,8 +1546,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                        return -EPERM;
                if (get_user(ent_count, p))
                        return -EFAULT;
-               credit_entropy_bits_safe(&input_pool, ent_count);
-               return 0;
+               return credit_entropy_bits_safe(&input_pool, ent_count);
        case RNDADDENTROPY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
@@ -1553,8 +1560,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                                    size);
                if (retval < 0)
                        return retval;
-               credit_entropy_bits_safe(&input_pool, ent_count);
-               return 0;
+               return credit_entropy_bits_safe(&input_pool, ent_count);
        case RNDZAPENTCNT:
        case RNDCLEARPOOL:
                /*
@@ -1842,12 +1848,18 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
 {
        struct entropy_store *poolp = &input_pool;
 
-       /* Suspend writing if we're above the trickle threshold.
-        * We'll be woken up again once below random_write_wakeup_thresh,
-        * or when the calling thread is about to terminate.
-        */
-       wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+       if (unlikely(nonblocking_pool.initialized == 0))
+               poolp = &nonblocking_pool;
+       else {
+               /* Suspend writing if we're above the trickle
+                * threshold.  We'll be woken up again once below
+                * random_write_wakeup_thresh, or when the calling
+                * thread is about to terminate.
+                */
+               wait_event_interruptible(random_write_wait,
+                                        kthread_should_stop() ||
                        ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
+       }
        mix_pool_bytes(poolp, buffer, count);
        credit_entropy_bits(poolp, entropy);
 }