From: Florian Fainelli Date: Wed, 26 Sep 2012 12:54:01 +0000 (+0000) Subject: backport the upstream entropy changes (#11951) X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=eb97933e2a4ea7d0002571eb780d73c339daa9db;p=openwrt%2Fstaging%2Fkaloz.git backport the upstream entropy changes (#11951) SVN-Revision: 33559 --- diff --git a/target/linux/generic/patches-3.3/050-rng_git_backport.patch b/target/linux/generic/patches-3.3/050-rng_git_backport.patch new file mode 100644 index 0000000000..825eb73a43 --- /dev/null +++ b/target/linux/generic/patches-3.3/050-rng_git_backport.patch @@ -0,0 +1,783 @@ +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -125,21 +125,26 @@ + * The current exported interfaces for gathering environmental noise + * from the devices are: + * ++ * void add_device_randomness(const void *buf, unsigned int size); + * 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_device_randomness() is for adding data to the random pool that ++ * is likely to differ between two devices (or possibly even per boot). ++ * This would be things like MAC addresses or serial numbers, or the ++ * read-out of the RTC. This does *not* add any actual entropy to the ++ * pool, but it initializes the pool to different values for devices ++ * that might otherwise be identical and have very little entropy ++ * available to them (particularly common in the embedded world). + * + * 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 +253,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_GENERIC_HARDIRQS + # include +@@ -256,8 +262,12 @@ + #include + #include + #include ++#include + #include + ++#define CREATE_TRACE_POINTS ++#include ++ + /* + * Configuration information + */ +@@ -420,8 +430,10 @@ struct entropy_store { + /* read-write data: */ + spinlock_t lock; + unsigned add_ptr; ++ unsigned input_rotate; + int entropy_count; +- int input_rotate; ++ int entropy_total; ++ unsigned int initialized:1; + __u8 last_data[EXTRACT_SIZE]; + }; + +@@ -454,6 +466,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 +@@ -464,29 +480,24 @@ static struct entropy_store nonblocking_ + * it's cheap to do so and helps slightly in the expected case where + * the entropy is concentrated in the low-order bits. + */ +-static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, +- int nbytes, __u8 out[64]) ++static void _mix_pool_bytes(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; + const char *bytes = in; + __u32 w; +- unsigned long flags; + +- /* Taps are constant, so we can load them without holding r->lock. */ + tap1 = r->poolinfo->tap1; + tap2 = r->poolinfo->tap2; + tap3 = r->poolinfo->tap3; + tap4 = r->poolinfo->tap4; + tap5 = r->poolinfo->tap5; + +- spin_lock_irqsave(&r->lock, flags); +- input_rotate = r->input_rotate; +- i = r->add_ptr; ++ smp_rmb(); ++ input_rotate = ACCESS_ONCE(r->input_rotate); ++ i = ACCESS_ONCE(r->add_ptr); + + /* mix one byte at a time to simplify size handling and churn faster */ + while (nbytes--) { +@@ -513,19 +524,61 @@ static void mix_pool_bytes_extract(struc + input_rotate += i ? 7 : 14; + } + +- r->input_rotate = input_rotate; +- r->add_ptr = i; ++ ACCESS_ONCE(r->input_rotate) = input_rotate; ++ ACCESS_ONCE(r->add_ptr) = i; ++ smp_wmb(); + + if (out) + for (j = 0; j < 16; j++) + ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; ++} ++ ++static void __mix_pool_bytes(struct entropy_store *r, const void *in, ++ int nbytes, __u8 out[64]) ++{ ++ trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_); ++ _mix_pool_bytes(r, in, nbytes, out); ++} + ++static void mix_pool_bytes(struct entropy_store *r, const void *in, ++ int nbytes, __u8 out[64]) ++{ ++ unsigned long flags; ++ ++ trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); ++ spin_lock_irqsave(&r->lock, flags); ++ _mix_pool_bytes(r, in, nbytes, out); + spin_unlock_irqrestore(&r->lock, flags); + } + +-static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) ++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) + { +- mix_pool_bytes_extract(r, in, bytes, NULL); ++ 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; + } + + /* +@@ -533,30 +586,38 @@ static void mix_pool_bytes(struct entrop + */ + static void credit_entropy_bits(struct entropy_store *r, int nbits) + { +- unsigned long flags; +- int entropy_count; ++ int entropy_count, orig; + + if (!nbits) + return; + +- spin_lock_irqsave(&r->lock, flags); +- + DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); +- entropy_count = r->entropy_count; ++retry: ++ entropy_count = orig = ACCESS_ONCE(r->entropy_count); + entropy_count += nbits; ++ + if (entropy_count < 0) { + DEBUG_ENT("negative entropy/overflow\n"); + entropy_count = 0; + } else if (entropy_count > r->poolinfo->POOLBITS) + entropy_count = r->poolinfo->POOLBITS; +- r->entropy_count = entropy_count; ++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) ++ goto retry; ++ ++ if (!r->initialized && nbits > 0) { ++ r->entropy_total += nbits; ++ if (r->entropy_total > 128) ++ r->initialized = 1; ++ } ++ ++ trace_credit_entropy_bits(r->name, nbits, entropy_count, ++ r->entropy_total, _RET_IP_); + + /* should we wake readers? */ + if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { + wake_up_interruptible(&random_read_wait); + kill_fasync(&fasync, SIGIO, POLL_IN); + } +- spin_unlock_irqrestore(&r->lock, flags); + } + + /********************************************************************* +@@ -609,6 +670,25 @@ static void set_timer_rand_state(unsigne + } + #endif + ++/* ++ * Add device- or boot-specific data to the input and nonblocking ++ * pools to help initialize them to unique values. ++ * ++ * None of this adds any entropy, it is meant to avoid the ++ * problem of the nonblocking pool having similar initial state ++ * across largely identical devices. ++ */ ++void add_device_randomness(const void *buf, unsigned int size) ++{ ++ unsigned long time = get_cycles() ^ jiffies; ++ ++ mix_pool_bytes(&input_pool, buf, size, NULL); ++ mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); ++ mix_pool_bytes(&nonblocking_pool, buf, size, NULL); ++ mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); ++} ++EXPORT_SYMBOL(add_device_randomness); ++ + static struct timer_rand_state input_timer_state; + + /* +@@ -637,13 +717,9 @@ static void add_timer_randomness(struct + goto out; + + sample.jiffies = jiffies; +- +- /* Use arch random value, fall back to cycles */ +- if (!arch_get_random_int(&sample.cycles)) +- sample.cycles = get_cycles(); +- ++ sample.cycles = get_cycles(); + sample.num = num; +- mix_pool_bytes(&input_pool, &sample, sizeof(sample)); ++ mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); + + /* + * Calculate number of bits of randomness we probably added. +@@ -700,17 +776,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), NULL); ++ /* ++ * 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 +@@ -742,7 +849,11 @@ static ssize_t extract_entropy(struct en + */ + static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) + { +- __u32 tmp[OUTPUT_POOL_WORDS]; ++ union { ++ __u32 tmp[OUTPUT_POOL_WORDS]; ++ long hwrand[4]; ++ } u; ++ int i; + + if (r->pull && r->entropy_count < nbytes * 8 && + r->entropy_count < r->poolinfo->POOLBITS) { +@@ -753,17 +864,22 @@ static void xfer_secondary_pool(struct e + /* pull at least as many as BYTES as wakeup BITS */ + bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); + /* but never more than the buffer size */ +- bytes = min_t(int, bytes, sizeof(tmp)); ++ bytes = min_t(int, bytes, sizeof(u.tmp)); + + DEBUG_ENT("going to reseed %s with %d bits " + "(%d of %d requested)\n", + r->name, bytes * 8, nbytes * 8, r->entropy_count); + +- bytes = extract_entropy(r->pull, tmp, bytes, ++ bytes = extract_entropy(r->pull, u.tmp, bytes, + random_read_wakeup_thresh / 8, rsvd); +- mix_pool_bytes(r, tmp, bytes); ++ mix_pool_bytes(r, u.tmp, bytes, NULL); + credit_entropy_bits(r, bytes*8); + } ++ for (i = 0; i < 4; i++) ++ if (arch_get_random_long(&u.hwrand[i])) ++ break; ++ if (i) ++ mix_pool_bytes(r, &u.hwrand, i * sizeof(u.hwrand[0]), 0); + } + + /* +@@ -822,9 +938,11 @@ static void extract_buf(struct entropy_s + int i; + __u32 hash[5], workspace[SHA_WORKSPACE_WORDS]; + __u8 extract[64]; ++ unsigned long flags; + + /* Generate a hash across the pool, 16 words (512 bits) at a time */ + sha_init(hash); ++ spin_lock_irqsave(&r->lock, flags); + for (i = 0; i < r->poolinfo->poolwords; i += 16) + sha_transform(hash, (__u8 *)(r->pool + i), workspace); + +@@ -837,7 +955,8 @@ static void extract_buf(struct entropy_s + * brute-forcing the feedback as hard as brute-forcing the + * hash. + */ +- mix_pool_bytes_extract(r, hash, sizeof(hash), extract); ++ __mix_pool_bytes(r, hash, sizeof(hash), extract); ++ spin_unlock_irqrestore(&r->lock, flags); + + /* + * To avoid duplicates, we atomically extract a portion of the +@@ -860,12 +979,12 @@ static void extract_buf(struct entropy_s + } + + static ssize_t extract_entropy(struct entropy_store *r, void *buf, +- size_t nbytes, int min, int reserved) ++ size_t nbytes, int min, int reserved) + { + ssize_t ret = 0, i; + __u8 tmp[EXTRACT_SIZE]; +- unsigned long flags; + ++ trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); + xfer_secondary_pool(r, nbytes); + nbytes = account(r, nbytes, min, reserved); + +@@ -873,6 +992,8 @@ static ssize_t extract_entropy(struct en + extract_buf(r, tmp); + + if (fips_enabled) { ++ unsigned long flags; ++ + spin_lock_irqsave(&r->lock, flags); + if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) + panic("Hardware RNG duplicated output!\n"); +@@ -898,6 +1019,7 @@ static ssize_t extract_entropy_user(stru + ssize_t ret = 0, i; + __u8 tmp[EXTRACT_SIZE]; + ++ trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_); + xfer_secondary_pool(r, nbytes); + nbytes = account(r, nbytes, 0, 0); + +@@ -931,17 +1053,35 @@ static ssize_t extract_entropy_user(stru + + /* + * This function is the exported kernel interface. It returns some +- * number of good random numbers, suitable for seeding TCP sequence +- * numbers, etc. ++ * number of good random numbers, suitable for key generation, seeding ++ * TCP sequence numbers, etc. It does not use the hw random number ++ * generator, if available; use get_random_bytes_arch() for that. + */ + void get_random_bytes(void *buf, int nbytes) + { ++ extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); ++} ++EXPORT_SYMBOL(get_random_bytes); ++ ++/* ++ * This function will use the architecture-specific hardware random ++ * number generator if it is available. The arch-specific hw RNG will ++ * almost certainly be faster than what we can do in software, but it ++ * is impossible to verify that it is implemented securely (as ++ * opposed, to, say, the AES encryption of a sequence number using a ++ * key known by the NSA). So it's useful if we need the speed, but ++ * only if we're willing to trust the hardware manufacturer not to ++ * have put in a back door. ++ */ ++void get_random_bytes_arch(void *buf, int nbytes) ++{ + char *p = buf; + ++ trace_get_random_bytes(nbytes, _RET_IP_); + while (nbytes) { + unsigned long v; + int chunk = min(nbytes, (int)sizeof(unsigned long)); +- ++ + if (!arch_get_random_long(&v)) + break; + +@@ -950,9 +1090,11 @@ void get_random_bytes(void *buf, int nby + nbytes -= chunk; + } + +- extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); ++ if (nbytes) ++ extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); + } +-EXPORT_SYMBOL(get_random_bytes); ++EXPORT_SYMBOL(get_random_bytes_arch); ++ + + /* + * init_std_data - initialize pool with system data +@@ -966,21 +1108,18 @@ EXPORT_SYMBOL(get_random_bytes); + static void init_std_data(struct entropy_store *r) + { + int i; +- ktime_t now; +- unsigned long flags; ++ ktime_t now = ktime_get_real(); ++ unsigned long rv; + +- spin_lock_irqsave(&r->lock, flags); + r->entropy_count = 0; +- spin_unlock_irqrestore(&r->lock, flags); +- +- now = ktime_get_real(); +- mix_pool_bytes(r, &now, sizeof(now)); +- for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof flags) { +- if (!arch_get_random_long(&flags)) ++ r->entropy_total = 0; ++ mix_pool_bytes(r, &now, sizeof(now), NULL); ++ for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { ++ if (!arch_get_random_long(&rv)) + break; +- mix_pool_bytes(r, &flags, sizeof(flags)); ++ mix_pool_bytes(r, &rv, sizeof(rv), NULL); + } +- mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); ++ mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); + } + + static int rand_initialize(void) +@@ -1117,7 +1256,7 @@ write_pool(struct entropy_store *r, cons + count -= bytes; + p += bytes; + +- mix_pool_bytes(r, buf, bytes); ++ mix_pool_bytes(r, buf, bytes, NULL); + cond_resched(); + } + +@@ -1274,6 +1413,7 @@ static int proc_do_uuid(ctl_table *table + } + + static int sysctl_poolsize = INPUT_POOL_WORDS * 32; ++extern ctl_table random_table[]; + ctl_table random_table[] = { + { + .procname = "poolsize", +@@ -1339,7 +1479,7 @@ late_initcall(random_int_secret_init); + * value is not cryptographically secure but for several uses the cost of + * depleting entropy is too high + */ +-DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); ++static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); + unsigned int get_random_int(void) + { + __u32 *hash; +--- a/drivers/mfd/ab3100-core.c ++++ b/drivers/mfd/ab3100-core.c +@@ -409,8 +409,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/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1896,6 +1897,14 @@ int usb_new_device(struct usb_device *ud + /* Tell the world! */ + announce_device(udev); + ++ if (udev->serial) ++ add_device_randomness(udev->serial, strlen(udev->serial)); ++ if (udev->product) ++ add_device_randomness(udev->product, strlen(udev->product)); ++ if (udev->manufacturer) ++ add_device_randomness(udev->manufacturer, ++ strlen(udev->manufacturer)); ++ + device_enable_async_suspend(&udev->dev); + /* Register the device. The device driver is responsible + * for configuring the device and invoking the add-device +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -50,11 +50,13 @@ struct rnd_state { + + extern void rand_initialize_irq(int irq); + ++extern void add_device_randomness(const void *, unsigned int); + 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); ++extern void get_random_bytes_arch(void *buf, int nbytes); + void generate_random_uuid(unsigned char uuid_out[16]); + + #ifndef MODULE +--- /dev/null ++++ b/include/trace/events/random.h +@@ -0,0 +1,134 @@ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM random ++ ++#if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_RANDOM_H ++ ++#include ++#include ++ ++DECLARE_EVENT_CLASS(random__mix_pool_bytes, ++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP), ++ ++ TP_ARGS(pool_name, bytes, IP), ++ ++ TP_STRUCT__entry( ++ __field( const char *, pool_name ) ++ __field( int, bytes ) ++ __field(unsigned long, IP ) ++ ), ++ ++ TP_fast_assign( ++ __entry->pool_name = pool_name; ++ __entry->bytes = bytes; ++ __entry->IP = IP; ++ ), ++ ++ TP_printk("%s pool: bytes %d caller %pF", ++ __entry->pool_name, __entry->bytes, (void *)__entry->IP) ++); ++ ++DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes, ++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP), ++ ++ TP_ARGS(pool_name, bytes, IP) ++); ++ ++DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock, ++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP), ++ ++ TP_ARGS(pool_name, bytes, IP) ++); ++ ++TRACE_EVENT(credit_entropy_bits, ++ TP_PROTO(const char *pool_name, int bits, int entropy_count, ++ int entropy_total, unsigned long IP), ++ ++ TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP), ++ ++ TP_STRUCT__entry( ++ __field( const char *, pool_name ) ++ __field( int, bits ) ++ __field( int, entropy_count ) ++ __field( int, entropy_total ) ++ __field(unsigned long, IP ) ++ ), ++ ++ TP_fast_assign( ++ __entry->pool_name = pool_name; ++ __entry->bits = bits; ++ __entry->entropy_count = entropy_count; ++ __entry->entropy_total = entropy_total; ++ __entry->IP = IP; ++ ), ++ ++ TP_printk("%s pool: bits %d entropy_count %d entropy_total %d " ++ "caller %pF", __entry->pool_name, __entry->bits, ++ __entry->entropy_count, __entry->entropy_total, ++ (void *)__entry->IP) ++); ++ ++TRACE_EVENT(get_random_bytes, ++ TP_PROTO(int nbytes, unsigned long IP), ++ ++ TP_ARGS(nbytes, IP), ++ ++ TP_STRUCT__entry( ++ __field( int, nbytes ) ++ __field(unsigned long, IP ) ++ ), ++ ++ TP_fast_assign( ++ __entry->nbytes = nbytes; ++ __entry->IP = IP; ++ ), ++ ++ TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP) ++); ++ ++DECLARE_EVENT_CLASS(random__extract_entropy, ++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count, ++ unsigned long IP), ++ ++ TP_ARGS(pool_name, nbytes, entropy_count, IP), ++ ++ TP_STRUCT__entry( ++ __field( const char *, pool_name ) ++ __field( int, nbytes ) ++ __field( int, entropy_count ) ++ __field(unsigned long, IP ) ++ ), ++ ++ TP_fast_assign( ++ __entry->pool_name = pool_name; ++ __entry->nbytes = nbytes; ++ __entry->entropy_count = entropy_count; ++ __entry->IP = IP; ++ ), ++ ++ TP_printk("%s pool: nbytes %d entropy_count %d caller %pF", ++ __entry->pool_name, __entry->nbytes, __entry->entropy_count, ++ (void *)__entry->IP) ++); ++ ++ ++DEFINE_EVENT(random__extract_entropy, extract_entropy, ++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count, ++ unsigned long IP), ++ ++ TP_ARGS(pool_name, nbytes, entropy_count, IP) ++); ++ ++DEFINE_EVENT(random__extract_entropy, extract_entropy_user, ++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count, ++ unsigned long IP), ++ ++ TP_ARGS(pool_name, nbytes, entropy_count, IP) ++); ++ ++ ++ ++#endif /* _TRACE_RANDOM_H */ ++ ++/* This part must be outside protection */ ++#include +--- 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); +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1176,6 +1176,7 @@ static int __dev_open(struct net_device + net_dmaengine_get(); + dev_set_rx_mode(dev); + dev_activate(dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); + } + + return ret; +@@ -4823,6 +4824,7 @@ int dev_set_mac_address(struct net_devic + err = ops->ndo_set_mac_address(dev, sa); + if (!err) + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); + return err; + } + EXPORT_SYMBOL(dev_set_mac_address); +@@ -5602,6 +5604,7 @@ int register_netdevice(struct net_device + dev_init_scheduler(dev); + dev_hold(dev); + list_netdevice(dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); + + /* Notify protocols, that a new device appeared. */ + ret = call_netdevice_notifiers(NETDEV_REGISTER, dev); +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1371,6 +1371,7 @@ static int do_setlink(struct net_device + goto errout; + send_addr_notify = 1; + modified = 1; ++ add_device_randomness(dev->dev_addr, dev->addr_len); + } + + if (tb[IFLA_MTU]) { diff --git a/target/linux/generic/patches-3.3/051-rng_git_backport-remove_irqf_sample_random.patch b/target/linux/generic/patches-3.3/051-rng_git_backport-remove_irqf_sample_random.patch new file mode 100644 index 0000000000..93706ed3f6 --- /dev/null +++ b/target/linux/generic/patches-3.3/051-rng_git_backport-remove_irqf_sample_random.patch @@ -0,0 +1,543 @@ +--- a/arch/arm/mach-omap1/board-palmz71.c ++++ b/arch/arm/mach-omap1/board-palmz71.c +@@ -291,8 +291,7 @@ palmz71_gpio_setup(int early) + } + gpio_direction_input(PALMZ71_USBDETECT_GPIO); + if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), +- palmz71_powercable, IRQF_SAMPLE_RANDOM, +- "palmz71-cable", 0)) ++ palmz71_powercable, 0, "palmz71-cable", 0)) + printk(KERN_ERR + "IRQ request for power cable failed!\n"); + palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), 0); +--- a/arch/arm/mach-pxa/lubbock.c ++++ b/arch/arm/mach-pxa/lubbock.c +@@ -455,7 +455,7 @@ static int lubbock_mci_init(struct devic + init_timer(&mmc_timer); + mmc_timer.data = (unsigned long) data; + return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, +- IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data); ++ 0, "lubbock-sd-detect", data); + } + + static int lubbock_mci_get_ro(struct device *dev) +--- a/arch/arm/mach-pxa/magician.c ++++ b/arch/arm/mach-pxa/magician.c +@@ -617,9 +617,8 @@ static struct platform_device bq24022 = + static int magician_mci_init(struct device *dev, + irq_handler_t detect_irq, void *data) + { +- return request_irq(IRQ_MAGICIAN_SD, detect_irq, +- IRQF_DISABLED | IRQF_SAMPLE_RANDOM, +- "mmc card detect", data); ++ return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED, ++ "mmc card detect", data); + } + + static void magician_mci_exit(struct device *dev, void *data) +--- a/arch/arm/mach-pxa/trizeps4.c ++++ b/arch/arm/mach-pxa/trizeps4.c +@@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct devi + int err; + + err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, +- IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM, +- "MMC card detect", data); ++ IRQF_DISABLED | IRQF_TRIGGER_RISING, ++ "MMC card detect", data); + if (err) { + printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" + "MMC card detect IRQ\n"); +--- a/arch/ia64/kernel/irq_ia64.c ++++ b/arch/ia64/kernel/irq_ia64.c +@@ -23,7 +23,6 @@ + #include + #include + #include +-#include /* for rand_initialize_irq() */ + #include + #include + #include +--- a/arch/sparc/kernel/ldc.c ++++ b/arch/sparc/kernel/ldc.c +@@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, con + snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); + snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); + +- err = request_irq(lp->cfg.rx_irq, ldc_rx, +- IRQF_SAMPLE_RANDOM | IRQF_DISABLED, ++ err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED, + lp->rx_irq_name, lp); + if (err) + return err; + +- err = request_irq(lp->cfg.tx_irq, ldc_tx, +- IRQF_SAMPLE_RANDOM | IRQF_DISABLED, ++ err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED, + lp->tx_irq_name, lp); + if (err) { + free_irq(lp->cfg.rx_irq, lp); +--- a/arch/um/drivers/line.c ++++ b/arch/um/drivers/line.c +@@ -371,7 +371,7 @@ static irqreturn_t line_write_interrupt( + int line_setup_irq(int fd, int input, int output, struct line *line, void *data) + { + const struct line_driver *driver = line->driver; +- int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM; ++ int err = 0, flags = IRQF_DISABLED | IRQF_SHARED; + + if (input) + err = um_request_irq(driver->read_irq, fd, IRQ_READ, +@@ -807,7 +807,7 @@ void register_winch_irq(int fd, int tty_ + .stack = stack }); + + if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, +- IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, ++ IRQF_DISABLED | IRQF_SHARED, + "winch", winch) < 0) { + printk(KERN_ERR "register_winch_irq - failed to register " + "IRQ\n"); +--- a/arch/um/drivers/mconsole_kern.c ++++ b/arch/um/drivers/mconsole_kern.c +@@ -773,7 +773,7 @@ static int __init mconsole_init(void) + register_reboot_notifier(&reboot_notifier); + + err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, +- IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, ++ IRQF_DISABLED | IRQF_SHARED, + "mconsole", (void *)sock); + if (err) { + printk(KERN_ERR "Failed to get IRQ for management console\n"); +--- a/arch/um/drivers/port_kern.c ++++ b/arch/um/drivers/port_kern.c +@@ -100,7 +100,7 @@ static int port_accept(struct port_list + .port = port }); + + if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, +- IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, ++ IRQF_DISABLED | IRQF_SHARED, + "telnetd", conn)) { + printk(KERN_ERR "port_accept : failed to get IRQ for " + "telnetd\n"); +@@ -184,7 +184,7 @@ void *port_data(int port_num) + } + + if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, +- IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, ++ IRQF_DISABLED | IRQF_SHARED, + "port", port)) { + printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); + goto out_close; +--- a/arch/um/drivers/random.c ++++ b/arch/um/drivers/random.c +@@ -131,8 +131,7 @@ static int __init rng_init (void) + random_fd = err; + + err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, +- IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random", +- NULL); ++ IRQF_DISABLED, "random", NULL); + if (err) + goto err_out_cleanup_hw; + +--- a/arch/um/drivers/xterm_kern.c ++++ b/arch/um/drivers/xterm_kern.c +@@ -50,8 +50,7 @@ int xterm_fd(int socket, int *pid_out) + init_completion(&data->ready); + + err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, +- IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, +- "xterm", data); ++ IRQF_DISABLED | IRQF_SHARED, "xterm", data); + if (err) { + printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " + "err = %d\n", err); +--- a/arch/um/kernel/sigio.c ++++ b/arch/um/kernel/sigio.c +@@ -25,8 +25,7 @@ int write_sigio_irq(int fd) + int err; + + err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, +- IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio", +- NULL); ++ IRQF_DISABLED, "write sigio", NULL); + if (err) { + printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " + "err = %d\n", err); +--- a/Documentation/feature-removal-schedule.txt ++++ b/Documentation/feature-removal-schedule.txt +@@ -71,20 +71,6 @@ Who: Luis R. Rodriguez & Matt Mackall +- +---------------------------- +- + What: The ieee80211_regdom module parameter + When: March 2010 / desktop catchup + +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -852,9 +852,8 @@ static int setup_blkring(struct xenbus_d + if (err) + goto fail; + +- err = bind_evtchn_to_irqhandler(info->evtchn, +- blkif_interrupt, +- IRQF_SAMPLE_RANDOM, "blkif", info); ++ err = bind_evtchn_to_irqhandler(info->evtchn, blkif_interrupt, 0, ++ "blkif", info); + if (err <= 0) { + xenbus_dev_fatal(dev, err, + "bind_evtchn_to_irqhandler failed"); +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -633,43 +633,6 @@ struct timer_rand_state { + unsigned dont_count_entropy:1; + }; + +-#ifndef CONFIG_GENERIC_HARDIRQS +- +-static struct timer_rand_state *irq_timer_state[NR_IRQS]; +- +-static struct timer_rand_state *get_timer_rand_state(unsigned int irq) +-{ +- return irq_timer_state[irq]; +-} +- +-static void set_timer_rand_state(unsigned int irq, +- struct timer_rand_state *state) +-{ +- irq_timer_state[irq] = state; +-} +- +-#else +- +-static struct timer_rand_state *get_timer_rand_state(unsigned int irq) +-{ +- struct irq_desc *desc; +- +- desc = irq_to_desc(irq); +- +- return desc->timer_rand_state; +-} +- +-static void set_timer_rand_state(unsigned int irq, +- struct timer_rand_state *state) +-{ +- struct irq_desc *desc; +- +- desc = irq_to_desc(irq); +- +- desc->timer_rand_state = state; +-} +-#endif +- + /* + * Add device- or boot-specific data to the input and nonblocking + * pools to help initialize them to unique values. +@@ -1131,24 +1094,6 @@ static int rand_initialize(void) + } + module_init(rand_initialize); + +-void rand_initialize_irq(int irq) +-{ +- struct timer_rand_state *state; +- +- state = get_timer_rand_state(irq); +- +- if (state) +- return; +- +- /* +- * If kzalloc returns null, we just won't use that entropy +- * source. +- */ +- state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); +- if (state) +- set_timer_rand_state(irq, state); +-} +- + #ifdef CONFIG_BLOCK + void rand_initialize_disk(struct gendisk *disk) + { +--- a/drivers/crypto/n2_core.c ++++ b/drivers/crypto/n2_core.c +@@ -1607,8 +1607,7 @@ static int spu_map_ino(struct platform_d + + sprintf(p->irq_name, "%s-%d", irq_name, index); + +- return request_irq(p->irq, handler, IRQF_SAMPLE_RANDOM, +- p->irq_name, p); ++ return request_irq(p->irq, handler, 0, p->irq_name, p); + } + + static struct kmem_cache *queue_cache[2]; +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -545,8 +545,7 @@ static int vmbus_bus_init(int irq) + if (ret) + goto err_cleanup; + +- ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, +- driver_name, hv_acpi_dev); ++ ret = request_irq(irq, vmbus_isr, 0, driver_name, hv_acpi_dev); + + if (ret != 0) { + pr_err("Unable to request IRQ %d\n", +--- a/drivers/i2c/busses/i2c-pmcmsp.c ++++ b/drivers/i2c/busses/i2c-pmcmsp.c +@@ -306,8 +306,7 @@ static int __devinit pmcmsptwi_probe(str + pmcmsptwi_data.irq = platform_get_irq(pldev, 0); + if (pmcmsptwi_data.irq) { + rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt, +- IRQF_SHARED | IRQF_SAMPLE_RANDOM, +- pldev->name, &pmcmsptwi_data); ++ IRQF_SHARED, pldev->name, &pmcmsptwi_data); + if (rc == 0) { + /* + * Enable 'DONE' interrupt only. +--- a/drivers/input/serio/hp_sdc.c ++++ b/drivers/input/serio/hp_sdc.c +@@ -879,7 +879,7 @@ static int __init hp_sdc_init(void) + #endif + + errstr = "IRQ not available for"; +- if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, ++ if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED, + "HP SDC", &hp_sdc)) + goto err1; + +--- a/drivers/mfd/ab3100-core.c ++++ b/drivers/mfd/ab3100-core.c +@@ -937,9 +937,6 @@ static int __devinit ab3100_probe(struct + + err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler, + IRQF_ONESHOT, "ab3100-core", ab3100); +- /* This real unpredictable IRQ is of course sampled for entropy */ +- rand_initialize_irq(client->irq); +- + if (err) + goto exit_no_irq; + +--- a/drivers/mfd/tps65010.c ++++ b/drivers/mfd/tps65010.c +@@ -563,8 +563,7 @@ static int tps65010_probe(struct i2c_cli + */ + if (client->irq > 0) { + status = request_irq(client->irq, tps65010_irq, +- IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, +- DRIVER_NAME, tps); ++ IRQF_TRIGGER_FALLING, DRIVER_NAME, tps); + if (status < 0) { + dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", + client->irq, status); +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -9415,7 +9415,7 @@ static int tg3_test_interrupt(struct tg3 + } + + err = request_irq(tnapi->irq_vec, tg3_test_isr, +- IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, tnapi); ++ IRQF_SHARED, dev->name, tnapi); + if (err) + return err; + +--- a/drivers/power/pda_power.c ++++ b/drivers/power/pda_power.c +@@ -24,11 +24,7 @@ + + static inline unsigned int get_irq_flags(struct resource *res) + { +- unsigned int flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED; +- +- flags |= res->flags & IRQF_TRIGGER_MASK; +- +- return flags; ++ return IRQF_SHARED | (res->flags & IRQF_TRIGGER_MASK); + } + + static struct device *dev; +--- a/drivers/tty/serial/uartlite.c ++++ b/drivers/tty/serial/uartlite.c +@@ -216,8 +216,7 @@ static int ulite_startup(struct uart_por + { + int ret; + +- ret = request_irq(port->irq, ulite_isr, +- IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port); ++ ret = request_irq(port->irq, ulite_isr, IRQF_SHARED, "uartlite", port); + if (ret) + return ret; + +--- a/drivers/usb/gadget/goku_udc.c ++++ b/drivers/usb/gadget/goku_udc.c +@@ -1839,7 +1839,7 @@ static int goku_probe(struct pci_dev *pd + /* init to known state, then setup irqs */ + udc_reset(dev); + udc_reinit (dev); +- if (request_irq(pdev->irq, goku_irq, IRQF_SHARED/*|IRQF_SAMPLE_RANDOM*/, ++ if (request_irq(pdev->irq, goku_irq, IRQF_SHARED, + driver_name, dev) != 0) { + DBG(dev, "request interrupt %d failed\n", pdev->irq); + retval = -EBUSY; +--- a/drivers/usb/gadget/omap_udc.c ++++ b/drivers/usb/gadget/omap_udc.c +@@ -2943,7 +2943,7 @@ known: + + /* USB general purpose IRQ: ep0, state changes, dma, etc */ + status = request_irq(pdev->resource[1].start, omap_udc_irq, +- IRQF_SAMPLE_RANDOM, driver_name, udc); ++ 0, driver_name, udc); + if (status != 0) { + ERR("can't get irq %d, err %d\n", + (int) pdev->resource[1].start, status); +@@ -2952,7 +2952,7 @@ known: + + /* USB "non-iso" IRQ (PIO for all but ep0) */ + status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, +- IRQF_SAMPLE_RANDOM, "omap_udc pio", udc); ++ 0, "omap_udc pio", udc); + if (status != 0) { + ERR("can't get irq %d, err %d\n", + (int) pdev->resource[2].start, status); +--- a/drivers/usb/gadget/pxa25x_udc.c ++++ b/drivers/usb/gadget/pxa25x_udc.c +@@ -2202,19 +2202,15 @@ static int __init pxa25x_udc_probe(struc + + #ifdef CONFIG_ARCH_LUBBOCK + if (machine_is_lubbock()) { +- retval = request_irq(LUBBOCK_USB_DISC_IRQ, +- lubbock_vbus_irq, +- IRQF_SAMPLE_RANDOM, +- driver_name, dev); ++ retval = request_irq(LUBBOCK_USB_DISC_IRQ, lubbock_vbus_irq, ++ 0, driver_name, dev); + if (retval != 0) { + pr_err("%s: can't get irq %i, err %d\n", + driver_name, LUBBOCK_USB_DISC_IRQ, retval); + goto err_irq_lub; + } +- retval = request_irq(LUBBOCK_USB_IRQ, +- lubbock_vbus_irq, +- IRQF_SAMPLE_RANDOM, +- driver_name, dev); ++ retval = request_irq(LUBBOCK_USB_IRQ, lubbock_vbus_irq, ++ 0, driver_name, dev); + if (retval != 0) { + pr_err("%s: can't get irq %i, err %d\n", + driver_name, LUBBOCK_USB_IRQ, retval); +--- a/drivers/usb/otg/gpio_vbus.c ++++ b/drivers/usb/otg/gpio_vbus.c +@@ -51,8 +51,7 @@ struct gpio_vbus_data { + * edges might be workable. + */ + #define VBUS_IRQ_FLAGS \ +- ( IRQF_SAMPLE_RANDOM | IRQF_SHARED \ +- | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING ) ++ ( IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING ) + + + /* interface to regulator framework */ +@@ -253,7 +252,7 @@ static int __init gpio_vbus_probe(struct + if (res) { + irq = res->start; + res->flags &= IRQF_TRIGGER_MASK; +- res->flags |= IRQF_SAMPLE_RANDOM | IRQF_SHARED; ++ res->flags |= IRQF_SHARED; + } else + irq = gpio_to_irq(gpio); + +--- a/drivers/usb/otg/isp1301_omap.c ++++ b/drivers/usb/otg/isp1301_omap.c +@@ -1567,7 +1567,6 @@ isp1301_probe(struct i2c_client *i2c, co + isp->irq_type = IRQF_TRIGGER_FALLING; + } + +- isp->irq_type |= IRQF_SAMPLE_RANDOM; + status = request_irq(i2c->irq, isp1301_irq, + isp->irq_type, DRIVER_NAME, isp); + if (status < 0) { +--- a/include/linux/interrupt.h ++++ b/include/linux/interrupt.h +@@ -44,7 +44,6 @@ + * + * IRQF_DISABLED - keep irqs disabled when calling the action handler. + * DEPRECATED. This flag is a NOOP and scheduled to be removed +- * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator + * IRQF_SHARED - allow sharing the irq among several devices + * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur + * IRQF_TIMER - Flag to mark this interrupt as timer interrupt +@@ -63,7 +62,6 @@ + * resume time. + */ + #define IRQF_DISABLED 0x00000020 +-#define IRQF_SAMPLE_RANDOM 0x00000040 + #define IRQF_SHARED 0x00000080 + #define IRQF_PROBE_SHARED 0x00000100 + #define __IRQF_TIMER 0x00000200 +--- a/include/linux/irqdesc.h ++++ b/include/linux/irqdesc.h +@@ -39,7 +39,6 @@ struct module; + */ + struct irq_desc { + struct irq_data irq_data; +- struct timer_rand_state *timer_rand_state; + unsigned int __percpu *kstat_irqs; + irq_flow_handler_t handle_irq; + #ifdef CONFIG_IRQ_PREFLOW_FASTEOI +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -48,8 +48,6 @@ struct rnd_state { + + #ifdef __KERNEL__ + +-extern void rand_initialize_irq(int irq); +- + extern void add_device_randomness(const void *, unsigned int); + extern void add_input_randomness(unsigned int type, unsigned int code, + unsigned int value); +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -891,22 +891,6 @@ __setup_irq(unsigned int irq, struct irq + return -ENOSYS; + if (!try_module_get(desc->owner)) + return -ENODEV; +- /* +- * Some drivers like serial.c use request_irq() heavily, +- * so we have to be careful not to interfere with a +- * running system. +- */ +- if (new->flags & IRQF_SAMPLE_RANDOM) { +- /* +- * This function might sleep, we want to call it first, +- * outside of the atomic block. +- * Yes, this might clear the entropy pool if the wrong +- * driver is attempted to be loaded, without actually +- * installing a new handler, but is this really a problem, +- * only the sysadmin is able to do this. +- */ +- rand_initialize_irq(irq); +- } + + /* + * Check whether the interrupt nests into another interrupt +@@ -1342,7 +1326,6 @@ EXPORT_SYMBOL(free_irq); + * Flags: + * + * IRQF_SHARED Interrupt is shared +- * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy + * IRQF_TRIGGER_* Specify active edge(s) or level + * + */ diff --git a/target/linux/generic/patches-3.3/941-ocf_20120127.patch b/target/linux/generic/patches-3.3/941-ocf_20120127.patch index 366a2586d4..794627a854 100644 --- a/target/linux/generic/patches-3.3/941-ocf_20120127.patch +++ b/target/linux/generic/patches-3.3/941-ocf_20120127.patch @@ -1,7 +1,7 @@ --- a/drivers/char/random.c +++ b/drivers/char/random.c -@@ -130,6 +130,9 @@ - * void add_interrupt_randomness(int irq); +@@ -131,6 +131,9 @@ + * void add_interrupt_randomness(int irq, int irq_flags); * void add_disk_randomness(struct gendisk *disk); * + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count) @@ -10,7 +10,7 @@ * add_input_randomness() uses the input layer interrupt timing, as well as * the event type information from the hardware. * -@@ -147,6 +150,13 @@ +@@ -152,6 +155,13 @@ * seek times do not make for good sources of entropy, as their seek * times are usually fairly consistent. * @@ -24,7 +24,7 @@ * All of these routines try to estimate how many bits of randomness a * particular randomness source. They do this by keeping track of the * first and second order deltas of the event timings. -@@ -726,6 +736,63 @@ void add_disk_randomness(struct gendisk +@@ -796,6 +806,63 @@ void add_disk_randomness(struct gendisk } #endif @@ -40,7 +40,7 @@ + */ +void random_input_words(__u32 *buf, size_t wordcount, int ent_count) +{ -+ mix_pool_bytes(&input_pool, buf, wordcount*4); ++ mix_pool_bytes(&input_pool, buf, wordcount*4, NULL); + + credit_entropy_bits(&input_pool, ent_count); + @@ -141,17 +141,17 @@ struct rand_pool_info { int entropy_count; int buf_size; -@@ -54,6 +78,10 @@ extern void add_input_randomness(unsigne +@@ -53,6 +77,10 @@ extern void add_input_randomness(unsigne unsigned int value); - extern void add_interrupt_randomness(int irq); + extern void add_interrupt_randomness(int irq, int irq_flags); +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count); +extern int random_input_wait(void); +#define HAS_RANDOM_INPUT_WAIT 1 + extern void get_random_bytes(void *buf, int nbytes); + extern void get_random_bytes_arch(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); - --- a/kernel/pid.c +++ b/kernel/pid.c @@ -430,6 +430,7 @@ struct task_struct *find_task_by_vpid(pi