/*
  * Configuration information
  */
-#define INPUT_POOL_WORDS 128
-#define OUTPUT_POOL_WORDS 32
-#define SEC_XFER_SIZE 512
-#define EXTRACT_SIZE 10
+#define INPUT_POOL_SHIFT       12
+#define INPUT_POOL_WORDS       (1 << (INPUT_POOL_SHIFT-5))
+#define OUTPUT_POOL_SHIFT      10
+#define OUTPUT_POOL_WORDS      (1 << (OUTPUT_POOL_SHIFT-5))
+#define SEC_XFER_SIZE          512
+#define EXTRACT_SIZE           10
 
 #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
 
  * this many fractional bits:
  *
  * entropy_count, trickle_thresh
+ *
+ * 2*(ENTROPY_SHIFT + log2(poolbits)) must <= 31, or the multiply in
+ * credit_entropy_bits() needs to be 64 bits wide.
  */
 #define ENTROPY_SHIFT 3
 #define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT)
 struct entropy_store;
 struct entropy_store {
        /* read-only data: */
-       struct poolinfo *poolinfo;
+       const struct poolinfo *poolinfo;
        __u32 *pool;
        const char *name;
        struct entropy_store *pull;
 static void credit_entropy_bits(struct entropy_store *r, int nbits)
 {
        int entropy_count, orig;
+       const int pool_size = r->poolinfo->poolfracbits;
+       int nfrac = nbits << ENTROPY_SHIFT;
 
        if (!nbits)
                return;
        DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
 retry:
        entropy_count = orig = ACCESS_ONCE(r->entropy_count);
-       entropy_count += nbits << ENTROPY_SHIFT;
+       if (nfrac < 0) {
+               /* Debit */
+               entropy_count += nfrac;
+       } else {
+               /*
+                * Credit: we have to account for the possibility of
+                * overwriting already present entropy.  Even in the
+                * ideal case of pure Shannon entropy, new contributions
+                * approach the full value asymptotically:
+                *
+                * entropy <- entropy + (pool_size - entropy) *
+                *      (1 - exp(-add_entropy/pool_size))
+                *
+                * For add_entropy <= pool_size/2 then
+                * (1 - exp(-add_entropy/pool_size)) >=
+                *    (add_entropy/pool_size)*0.7869...
+                * so we can approximate the exponential with
+                * 3/4*add_entropy/pool_size and still be on the
+                * safe side by adding at most pool_size/2 at a time.
+                *
+                * The use of pool_size-2 in the while statement is to
+                * prevent rounding artifacts from making the loop
+                * arbitrarily long; this limits the loop to log2(pool_size)*2
+                * turns no matter how large nbits is.
+                */
+               int pnfrac = nfrac;
+               const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2;
+               /* The +2 corresponds to the /4 in the denominator */
+
+               do {
+                       unsigned int anfrac = min(pnfrac, pool_size/2);
+                       unsigned int add =
+                               ((pool_size - entropy_count)*anfrac*3) >> s;
+
+                       entropy_count += add;
+                       pnfrac -= anfrac;
+               } while (unlikely(entropy_count < pool_size-2 && pnfrac));
+       }
 
        if (entropy_count < 0) {
                DEBUG_ENT("negative entropy/overflow\n");
                entropy_count = 0;
-       } else if (entropy_count > r->poolinfo->poolfracbits)
-               entropy_count = r->poolinfo->poolfracbits;
+       } else if (entropy_count > pool_size)
+               entropy_count = pool_size;
        if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
                goto retry;