--- /dev/null
+From 63d77173266c1791f1553e9e8ccea65dc87c4485 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@zytor.com>
+Date: Sun, 31 Jul 2011 13:54:50 -0700
+Subject: random: Add support for architectural random hooks
+
+From: "H. Peter Anvin" <hpa@zytor.com>
+
+commit 63d77173266c1791f1553e9e8ccea65dc87c4485 upstream.
+
+Add support for architecture-specific hooks into the kernel-directed
+random number generator interfaces. This patchset does not use the
+architecture random number generator interfaces for the
+userspace-directed interfaces (/dev/random and /dev/urandom), thus
+eliminating the need to distinguish between them based on a pool
+pointer.
+
+Changes in version 3:
+- Moved the hooks from extract_entropy() to get_random_bytes().
+- Changes the hooks to inlines.
+
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Cc: Fenghua Yu <fenghua.yu@intel.com>
+Cc: Matt Mackall <mpm@selenic.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 23 +++++++++++++++++++++--
+ include/linux/random.h | 13 +++++++++++++
+ 2 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -932,7 +932,21 @@ static ssize_t extract_entropy_user(stru
+ */
+ void get_random_bytes(void *buf, int nbytes)
+ {
+- extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
++ char *p = buf;
++
++ while (nbytes) {
++ unsigned long v;
++ int chunk = min(nbytes, (int)sizeof(unsigned long));
++
++ if (!arch_get_random_long(&v))
++ break;
++
++ memcpy(buf, &v, chunk);
++ p += chunk;
++ nbytes -= chunk;
++ }
++
++ extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
+ }
+ EXPORT_SYMBOL(get_random_bytes);
+
+@@ -1318,9 +1332,14 @@ late_initcall(random_int_secret_init);
+ DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
+ unsigned int get_random_int(void)
+ {
+- __u32 *hash = get_cpu_var(get_random_int_hash);
++ __u32 *hash;
+ unsigned int ret;
+
++ if (arch_get_random_int(&ret))
++ return ret;
++
++ hash = get_cpu_var(get_random_int_hash);
++
+ hash[0] += current->pid + jiffies + get_cycles();
+ md5_transform(hash, random_int_secret);
+ ret = hash[0];
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -91,6 +91,19 @@ static inline void prandom32_seed(struct
+ state->s3 = __seed(i, 15);
+ }
+
++#ifdef CONFIG_ARCH_RANDOM
++# include <asm/archrandom.h>
++#else
++static inline int arch_get_random_long(unsigned long *v)
++{
++ return 0;
++}
++static inline int arch_get_random_int(unsigned int *v)
++{
++ return 0;
++}
++#endif
++
+ #endif /* __KERNEL___ */
+
+ #endif /* _LINUX_RANDOM_H */
--- /dev/null
+From 775f4b297b780601e61787b766f306ed3e1d23eb Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 2 Jul 2012 07:52:16 -0400
+Subject: random: make 'add_interrupt_randomness()' do something sane
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 775f4b297b780601e61787b766f306ed3e1d23eb upstream.
+
+We've been moving away from add_interrupt_randomness() for various
+reasons: it's too expensive to do on every interrupt, and flooding the
+CPU with interrupts could theoretically cause bogus floods of entropy
+from a somewhat externally controllable source.
+
+This solves both problems by limiting the actual randomness addition
+to just once a second or after 64 interrupts, whicever comes first.
+During that time, the interrupt cycle data is buffered up in a per-cpu
+pool. Also, we make sure the the nonblocking pool used by urandom is
+initialized before we start feeding the normal input pool. This
+assures that /dev/urandom is returning unpredictable data as soon as
+possible.
+
+(Based on an original patch by Linus, but significantly modified by
+tytso.)
+
+Tested-by: Eric Wustrow <ewust@umich.edu>
+Reported-by: Eric Wustrow <ewust@umich.edu>
+Reported-by: Nadia Heninger <nadiah@cs.ucsd.edu>
+Reported-by: Zakir Durumeric <zakir@umich.edu>
+Reported-by: J. Alex Halderman <jhalderm@umich.edu>.
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 103 ++++++++++++++++++++++++++++++++++++++--------
+ drivers/mfd/ab3100-core.c | 2
+ include/linux/random.h | 2
+ kernel/irq/handle.c | 7 +--
+ 4 files changed, 90 insertions(+), 24 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -127,19 +127,15 @@
+ *
+ * void add_input_randomness(unsigned int type, unsigned int code,
+ * unsigned int value);
+- * void add_interrupt_randomness(int irq);
++ * void add_interrupt_randomness(int irq, int irq_flags);
+ * void add_disk_randomness(struct gendisk *disk);
+ *
+ * add_input_randomness() uses the input layer interrupt timing, as well as
+ * the event type information from the hardware.
+ *
+- * add_interrupt_randomness() uses the inter-interrupt timing as random
+- * inputs to the entropy pool. Note that not all interrupts are good
+- * sources of randomness! For example, the timer interrupts is not a
+- * good choice, because the periodicity of the interrupts is too
+- * regular, and hence predictable to an attacker. Network Interface
+- * Controller interrupts are a better measure, since the timing of the
+- * NIC interrupts are more unpredictable.
++ * add_interrupt_randomness() uses the interrupt timing as random
++ * inputs to the entropy pool. Using the cycle counters and the irq source
++ * as inputs, it feeds the randomness roughly once a second.
+ *
+ * add_disk_randomness() uses what amounts to the seek time of block
+ * layer request events, on a per-disk_devt basis, as input to the
+@@ -248,6 +244,7 @@
+ #include <linux/percpu.h>
+ #include <linux/cryptohash.h>
+ #include <linux/fips.h>
++#include <linux/ptrace.h>
+
+ #ifdef CONFIG_GENERIC_HARDIRQS
+ # include <linux/irq.h>
+@@ -256,6 +253,7 @@
+ #include <asm/processor.h>
+ #include <asm/uaccess.h>
+ #include <asm/irq.h>
++#include <asm/irq_regs.h>
+ #include <asm/io.h>
+
+ /*
+@@ -421,7 +419,9 @@ struct entropy_store {
+ spinlock_t lock;
+ unsigned add_ptr;
+ int entropy_count;
++ int entropy_total;
+ int input_rotate;
++ unsigned int initialized:1;
+ __u8 last_data[EXTRACT_SIZE];
+ };
+
+@@ -454,6 +454,10 @@ static struct entropy_store nonblocking_
+ .pool = nonblocking_pool_data
+ };
+
++static __u32 const twist_table[8] = {
++ 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
++ 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
++
+ /*
+ * This function adds bytes into the entropy "pool". It does not
+ * update the entropy estimate. The caller should call
+@@ -467,9 +471,6 @@ static struct entropy_store nonblocking_
+ static void mix_pool_bytes_extract(struct entropy_store *r, const void *in,
+ int nbytes, __u8 out[64])
+ {
+- static __u32 const twist_table[8] = {
+- 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
+- 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
+ unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
+ int input_rotate;
+ int wordmask = r->poolinfo->poolwords - 1;
+@@ -528,6 +529,36 @@ static void mix_pool_bytes(struct entrop
+ mix_pool_bytes_extract(r, in, bytes, NULL);
+ }
+
++struct fast_pool {
++ __u32 pool[4];
++ unsigned long last;
++ unsigned short count;
++ unsigned char rotate;
++ unsigned char last_timer_intr;
++};
++
++/*
++ * This is a fast mixing routine used by the interrupt randomness
++ * collector. It's hardcoded for an 128 bit pool and assumes that any
++ * locks that might be needed are taken by the caller.
++ */
++static void fast_mix(struct fast_pool *f, const void *in, int nbytes)
++{
++ const char *bytes = in;
++ __u32 w;
++ unsigned i = f->count;
++ unsigned input_rotate = f->rotate;
++
++ while (nbytes--) {
++ w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^
++ f->pool[(i + 1) & 3];
++ f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7];
++ input_rotate += (i++ & 3) ? 7 : 14;
++ }
++ f->count = i;
++ f->rotate = input_rotate;
++}
++
+ /*
+ * Credit (or debit) the entropy store with n bits of entropy
+ */
+@@ -551,6 +582,12 @@ static void credit_entropy_bits(struct e
+ entropy_count = r->poolinfo->POOLBITS;
+ r->entropy_count = entropy_count;
+
++ if (!r->initialized && nbits > 0) {
++ r->entropy_total += nbits;
++ if (r->entropy_total > 128)
++ r->initialized = 1;
++ }
++
+ /* should we wake readers? */
+ if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
+ wake_up_interruptible(&random_read_wait);
+@@ -700,17 +737,48 @@ void add_input_randomness(unsigned int t
+ }
+ EXPORT_SYMBOL_GPL(add_input_randomness);
+
+-void add_interrupt_randomness(int irq)
++static DEFINE_PER_CPU(struct fast_pool, irq_randomness);
++
++void add_interrupt_randomness(int irq, int irq_flags)
+ {
+- struct timer_rand_state *state;
++ struct entropy_store *r;
++ struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness);
++ struct pt_regs *regs = get_irq_regs();
++ unsigned long now = jiffies;
++ __u32 input[4], cycles = get_cycles();
++
++ input[0] = cycles ^ jiffies;
++ input[1] = irq;
++ if (regs) {
++ __u64 ip = instruction_pointer(regs);
++ input[2] = ip;
++ input[3] = ip >> 32;
++ }
+
+- state = get_timer_rand_state(irq);
++ fast_mix(fast_pool, input, sizeof(input));
+
+- if (state == NULL)
++ if ((fast_pool->count & 1023) &&
++ !time_after(now, fast_pool->last + HZ))
+ return;
+
+- DEBUG_ENT("irq event %d\n", irq);
+- add_timer_randomness(state, 0x100 + irq);
++ fast_pool->last = now;
++
++ r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
++ mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool));
++ /*
++ * If we don't have a valid cycle counter, and we see
++ * back-to-back timer interrupts, then skip giving credit for
++ * any entropy.
++ */
++ if (cycles == 0) {
++ if (irq_flags & __IRQF_TIMER) {
++ if (fast_pool->last_timer_intr)
++ return;
++ fast_pool->last_timer_intr = 1;
++ } else
++ fast_pool->last_timer_intr = 0;
++ }
++ credit_entropy_bits(r, 1);
+ }
+
+ #ifdef CONFIG_BLOCK
+@@ -970,6 +1038,7 @@ static void init_std_data(struct entropy
+
+ spin_lock_irqsave(&r->lock, flags);
+ r->entropy_count = 0;
++ r->entropy_total = 0;
+ spin_unlock_irqrestore(&r->lock, flags);
+
+ now = ktime_get_real();
+--- a/drivers/mfd/ab3100-core.c
++++ b/drivers/mfd/ab3100-core.c
+@@ -408,8 +408,6 @@ static irqreturn_t ab3100_irq_handler(in
+ u32 fatevent;
+ int err;
+
+- add_interrupt_randomness(irq);
+-
+ err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
+ event_regs, 3);
+ if (err)
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -52,7 +52,7 @@ extern void rand_initialize_irq(int irq)
+
+ extern void add_input_randomness(unsigned int type, unsigned int code,
+ unsigned int value);
+-extern void add_interrupt_randomness(int irq);
++extern void add_interrupt_randomness(int irq, int irq_flags);
+
+ extern void get_random_bytes(void *buf, int nbytes);
+ void generate_random_uuid(unsigned char uuid_out[16]);
+--- a/kernel/irq/handle.c
++++ b/kernel/irq/handle.c
+@@ -117,7 +117,7 @@ irqreturn_t
+ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
+ {
+ irqreturn_t retval = IRQ_NONE;
+- unsigned int random = 0, irq = desc->irq_data.irq;
++ unsigned int flags = 0, irq = desc->irq_data.irq;
+
+ do {
+ irqreturn_t res;
+@@ -145,7 +145,7 @@ handle_irq_event_percpu(struct irq_desc
+
+ /* Fall through to add to randomness */
+ case IRQ_HANDLED:
+- random |= action->flags;
++ flags |= action->flags;
+ break;
+
+ default:
+@@ -156,8 +156,7 @@ handle_irq_event_percpu(struct irq_desc
+ action = action->next;
+ } while (action);
+
+- if (random & IRQF_SAMPLE_RANDOM)
+- add_interrupt_randomness(irq);
++ add_interrupt_randomness(irq, flags);
+
+ if (!noirqdebug)
+ note_interrupt(irq, desc, retval);
--- /dev/null
+From cf833d0b9937874b50ef2867c4e8badfd64948ce Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Thu, 22 Dec 2011 11:36:22 -0800
+Subject: random: Use arch_get_random_int instead of cycle counter if avail
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit cf833d0b9937874b50ef2867c4e8badfd64948ce upstream.
+
+We still don't use rdrand in /dev/random, which just seems stupid. We
+accept the *cycle*counter* as a random input, but we don't accept
+rdrand? That's just broken.
+
+Sure, people can do things in user space (write to /dev/random, use
+rdrand in addition to /dev/random themselves etc etc), but that
+*still* seems to be a particularly stupid reason for saying "we
+shouldn't bother to try to do better in /dev/random".
+
+And even if somebody really doesn't trust rdrand as a source of random
+bytes, it seems singularly stupid to trust the cycle counter *more*.
+
+So I'd suggest the attached patch. I'm not going to even bother
+arguing that we should add more bits to the entropy estimate, because
+that's not the point - I don't care if /dev/random fills up slowly or
+not, I think it's just stupid to not use the bits we can get from
+rdrand and mix them into the strong randomness pool.
+
+Link: http://lkml.kernel.org/r/CA%2B55aFwn59N1=m651QAyTy-1gO1noGbK18zwKDwvwqnravA84A@mail.gmail.com
+Acked-by: "David S. Miller" <davem@davemloft.net>
+Acked-by: "Theodore Ts'o" <tytso@mit.edu>
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Matt Mackall <mpm@selenic.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -624,8 +624,8 @@ static struct timer_rand_state input_tim
+ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
+ {
+ struct {
+- cycles_t cycles;
+ long jiffies;
++ unsigned cycles;
+ unsigned num;
+ } sample;
+ long delta, delta2, delta3;
+@@ -637,7 +637,11 @@ static void add_timer_randomness(struct
+ goto out;
+
+ sample.jiffies = jiffies;
+- sample.cycles = get_cycles();
++
++ /* Use arch random value, fall back to cycles */
++ if (!arch_get_random_int(&sample.cycles))
++ sample.cycles = get_cycles();
++
+ sample.num = num;
+ mix_pool_bytes(&input_pool, &sample, sizeof(sample));
+