parent
4a67ccb163
commit
eb97933e2a
@ -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 <linux/percpu.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/fips.h>
|
||||
+#include <linux/ptrace.h>
|
||||
|
||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||
# include <linux/irq.h>
|
||||
@@ -256,8 +262,12 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/irq.h>
|
||||
+#include <asm/irq_regs.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
+#define CREATE_TRACE_POINTS
|
||||
+#include <trace/events/random.h>
|
||||
+
|
||||
/*
|
||||
* 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 <linux/kthread.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/freezer.h>
|
||||
+#include <linux/random.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
@@ -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 <linux/writeback.h>
|
||||
+#include <linux/tracepoint.h>
|
||||
+
|
||||
+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 <trace/define_trace.h>
|
||||
--- 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]) {
|
@ -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 <linux/ioport.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/ptrace.h>
|
||||
-#include <linux/random.h> /* for rand_initialize_irq() */
|
||||
#include <linux/signal.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/threads.h>
|
||||
--- 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 <lrodriguez@ather
|
||||
|
||||
---------------------------
|
||||
|
||||
-What: IRQF_SAMPLE_RANDOM
|
||||
-Check: IRQF_SAMPLE_RANDOM
|
||||
-When: July 2009
|
||||
-
|
||||
-Why: Many of IRQF_SAMPLE_RANDOM users are technically bogus as entropy
|
||||
- sources in the kernel's current entropy model. To resolve this, every
|
||||
- input point to the kernel's entropy pool needs to better document the
|
||||
- type of entropy source it actually is. This will be replaced with
|
||||
- additional add_*_randomness functions in drivers/char/random.c
|
||||
-
|
||||
-Who: Robin Getz <rgetz@blackfin.uclinux.org> & Matt Mackall <mpm@selenic.com>
|
||||
-
|
||||
----------------------------
|
||||
-
|
||||
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
|
||||
*
|
||||
*/
|
Loading…
Reference in new issue