diff options
39 files changed, 452 insertions, 233 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 09b132dd062d..24fec7603e5e 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -70,20 +70,6 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com> | |||
70 | 70 | ||
71 | --------------------------- | 71 | --------------------------- |
72 | 72 | ||
73 | What: IRQF_SAMPLE_RANDOM | ||
74 | Check: IRQF_SAMPLE_RANDOM | ||
75 | When: July 2009 | ||
76 | |||
77 | Why: Many of IRQF_SAMPLE_RANDOM users are technically bogus as entropy | ||
78 | sources in the kernel's current entropy model. To resolve this, every | ||
79 | input point to the kernel's entropy pool needs to better document the | ||
80 | type of entropy source it actually is. This will be replaced with | ||
81 | additional add_*_randomness functions in drivers/char/random.c | ||
82 | |||
83 | Who: Robin Getz <rgetz@blackfin.uclinux.org> & Matt Mackall <mpm@selenic.com> | ||
84 | |||
85 | --------------------------- | ||
86 | |||
87 | What: The ieee80211_regdom module parameter | 73 | What: The ieee80211_regdom module parameter |
88 | When: March 2010 / desktop catchup | 74 | When: March 2010 / desktop catchup |
89 | 75 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 5b44872b64ec..36ed8a14e8e2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5682,7 +5682,7 @@ F: Documentation/blockdev/ramdisk.txt | |||
5682 | F: drivers/block/brd.c | 5682 | F: drivers/block/brd.c |
5683 | 5683 | ||
5684 | RANDOM NUMBER DRIVER | 5684 | RANDOM NUMBER DRIVER |
5685 | M: Matt Mackall <mpm@selenic.com> | 5685 | M: Theodore Ts'o" <tytso@mit.edu> |
5686 | S: Maintained | 5686 | S: Maintained |
5687 | F: drivers/char/random.c | 5687 | F: drivers/char/random.c |
5688 | 5688 | ||
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index cc71a26723ef..355980321c2d 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c | |||
@@ -288,8 +288,7 @@ palmz71_gpio_setup(int early) | |||
288 | } | 288 | } |
289 | gpio_direction_input(PALMZ71_USBDETECT_GPIO); | 289 | gpio_direction_input(PALMZ71_USBDETECT_GPIO); |
290 | if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), | 290 | if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), |
291 | palmz71_powercable, IRQF_SAMPLE_RANDOM, | 291 | palmz71_powercable, 0, "palmz71-cable", NULL)) |
292 | "palmz71-cable", NULL)) | ||
293 | printk(KERN_ERR | 292 | printk(KERN_ERR |
294 | "IRQ request for power cable failed!\n"); | 293 | "IRQ request for power cable failed!\n"); |
295 | palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); | 294 | palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6bb3f47b1f14..0ca0db787903 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
@@ -456,7 +456,7 @@ static int lubbock_mci_init(struct device *dev, | |||
456 | init_timer(&mmc_timer); | 456 | init_timer(&mmc_timer); |
457 | mmc_timer.data = (unsigned long) data; | 457 | mmc_timer.data = (unsigned long) data; |
458 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, | 458 | return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, |
459 | IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data); | 459 | 0, "lubbock-sd-detect", data); |
460 | } | 460 | } |
461 | 461 | ||
462 | static int lubbock_mci_get_ro(struct device *dev) | 462 | static int lubbock_mci_get_ro(struct device *dev) |
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 2db697cd2b4e..39561dcf65f2 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c | |||
@@ -633,9 +633,8 @@ static struct platform_device bq24022 = { | |||
633 | static int magician_mci_init(struct device *dev, | 633 | static int magician_mci_init(struct device *dev, |
634 | irq_handler_t detect_irq, void *data) | 634 | irq_handler_t detect_irq, void *data) |
635 | { | 635 | { |
636 | return request_irq(IRQ_MAGICIAN_SD, detect_irq, | 636 | return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED, |
637 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 637 | "mmc card detect", data); |
638 | "mmc card detect", data); | ||
639 | } | 638 | } |
640 | 639 | ||
641 | static void magician_mci_exit(struct device *dev, void *data) | 640 | static void magician_mci_exit(struct device *dev, void *data) |
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 2b6ac00b2cd9..166dd32cc1d3 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c | |||
@@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, | |||
332 | int err; | 332 | int err; |
333 | 333 | ||
334 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, | 334 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, |
335 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM, | 335 | IRQF_DISABLED | IRQF_TRIGGER_RISING, |
336 | "MMC card detect", data); | 336 | "MMC card detect", data); |
337 | if (err) { | 337 | if (err) { |
338 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" | 338 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" |
339 | "MMC card detect IRQ\n"); | 339 | "MMC card detect IRQ\n"); |
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 5c3e0888265a..1034884b77da 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
24 | #include <linux/kernel_stat.h> | 24 | #include <linux/kernel_stat.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/random.h> /* for rand_initialize_irq() */ | ||
27 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
28 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
29 | #include <linux/threads.h> | 28 | #include <linux/threads.h> |
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 435e406fdec3..81d92fc9983b 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c | |||
@@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name) | |||
1250 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); | 1250 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); |
1251 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | 1251 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); |
1252 | 1252 | ||
1253 | err = request_irq(lp->cfg.rx_irq, ldc_rx, | 1253 | err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED, |
1254 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
1255 | lp->rx_irq_name, lp); | 1254 | lp->rx_irq_name, lp); |
1256 | if (err) | 1255 | if (err) |
1257 | return err; | 1256 | return err; |
1258 | 1257 | ||
1259 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | 1258 | err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED, |
1260 | IRQF_SAMPLE_RANDOM | IRQF_DISABLED, | ||
1261 | lp->tx_irq_name, lp); | 1259 | lp->tx_irq_name, lp); |
1262 | if (err) { | 1260 | if (err) { |
1263 | free_irq(lp->cfg.rx_irq, lp); | 1261 | free_irq(lp->cfg.rx_irq, lp); |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index acfd0e0fd0c9..ac9d25c8dc01 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -362,18 +362,18 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
362 | int line_setup_irq(int fd, int input, int output, struct line *line, void *data) | 362 | int line_setup_irq(int fd, int input, int output, struct line *line, void *data) |
363 | { | 363 | { |
364 | const struct line_driver *driver = line->driver; | 364 | const struct line_driver *driver = line->driver; |
365 | int err = 0, flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM; | 365 | int err = 0; |
366 | 366 | ||
367 | if (input) | 367 | if (input) |
368 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, | 368 | err = um_request_irq(driver->read_irq, fd, IRQ_READ, |
369 | line_interrupt, flags, | 369 | line_interrupt, IRQF_SHARED, |
370 | driver->read_irq_name, data); | 370 | driver->read_irq_name, data); |
371 | if (err) | 371 | if (err) |
372 | return err; | 372 | return err; |
373 | if (output) | 373 | if (output) |
374 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, | 374 | err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, |
375 | line_write_interrupt, flags, | 375 | line_write_interrupt, IRQF_SHARED, |
376 | driver->write_irq_name, data); | 376 | driver->write_irq_name, data); |
377 | return err; | 377 | return err; |
378 | } | 378 | } |
379 | 379 | ||
@@ -779,8 +779,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | |||
779 | .stack = stack }); | 779 | .stack = stack }); |
780 | 780 | ||
781 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, | 781 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, |
782 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 782 | IRQF_SHARED, "winch", winch) < 0) { |
783 | "winch", winch) < 0) { | ||
784 | printk(KERN_ERR "register_winch_irq - failed to register " | 783 | printk(KERN_ERR "register_winch_irq - failed to register " |
785 | "IRQ\n"); | 784 | "IRQ\n"); |
786 | goto out_free; | 785 | goto out_free; |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 43b39d61b538..664a60e8dfb4 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -774,8 +774,7 @@ static int __init mconsole_init(void) | |||
774 | register_reboot_notifier(&reboot_notifier); | 774 | register_reboot_notifier(&reboot_notifier); |
775 | 775 | ||
776 | err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, | 776 | err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, |
777 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 777 | IRQF_SHARED, "mconsole", (void *)sock); |
778 | "mconsole", (void *)sock); | ||
779 | if (err) { | 778 | if (err) { |
780 | printk(KERN_ERR "Failed to get IRQ for management console\n"); | 779 | printk(KERN_ERR "Failed to get IRQ for management console\n"); |
781 | goto out; | 780 | goto out; |
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 11866ffd45a9..1d83d50236e1 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c | |||
@@ -100,8 +100,7 @@ static int port_accept(struct port_list *port) | |||
100 | .port = port }); | 100 | .port = port }); |
101 | 101 | ||
102 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, | 102 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, |
103 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 103 | IRQF_SHARED, "telnetd", conn)) { |
104 | "telnetd", conn)) { | ||
105 | printk(KERN_ERR "port_accept : failed to get IRQ for " | 104 | printk(KERN_ERR "port_accept : failed to get IRQ for " |
106 | "telnetd\n"); | 105 | "telnetd\n"); |
107 | goto out_free; | 106 | goto out_free; |
@@ -184,8 +183,7 @@ void *port_data(int port_num) | |||
184 | } | 183 | } |
185 | 184 | ||
186 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, | 185 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, |
187 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 186 | IRQF_SHARED, "port", port)) { |
188 | "port", port)) { | ||
189 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); | 187 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); |
190 | goto out_close; | 188 | goto out_close; |
191 | } | 189 | } |
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index b25296e6218a..e32c6aa6396f 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
@@ -131,8 +131,7 @@ static int __init rng_init (void) | |||
131 | random_fd = err; | 131 | random_fd = err; |
132 | 132 | ||
133 | err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, | 133 | err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, |
134 | IRQF_SAMPLE_RANDOM, "random", | 134 | 0, "random", NULL); |
135 | NULL); | ||
136 | if (err) | 135 | if (err) |
137 | goto err_out_cleanup_hw; | 136 | goto err_out_cleanup_hw; |
138 | 137 | ||
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index b68bbe269e01..e3031e69445d 100644 --- 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) | |||
50 | init_completion(&data->ready); | 50 | init_completion(&data->ready); |
51 | 51 | ||
52 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, | 52 | err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, |
53 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 53 | IRQF_SHARED, "xterm", data); |
54 | "xterm", data); | ||
55 | if (err) { | 54 | if (err) { |
56 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " | 55 | printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " |
57 | "err = %d\n", err); | 56 | "err = %d\n", err); |
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index 2a1639255763..c88211139a51 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c | |||
@@ -25,8 +25,7 @@ int write_sigio_irq(int fd) | |||
25 | int err; | 25 | int err; |
26 | 26 | ||
27 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, | 27 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, |
28 | IRQF_SAMPLE_RANDOM, "write sigio", | 28 | 0, "write sigio", NULL); |
29 | NULL); | ||
30 | if (err) { | 29 | if (err) { |
31 | printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " | 30 | printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " |
32 | "err = %d\n", err); | 31 | "err = %d\n", err); |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index e4fb3374dcd2..2c2d2e5c1597 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -888,9 +888,8 @@ static int setup_blkring(struct xenbus_device *dev, | |||
888 | if (err) | 888 | if (err) |
889 | goto fail; | 889 | goto fail; |
890 | 890 | ||
891 | err = bind_evtchn_to_irqhandler(info->evtchn, | 891 | err = bind_evtchn_to_irqhandler(info->evtchn, blkif_interrupt, 0, |
892 | blkif_interrupt, | 892 | "blkif", info); |
893 | IRQF_SAMPLE_RANDOM, "blkif", info); | ||
894 | if (err <= 0) { | 893 | if (err <= 0) { |
895 | xenbus_dev_fatal(dev, err, | 894 | xenbus_dev_fatal(dev, err, |
896 | "bind_evtchn_to_irqhandler failed"); | 895 | "bind_evtchn_to_irqhandler failed"); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 4ec04a754733..b86eae9b77df 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -125,21 +125,26 @@ | |||
125 | * The current exported interfaces for gathering environmental noise | 125 | * The current exported interfaces for gathering environmental noise |
126 | * from the devices are: | 126 | * from the devices are: |
127 | * | 127 | * |
128 | * void add_device_randomness(const void *buf, unsigned int size); | ||
128 | * void add_input_randomness(unsigned int type, unsigned int code, | 129 | * void add_input_randomness(unsigned int type, unsigned int code, |
129 | * unsigned int value); | 130 | * unsigned int value); |
130 | * void add_interrupt_randomness(int irq); | 131 | * void add_interrupt_randomness(int irq, int irq_flags); |
131 | * void add_disk_randomness(struct gendisk *disk); | 132 | * void add_disk_randomness(struct gendisk *disk); |
132 | * | 133 | * |
134 | * add_device_randomness() is for adding data to the random pool that | ||
135 | * is likely to differ between two devices (or possibly even per boot). | ||
136 | * This would be things like MAC addresses or serial numbers, or the | ||
137 | * read-out of the RTC. This does *not* add any actual entropy to the | ||
138 | * pool, but it initializes the pool to different values for devices | ||
139 | * that might otherwise be identical and have very little entropy | ||
140 | * available to them (particularly common in the embedded world). | ||
141 | * | ||
133 | * add_input_randomness() uses the input layer interrupt timing, as well as | 142 | * add_input_randomness() uses the input layer interrupt timing, as well as |
134 | * the event type information from the hardware. | 143 | * the event type information from the hardware. |
135 | * | 144 | * |
136 | * add_interrupt_randomness() uses the inter-interrupt timing as random | 145 | * add_interrupt_randomness() uses the interrupt timing as random |
137 | * inputs to the entropy pool. Note that not all interrupts are good | 146 | * inputs to the entropy pool. Using the cycle counters and the irq source |
138 | * sources of randomness! For example, the timer interrupts is not a | 147 | * as inputs, it feeds the randomness roughly once a second. |
139 | * good choice, because the periodicity of the interrupts is too | ||
140 | * regular, and hence predictable to an attacker. Network Interface | ||
141 | * Controller interrupts are a better measure, since the timing of the | ||
142 | * NIC interrupts are more unpredictable. | ||
143 | * | 148 | * |
144 | * add_disk_randomness() uses what amounts to the seek time of block | 149 | * add_disk_randomness() uses what amounts to the seek time of block |
145 | * layer request events, on a per-disk_devt basis, as input to the | 150 | * layer request events, on a per-disk_devt basis, as input to the |
@@ -248,6 +253,8 @@ | |||
248 | #include <linux/percpu.h> | 253 | #include <linux/percpu.h> |
249 | #include <linux/cryptohash.h> | 254 | #include <linux/cryptohash.h> |
250 | #include <linux/fips.h> | 255 | #include <linux/fips.h> |
256 | #include <linux/ptrace.h> | ||
257 | #include <linux/kmemcheck.h> | ||
251 | 258 | ||
252 | #ifdef CONFIG_GENERIC_HARDIRQS | 259 | #ifdef CONFIG_GENERIC_HARDIRQS |
253 | # include <linux/irq.h> | 260 | # include <linux/irq.h> |
@@ -256,8 +263,12 @@ | |||
256 | #include <asm/processor.h> | 263 | #include <asm/processor.h> |
257 | #include <asm/uaccess.h> | 264 | #include <asm/uaccess.h> |
258 | #include <asm/irq.h> | 265 | #include <asm/irq.h> |
266 | #include <asm/irq_regs.h> | ||
259 | #include <asm/io.h> | 267 | #include <asm/io.h> |
260 | 268 | ||
269 | #define CREATE_TRACE_POINTS | ||
270 | #include <trace/events/random.h> | ||
271 | |||
261 | /* | 272 | /* |
262 | * Configuration information | 273 | * Configuration information |
263 | */ | 274 | */ |
@@ -266,6 +277,8 @@ | |||
266 | #define SEC_XFER_SIZE 512 | 277 | #define SEC_XFER_SIZE 512 |
267 | #define EXTRACT_SIZE 10 | 278 | #define EXTRACT_SIZE 10 |
268 | 279 | ||
280 | #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) | ||
281 | |||
269 | /* | 282 | /* |
270 | * The minimum number of bits of entropy before we wake up a read on | 283 | * The minimum number of bits of entropy before we wake up a read on |
271 | * /dev/random. Should be enough to do a significant reseed. | 284 | * /dev/random. Should be enough to do a significant reseed. |
@@ -420,8 +433,10 @@ struct entropy_store { | |||
420 | /* read-write data: */ | 433 | /* read-write data: */ |
421 | spinlock_t lock; | 434 | spinlock_t lock; |
422 | unsigned add_ptr; | 435 | unsigned add_ptr; |
436 | unsigned input_rotate; | ||
423 | int entropy_count; | 437 | int entropy_count; |
424 | int input_rotate; | 438 | int entropy_total; |
439 | unsigned int initialized:1; | ||
425 | __u8 last_data[EXTRACT_SIZE]; | 440 | __u8 last_data[EXTRACT_SIZE]; |
426 | }; | 441 | }; |
427 | 442 | ||
@@ -454,6 +469,10 @@ static struct entropy_store nonblocking_pool = { | |||
454 | .pool = nonblocking_pool_data | 469 | .pool = nonblocking_pool_data |
455 | }; | 470 | }; |
456 | 471 | ||
472 | static __u32 const twist_table[8] = { | ||
473 | 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, | ||
474 | 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; | ||
475 | |||
457 | /* | 476 | /* |
458 | * This function adds bytes into the entropy "pool". It does not | 477 | * This function adds bytes into the entropy "pool". It does not |
459 | * update the entropy estimate. The caller should call | 478 | * update the entropy estimate. The caller should call |
@@ -464,29 +483,24 @@ static struct entropy_store nonblocking_pool = { | |||
464 | * it's cheap to do so and helps slightly in the expected case where | 483 | * it's cheap to do so and helps slightly in the expected case where |
465 | * the entropy is concentrated in the low-order bits. | 484 | * the entropy is concentrated in the low-order bits. |
466 | */ | 485 | */ |
467 | static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, | 486 | static void _mix_pool_bytes(struct entropy_store *r, const void *in, |
468 | int nbytes, __u8 out[64]) | 487 | int nbytes, __u8 out[64]) |
469 | { | 488 | { |
470 | static __u32 const twist_table[8] = { | ||
471 | 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, | ||
472 | 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; | ||
473 | unsigned long i, j, tap1, tap2, tap3, tap4, tap5; | 489 | unsigned long i, j, tap1, tap2, tap3, tap4, tap5; |
474 | int input_rotate; | 490 | int input_rotate; |
475 | int wordmask = r->poolinfo->poolwords - 1; | 491 | int wordmask = r->poolinfo->poolwords - 1; |
476 | const char *bytes = in; | 492 | const char *bytes = in; |
477 | __u32 w; | 493 | __u32 w; |
478 | unsigned long flags; | ||
479 | 494 | ||
480 | /* Taps are constant, so we can load them without holding r->lock. */ | ||
481 | tap1 = r->poolinfo->tap1; | 495 | tap1 = r->poolinfo->tap1; |
482 | tap2 = r->poolinfo->tap2; | 496 | tap2 = r->poolinfo->tap2; |
483 | tap3 = r->poolinfo->tap3; | 497 | tap3 = r->poolinfo->tap3; |
484 | tap4 = r->poolinfo->tap4; | 498 | tap4 = r->poolinfo->tap4; |
485 | tap5 = r->poolinfo->tap5; | 499 | tap5 = r->poolinfo->tap5; |
486 | 500 | ||
487 | spin_lock_irqsave(&r->lock, flags); | 501 | smp_rmb(); |
488 | input_rotate = r->input_rotate; | 502 | input_rotate = ACCESS_ONCE(r->input_rotate); |
489 | i = r->add_ptr; | 503 | i = ACCESS_ONCE(r->add_ptr); |
490 | 504 | ||
491 | /* mix one byte at a time to simplify size handling and churn faster */ | 505 | /* mix one byte at a time to simplify size handling and churn faster */ |
492 | while (nbytes--) { | 506 | while (nbytes--) { |
@@ -513,19 +527,61 @@ static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, | |||
513 | input_rotate += i ? 7 : 14; | 527 | input_rotate += i ? 7 : 14; |
514 | } | 528 | } |
515 | 529 | ||
516 | r->input_rotate = input_rotate; | 530 | ACCESS_ONCE(r->input_rotate) = input_rotate; |
517 | r->add_ptr = i; | 531 | ACCESS_ONCE(r->add_ptr) = i; |
532 | smp_wmb(); | ||
518 | 533 | ||
519 | if (out) | 534 | if (out) |
520 | for (j = 0; j < 16; j++) | 535 | for (j = 0; j < 16; j++) |
521 | ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; | 536 | ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; |
537 | } | ||
538 | |||
539 | static void __mix_pool_bytes(struct entropy_store *r, const void *in, | ||
540 | int nbytes, __u8 out[64]) | ||
541 | { | ||
542 | trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_); | ||
543 | _mix_pool_bytes(r, in, nbytes, out); | ||
544 | } | ||
545 | |||
546 | static void mix_pool_bytes(struct entropy_store *r, const void *in, | ||
547 | int nbytes, __u8 out[64]) | ||
548 | { | ||
549 | unsigned long flags; | ||
522 | 550 | ||
551 | trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); | ||
552 | spin_lock_irqsave(&r->lock, flags); | ||
553 | _mix_pool_bytes(r, in, nbytes, out); | ||
523 | spin_unlock_irqrestore(&r->lock, flags); | 554 | spin_unlock_irqrestore(&r->lock, flags); |
524 | } | 555 | } |
525 | 556 | ||
526 | static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) | 557 | struct fast_pool { |
558 | __u32 pool[4]; | ||
559 | unsigned long last; | ||
560 | unsigned short count; | ||
561 | unsigned char rotate; | ||
562 | unsigned char last_timer_intr; | ||
563 | }; | ||
564 | |||
565 | /* | ||
566 | * This is a fast mixing routine used by the interrupt randomness | ||
567 | * collector. It's hardcoded for an 128 bit pool and assumes that any | ||
568 | * locks that might be needed are taken by the caller. | ||
569 | */ | ||
570 | static void fast_mix(struct fast_pool *f, const void *in, int nbytes) | ||
527 | { | 571 | { |
528 | mix_pool_bytes_extract(r, in, bytes, NULL); | 572 | const char *bytes = in; |
573 | __u32 w; | ||
574 | unsigned i = f->count; | ||
575 | unsigned input_rotate = f->rotate; | ||
576 | |||
577 | while (nbytes--) { | ||
578 | w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^ | ||
579 | f->pool[(i + 1) & 3]; | ||
580 | f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7]; | ||
581 | input_rotate += (i++ & 3) ? 7 : 14; | ||
582 | } | ||
583 | f->count = i; | ||
584 | f->rotate = input_rotate; | ||
529 | } | 585 | } |
530 | 586 | ||
531 | /* | 587 | /* |
@@ -533,30 +589,38 @@ static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) | |||
533 | */ | 589 | */ |
534 | static void credit_entropy_bits(struct entropy_store *r, int nbits) | 590 | static void credit_entropy_bits(struct entropy_store *r, int nbits) |
535 | { | 591 | { |
536 | unsigned long flags; | 592 | int entropy_count, orig; |
537 | int entropy_count; | ||
538 | 593 | ||
539 | if (!nbits) | 594 | if (!nbits) |
540 | return; | 595 | return; |
541 | 596 | ||
542 | spin_lock_irqsave(&r->lock, flags); | ||
543 | |||
544 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); | 597 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); |
545 | entropy_count = r->entropy_count; | 598 | retry: |
599 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | ||
546 | entropy_count += nbits; | 600 | entropy_count += nbits; |
601 | |||
547 | if (entropy_count < 0) { | 602 | if (entropy_count < 0) { |
548 | DEBUG_ENT("negative entropy/overflow\n"); | 603 | DEBUG_ENT("negative entropy/overflow\n"); |
549 | entropy_count = 0; | 604 | entropy_count = 0; |
550 | } else if (entropy_count > r->poolinfo->POOLBITS) | 605 | } else if (entropy_count > r->poolinfo->POOLBITS) |
551 | entropy_count = r->poolinfo->POOLBITS; | 606 | entropy_count = r->poolinfo->POOLBITS; |
552 | r->entropy_count = entropy_count; | 607 | if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) |
608 | goto retry; | ||
609 | |||
610 | if (!r->initialized && nbits > 0) { | ||
611 | r->entropy_total += nbits; | ||
612 | if (r->entropy_total > 128) | ||
613 | r->initialized = 1; | ||
614 | } | ||
615 | |||
616 | trace_credit_entropy_bits(r->name, nbits, entropy_count, | ||
617 | r->entropy_total, _RET_IP_); | ||
553 | 618 | ||
554 | /* should we wake readers? */ | 619 | /* should we wake readers? */ |
555 | if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { | 620 | if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { |
556 | wake_up_interruptible(&random_read_wait); | 621 | wake_up_interruptible(&random_read_wait); |
557 | kill_fasync(&fasync, SIGIO, POLL_IN); | 622 | kill_fasync(&fasync, SIGIO, POLL_IN); |
558 | } | 623 | } |
559 | spin_unlock_irqrestore(&r->lock, flags); | ||
560 | } | 624 | } |
561 | 625 | ||
562 | /********************************************************************* | 626 | /********************************************************************* |
@@ -572,42 +636,24 @@ struct timer_rand_state { | |||
572 | unsigned dont_count_entropy:1; | 636 | unsigned dont_count_entropy:1; |
573 | }; | 637 | }; |
574 | 638 | ||
575 | #ifndef CONFIG_GENERIC_HARDIRQS | 639 | /* |
576 | 640 | * Add device- or boot-specific data to the input and nonblocking | |
577 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; | 641 | * pools to help initialize them to unique values. |
578 | 642 | * | |
579 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | 643 | * None of this adds any entropy, it is meant to avoid the |
580 | { | 644 | * problem of the nonblocking pool having similar initial state |
581 | return irq_timer_state[irq]; | 645 | * across largely identical devices. |
582 | } | 646 | */ |
583 | 647 | void add_device_randomness(const void *buf, unsigned int size) | |
584 | static void set_timer_rand_state(unsigned int irq, | ||
585 | struct timer_rand_state *state) | ||
586 | { | ||
587 | irq_timer_state[irq] = state; | ||
588 | } | ||
589 | |||
590 | #else | ||
591 | |||
592 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
593 | { | ||
594 | struct irq_desc *desc; | ||
595 | |||
596 | desc = irq_to_desc(irq); | ||
597 | |||
598 | return desc->timer_rand_state; | ||
599 | } | ||
600 | |||
601 | static void set_timer_rand_state(unsigned int irq, | ||
602 | struct timer_rand_state *state) | ||
603 | { | 648 | { |
604 | struct irq_desc *desc; | 649 | unsigned long time = get_cycles() ^ jiffies; |
605 | 650 | ||
606 | desc = irq_to_desc(irq); | 651 | mix_pool_bytes(&input_pool, buf, size, NULL); |
607 | 652 | mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); | |
608 | desc->timer_rand_state = state; | 653 | mix_pool_bytes(&nonblocking_pool, buf, size, NULL); |
654 | mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); | ||
609 | } | 655 | } |
610 | #endif | 656 | EXPORT_SYMBOL(add_device_randomness); |
611 | 657 | ||
612 | static struct timer_rand_state input_timer_state; | 658 | static struct timer_rand_state input_timer_state; |
613 | 659 | ||
@@ -637,13 +683,9 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
637 | goto out; | 683 | goto out; |
638 | 684 | ||
639 | sample.jiffies = jiffies; | 685 | sample.jiffies = jiffies; |
640 | 686 | sample.cycles = get_cycles(); | |
641 | /* Use arch random value, fall back to cycles */ | ||
642 | if (!arch_get_random_int(&sample.cycles)) | ||
643 | sample.cycles = get_cycles(); | ||
644 | |||
645 | sample.num = num; | 687 | sample.num = num; |
646 | mix_pool_bytes(&input_pool, &sample, sizeof(sample)); | 688 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); |
647 | 689 | ||
648 | /* | 690 | /* |
649 | * Calculate number of bits of randomness we probably added. | 691 | * Calculate number of bits of randomness we probably added. |
@@ -700,17 +742,48 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
700 | } | 742 | } |
701 | EXPORT_SYMBOL_GPL(add_input_randomness); | 743 | EXPORT_SYMBOL_GPL(add_input_randomness); |
702 | 744 | ||
703 | void add_interrupt_randomness(int irq) | 745 | static DEFINE_PER_CPU(struct fast_pool, irq_randomness); |
746 | |||
747 | void add_interrupt_randomness(int irq, int irq_flags) | ||
704 | { | 748 | { |
705 | struct timer_rand_state *state; | 749 | struct entropy_store *r; |
750 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); | ||
751 | struct pt_regs *regs = get_irq_regs(); | ||
752 | unsigned long now = jiffies; | ||
753 | __u32 input[4], cycles = get_cycles(); | ||
754 | |||
755 | input[0] = cycles ^ jiffies; | ||
756 | input[1] = irq; | ||
757 | if (regs) { | ||
758 | __u64 ip = instruction_pointer(regs); | ||
759 | input[2] = ip; | ||
760 | input[3] = ip >> 32; | ||
761 | } | ||
706 | 762 | ||
707 | state = get_timer_rand_state(irq); | 763 | fast_mix(fast_pool, input, sizeof(input)); |
708 | 764 | ||
709 | if (state == NULL) | 765 | if ((fast_pool->count & 1023) && |
766 | !time_after(now, fast_pool->last + HZ)) | ||
710 | return; | 767 | return; |
711 | 768 | ||
712 | DEBUG_ENT("irq event %d\n", irq); | 769 | fast_pool->last = now; |
713 | add_timer_randomness(state, 0x100 + irq); | 770 | |
771 | r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; | ||
772 | __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL); | ||
773 | /* | ||
774 | * If we don't have a valid cycle counter, and we see | ||
775 | * back-to-back timer interrupts, then skip giving credit for | ||
776 | * any entropy. | ||
777 | */ | ||
778 | if (cycles == 0) { | ||
779 | if (irq_flags & __IRQF_TIMER) { | ||
780 | if (fast_pool->last_timer_intr) | ||
781 | return; | ||
782 | fast_pool->last_timer_intr = 1; | ||
783 | } else | ||
784 | fast_pool->last_timer_intr = 0; | ||
785 | } | ||
786 | credit_entropy_bits(r, 1); | ||
714 | } | 787 | } |
715 | 788 | ||
716 | #ifdef CONFIG_BLOCK | 789 | #ifdef CONFIG_BLOCK |
@@ -742,7 +815,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
742 | */ | 815 | */ |
743 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | 816 | static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) |
744 | { | 817 | { |
745 | __u32 tmp[OUTPUT_POOL_WORDS]; | 818 | __u32 tmp[OUTPUT_POOL_WORDS]; |
746 | 819 | ||
747 | if (r->pull && r->entropy_count < nbytes * 8 && | 820 | if (r->pull && r->entropy_count < nbytes * 8 && |
748 | r->entropy_count < r->poolinfo->POOLBITS) { | 821 | r->entropy_count < r->poolinfo->POOLBITS) { |
@@ -761,7 +834,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
761 | 834 | ||
762 | bytes = extract_entropy(r->pull, tmp, bytes, | 835 | bytes = extract_entropy(r->pull, tmp, bytes, |
763 | random_read_wakeup_thresh / 8, rsvd); | 836 | random_read_wakeup_thresh / 8, rsvd); |
764 | mix_pool_bytes(r, tmp, bytes); | 837 | mix_pool_bytes(r, tmp, bytes, NULL); |
765 | credit_entropy_bits(r, bytes*8); | 838 | credit_entropy_bits(r, bytes*8); |
766 | } | 839 | } |
767 | } | 840 | } |
@@ -820,13 +893,19 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
820 | static void extract_buf(struct entropy_store *r, __u8 *out) | 893 | static void extract_buf(struct entropy_store *r, __u8 *out) |
821 | { | 894 | { |
822 | int i; | 895 | int i; |
823 | __u32 hash[5], workspace[SHA_WORKSPACE_WORDS]; | 896 | union { |
897 | __u32 w[5]; | ||
898 | unsigned long l[LONGS(EXTRACT_SIZE)]; | ||
899 | } hash; | ||
900 | __u32 workspace[SHA_WORKSPACE_WORDS]; | ||
824 | __u8 extract[64]; | 901 | __u8 extract[64]; |
902 | unsigned long flags; | ||
825 | 903 | ||
826 | /* Generate a hash across the pool, 16 words (512 bits) at a time */ | 904 | /* Generate a hash across the pool, 16 words (512 bits) at a time */ |
827 | sha_init(hash); | 905 | sha_init(hash.w); |
906 | spin_lock_irqsave(&r->lock, flags); | ||
828 | for (i = 0; i < r->poolinfo->poolwords; i += 16) | 907 | for (i = 0; i < r->poolinfo->poolwords; i += 16) |
829 | sha_transform(hash, (__u8 *)(r->pool + i), workspace); | 908 | sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); |
830 | 909 | ||
831 | /* | 910 | /* |
832 | * We mix the hash back into the pool to prevent backtracking | 911 | * We mix the hash back into the pool to prevent backtracking |
@@ -837,13 +916,14 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
837 | * brute-forcing the feedback as hard as brute-forcing the | 916 | * brute-forcing the feedback as hard as brute-forcing the |
838 | * hash. | 917 | * hash. |
839 | */ | 918 | */ |
840 | mix_pool_bytes_extract(r, hash, sizeof(hash), extract); | 919 | __mix_pool_bytes(r, hash.w, sizeof(hash.w), extract); |
920 | spin_unlock_irqrestore(&r->lock, flags); | ||
841 | 921 | ||
842 | /* | 922 | /* |
843 | * To avoid duplicates, we atomically extract a portion of the | 923 | * To avoid duplicates, we atomically extract a portion of the |
844 | * pool while mixing, and hash one final time. | 924 | * pool while mixing, and hash one final time. |
845 | */ | 925 | */ |
846 | sha_transform(hash, extract, workspace); | 926 | sha_transform(hash.w, extract, workspace); |
847 | memset(extract, 0, sizeof(extract)); | 927 | memset(extract, 0, sizeof(extract)); |
848 | memset(workspace, 0, sizeof(workspace)); | 928 | memset(workspace, 0, sizeof(workspace)); |
849 | 929 | ||
@@ -852,20 +932,32 @@ static void extract_buf(struct entropy_store *r, __u8 *out) | |||
852 | * pattern, we fold it in half. Thus, we always feed back | 932 | * pattern, we fold it in half. Thus, we always feed back |
853 | * twice as much data as we output. | 933 | * twice as much data as we output. |
854 | */ | 934 | */ |
855 | hash[0] ^= hash[3]; | 935 | hash.w[0] ^= hash.w[3]; |
856 | hash[1] ^= hash[4]; | 936 | hash.w[1] ^= hash.w[4]; |
857 | hash[2] ^= rol32(hash[2], 16); | 937 | hash.w[2] ^= rol32(hash.w[2], 16); |
858 | memcpy(out, hash, EXTRACT_SIZE); | 938 | |
859 | memset(hash, 0, sizeof(hash)); | 939 | /* |
940 | * If we have a architectural hardware random number | ||
941 | * generator, mix that in, too. | ||
942 | */ | ||
943 | for (i = 0; i < LONGS(EXTRACT_SIZE); i++) { | ||
944 | unsigned long v; | ||
945 | if (!arch_get_random_long(&v)) | ||
946 | break; | ||
947 | hash.l[i] ^= v; | ||
948 | } | ||
949 | |||
950 | memcpy(out, &hash, EXTRACT_SIZE); | ||
951 | memset(&hash, 0, sizeof(hash)); | ||
860 | } | 952 | } |
861 | 953 | ||
862 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, | 954 | static ssize_t extract_entropy(struct entropy_store *r, void *buf, |
863 | size_t nbytes, int min, int reserved) | 955 | size_t nbytes, int min, int reserved) |
864 | { | 956 | { |
865 | ssize_t ret = 0, i; | 957 | ssize_t ret = 0, i; |
866 | __u8 tmp[EXTRACT_SIZE]; | 958 | __u8 tmp[EXTRACT_SIZE]; |
867 | unsigned long flags; | ||
868 | 959 | ||
960 | trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); | ||
869 | xfer_secondary_pool(r, nbytes); | 961 | xfer_secondary_pool(r, nbytes); |
870 | nbytes = account(r, nbytes, min, reserved); | 962 | nbytes = account(r, nbytes, min, reserved); |
871 | 963 | ||
@@ -873,6 +965,8 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, | |||
873 | extract_buf(r, tmp); | 965 | extract_buf(r, tmp); |
874 | 966 | ||
875 | if (fips_enabled) { | 967 | if (fips_enabled) { |
968 | unsigned long flags; | ||
969 | |||
876 | spin_lock_irqsave(&r->lock, flags); | 970 | spin_lock_irqsave(&r->lock, flags); |
877 | if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) | 971 | if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) |
878 | panic("Hardware RNG duplicated output!\n"); | 972 | panic("Hardware RNG duplicated output!\n"); |
@@ -898,6 +992,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
898 | ssize_t ret = 0, i; | 992 | ssize_t ret = 0, i; |
899 | __u8 tmp[EXTRACT_SIZE]; | 993 | __u8 tmp[EXTRACT_SIZE]; |
900 | 994 | ||
995 | trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_); | ||
901 | xfer_secondary_pool(r, nbytes); | 996 | xfer_secondary_pool(r, nbytes); |
902 | nbytes = account(r, nbytes, 0, 0); | 997 | nbytes = account(r, nbytes, 0, 0); |
903 | 998 | ||
@@ -931,17 +1026,35 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, | |||
931 | 1026 | ||
932 | /* | 1027 | /* |
933 | * This function is the exported kernel interface. It returns some | 1028 | * This function is the exported kernel interface. It returns some |
934 | * number of good random numbers, suitable for seeding TCP sequence | 1029 | * number of good random numbers, suitable for key generation, seeding |
935 | * numbers, etc. | 1030 | * TCP sequence numbers, etc. It does not use the hw random number |
1031 | * generator, if available; use get_random_bytes_arch() for that. | ||
936 | */ | 1032 | */ |
937 | void get_random_bytes(void *buf, int nbytes) | 1033 | void get_random_bytes(void *buf, int nbytes) |
938 | { | 1034 | { |
1035 | extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); | ||
1036 | } | ||
1037 | EXPORT_SYMBOL(get_random_bytes); | ||
1038 | |||
1039 | /* | ||
1040 | * This function will use the architecture-specific hardware random | ||
1041 | * number generator if it is available. The arch-specific hw RNG will | ||
1042 | * almost certainly be faster than what we can do in software, but it | ||
1043 | * is impossible to verify that it is implemented securely (as | ||
1044 | * opposed, to, say, the AES encryption of a sequence number using a | ||
1045 | * key known by the NSA). So it's useful if we need the speed, but | ||
1046 | * only if we're willing to trust the hardware manufacturer not to | ||
1047 | * have put in a back door. | ||
1048 | */ | ||
1049 | void get_random_bytes_arch(void *buf, int nbytes) | ||
1050 | { | ||
939 | char *p = buf; | 1051 | char *p = buf; |
940 | 1052 | ||
1053 | trace_get_random_bytes(nbytes, _RET_IP_); | ||
941 | while (nbytes) { | 1054 | while (nbytes) { |
942 | unsigned long v; | 1055 | unsigned long v; |
943 | int chunk = min(nbytes, (int)sizeof(unsigned long)); | 1056 | int chunk = min(nbytes, (int)sizeof(unsigned long)); |
944 | 1057 | ||
945 | if (!arch_get_random_long(&v)) | 1058 | if (!arch_get_random_long(&v)) |
946 | break; | 1059 | break; |
947 | 1060 | ||
@@ -950,9 +1063,11 @@ void get_random_bytes(void *buf, int nbytes) | |||
950 | nbytes -= chunk; | 1063 | nbytes -= chunk; |
951 | } | 1064 | } |
952 | 1065 | ||
953 | extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); | 1066 | if (nbytes) |
1067 | extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); | ||
954 | } | 1068 | } |
955 | EXPORT_SYMBOL(get_random_bytes); | 1069 | EXPORT_SYMBOL(get_random_bytes_arch); |
1070 | |||
956 | 1071 | ||
957 | /* | 1072 | /* |
958 | * init_std_data - initialize pool with system data | 1073 | * init_std_data - initialize pool with system data |
@@ -966,23 +1081,30 @@ EXPORT_SYMBOL(get_random_bytes); | |||
966 | static void init_std_data(struct entropy_store *r) | 1081 | static void init_std_data(struct entropy_store *r) |
967 | { | 1082 | { |
968 | int i; | 1083 | int i; |
969 | ktime_t now; | 1084 | ktime_t now = ktime_get_real(); |
970 | unsigned long flags; | 1085 | unsigned long rv; |
971 | 1086 | ||
972 | spin_lock_irqsave(&r->lock, flags); | ||
973 | r->entropy_count = 0; | 1087 | r->entropy_count = 0; |
974 | spin_unlock_irqrestore(&r->lock, flags); | 1088 | r->entropy_total = 0; |
975 | 1089 | mix_pool_bytes(r, &now, sizeof(now), NULL); | |
976 | now = ktime_get_real(); | 1090 | for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { |
977 | mix_pool_bytes(r, &now, sizeof(now)); | 1091 | if (!arch_get_random_long(&rv)) |
978 | for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof flags) { | ||
979 | if (!arch_get_random_long(&flags)) | ||
980 | break; | 1092 | break; |
981 | mix_pool_bytes(r, &flags, sizeof(flags)); | 1093 | mix_pool_bytes(r, &rv, sizeof(rv), NULL); |
982 | } | 1094 | } |
983 | mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); | 1095 | mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); |
984 | } | 1096 | } |
985 | 1097 | ||
1098 | /* | ||
1099 | * Note that setup_arch() may call add_device_randomness() | ||
1100 | * long before we get here. This allows seeding of the pools | ||
1101 | * with some platform dependent data very early in the boot | ||
1102 | * process. But it limits our options here. We must use | ||
1103 | * statically allocated structures that already have all | ||
1104 | * initializations complete at compile time. We should also | ||
1105 | * take care not to overwrite the precious per platform data | ||
1106 | * we were given. | ||
1107 | */ | ||
986 | static int rand_initialize(void) | 1108 | static int rand_initialize(void) |
987 | { | 1109 | { |
988 | init_std_data(&input_pool); | 1110 | init_std_data(&input_pool); |
@@ -992,24 +1114,6 @@ static int rand_initialize(void) | |||
992 | } | 1114 | } |
993 | module_init(rand_initialize); | 1115 | module_init(rand_initialize); |
994 | 1116 | ||
995 | void rand_initialize_irq(int irq) | ||
996 | { | ||
997 | struct timer_rand_state *state; | ||
998 | |||
999 | state = get_timer_rand_state(irq); | ||
1000 | |||
1001 | if (state) | ||
1002 | return; | ||
1003 | |||
1004 | /* | ||
1005 | * If kzalloc returns null, we just won't use that entropy | ||
1006 | * source. | ||
1007 | */ | ||
1008 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); | ||
1009 | if (state) | ||
1010 | set_timer_rand_state(irq, state); | ||
1011 | } | ||
1012 | |||
1013 | #ifdef CONFIG_BLOCK | 1117 | #ifdef CONFIG_BLOCK |
1014 | void rand_initialize_disk(struct gendisk *disk) | 1118 | void rand_initialize_disk(struct gendisk *disk) |
1015 | { | 1119 | { |
@@ -1117,7 +1221,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) | |||
1117 | count -= bytes; | 1221 | count -= bytes; |
1118 | p += bytes; | 1222 | p += bytes; |
1119 | 1223 | ||
1120 | mix_pool_bytes(r, buf, bytes); | 1224 | mix_pool_bytes(r, buf, bytes, NULL); |
1121 | cond_resched(); | 1225 | cond_resched(); |
1122 | } | 1226 | } |
1123 | 1227 | ||
@@ -1279,6 +1383,7 @@ static int proc_do_uuid(ctl_table *table, int write, | |||
1279 | } | 1383 | } |
1280 | 1384 | ||
1281 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; | 1385 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; |
1386 | extern ctl_table random_table[]; | ||
1282 | ctl_table random_table[] = { | 1387 | ctl_table random_table[] = { |
1283 | { | 1388 | { |
1284 | .procname = "poolsize", | 1389 | .procname = "poolsize", |
@@ -1344,7 +1449,7 @@ late_initcall(random_int_secret_init); | |||
1344 | * value is not cryptographically secure but for several uses the cost of | 1449 | * value is not cryptographically secure but for several uses the cost of |
1345 | * depleting entropy is too high | 1450 | * depleting entropy is too high |
1346 | */ | 1451 | */ |
1347 | DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); | 1452 | static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); |
1348 | unsigned int get_random_int(void) | 1453 | unsigned int get_random_int(void) |
1349 | { | 1454 | { |
1350 | __u32 *hash; | 1455 | __u32 *hash; |
diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 67b97c5fd859..a8bd0310f8fe 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c | |||
@@ -1610,8 +1610,7 @@ static int spu_map_ino(struct platform_device *dev, struct spu_mdesc_info *ip, | |||
1610 | 1610 | ||
1611 | sprintf(p->irq_name, "%s-%d", irq_name, index); | 1611 | sprintf(p->irq_name, "%s-%d", irq_name, index); |
1612 | 1612 | ||
1613 | return request_irq(p->irq, handler, IRQF_SAMPLE_RANDOM, | 1613 | return request_irq(p->irq, handler, 0, p->irq_name, p); |
1614 | p->irq_name, p); | ||
1615 | } | 1614 | } |
1616 | 1615 | ||
1617 | static struct kmem_cache *queue_cache[2]; | 1616 | static struct kmem_cache *queue_cache[2]; |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 153980be4ee6..b298158cb922 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/dmi.h> | 6 | #include <linux/dmi.h> |
7 | #include <linux/efi.h> | 7 | #include <linux/efi.h> |
8 | #include <linux/bootmem.h> | 8 | #include <linux/bootmem.h> |
9 | #include <linux/random.h> | ||
9 | #include <asm/dmi.h> | 10 | #include <asm/dmi.h> |
10 | 11 | ||
11 | /* | 12 | /* |
@@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, | |||
111 | 112 | ||
112 | dmi_table(buf, dmi_len, dmi_num, decode, NULL); | 113 | dmi_table(buf, dmi_len, dmi_num, decode, NULL); |
113 | 114 | ||
115 | add_device_randomness(buf, dmi_len); | ||
116 | |||
114 | dmi_iounmap(buf, dmi_len); | 117 | dmi_iounmap(buf, dmi_len); |
115 | return 0; | 118 | return 0; |
116 | } | 119 | } |
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index a220e5746d67..4748086eaaf2 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
@@ -545,8 +545,7 @@ static int vmbus_bus_init(int irq) | |||
545 | if (ret) | 545 | if (ret) |
546 | goto err_cleanup; | 546 | goto err_cleanup; |
547 | 547 | ||
548 | ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, | 548 | ret = request_irq(irq, vmbus_isr, 0, driver_name, hv_acpi_dev); |
549 | driver_name, hv_acpi_dev); | ||
550 | 549 | ||
551 | if (ret != 0) { | 550 | if (ret != 0) { |
552 | pr_err("Unable to request IRQ %d\n", | 551 | pr_err("Unable to request IRQ %d\n", |
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 07b7447ecbc9..3d71395ae1f7 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c | |||
@@ -306,8 +306,7 @@ static int __devinit pmcmsptwi_probe(struct platform_device *pldev) | |||
306 | pmcmsptwi_data.irq = platform_get_irq(pldev, 0); | 306 | pmcmsptwi_data.irq = platform_get_irq(pldev, 0); |
307 | if (pmcmsptwi_data.irq) { | 307 | if (pmcmsptwi_data.irq) { |
308 | rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt, | 308 | rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt, |
309 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 309 | IRQF_SHARED, pldev->name, &pmcmsptwi_data); |
310 | pldev->name, &pmcmsptwi_data); | ||
311 | if (rc == 0) { | 310 | if (rc == 0) { |
312 | /* | 311 | /* |
313 | * Enable 'DONE' interrupt only. | 312 | * Enable 'DONE' interrupt only. |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 09a089996ded..d7a7e54f6465 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -878,7 +878,7 @@ static int __init hp_sdc_init(void) | |||
878 | #endif | 878 | #endif |
879 | 879 | ||
880 | errstr = "IRQ not available for"; | 880 | errstr = "IRQ not available for"; |
881 | if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, | 881 | if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED, |
882 | "HP SDC", &hp_sdc)) | 882 | "HP SDC", &hp_sdc)) |
883 | goto err1; | 883 | goto err1; |
884 | 884 | ||
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 4276aab4f196..78fca2902c8d 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -409,8 +409,6 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data) | |||
409 | u32 fatevent; | 409 | u32 fatevent; |
410 | int err; | 410 | int err; |
411 | 411 | ||
412 | add_interrupt_randomness(irq); | ||
413 | |||
414 | err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, | 412 | err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, |
415 | event_regs, 3); | 413 | event_regs, 3); |
416 | if (err) | 414 | if (err) |
@@ -936,8 +934,6 @@ static int __devinit ab3100_probe(struct i2c_client *client, | |||
936 | IRQF_ONESHOT, "ab3100-core", ab3100); | 934 | IRQF_ONESHOT, "ab3100-core", ab3100); |
937 | if (err) | 935 | if (err) |
938 | goto exit_no_irq; | 936 | goto exit_no_irq; |
939 | /* This real unpredictable IRQ is of course sampled for entropy */ | ||
940 | rand_initialize_irq(client->irq); | ||
941 | 937 | ||
942 | err = abx500_register_ops(&client->dev, &ab3100_ops); | 938 | err = abx500_register_ops(&client->dev, &ab3100_ops); |
943 | if (err) | 939 | if (err) |
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index 93d5fdf020c7..da2691f22e11 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c | |||
@@ -563,8 +563,7 @@ static int tps65010_probe(struct i2c_client *client, | |||
563 | */ | 563 | */ |
564 | if (client->irq > 0) { | 564 | if (client->irq > 0) { |
565 | status = request_irq(client->irq, tps65010_irq, | 565 | status = request_irq(client->irq, tps65010_irq, |
566 | IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, | 566 | IRQF_TRIGGER_FALLING, DRIVER_NAME, tps); |
567 | DRIVER_NAME, tps); | ||
568 | if (status < 0) { | 567 | if (status < 0) { |
569 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", | 568 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", |
570 | client->irq, status); | 569 | client->irq, status); |
diff --git a/drivers/mfd/wm831x-otp.c b/drivers/mfd/wm831x-otp.c index f742745ff354..b90f3e06b6c9 100644 --- a/drivers/mfd/wm831x-otp.c +++ b/drivers/mfd/wm831x-otp.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
21 | #include <linux/random.h> | ||
21 | 22 | ||
22 | #include <linux/mfd/wm831x/core.h> | 23 | #include <linux/mfd/wm831x/core.h> |
23 | #include <linux/mfd/wm831x/otp.h> | 24 | #include <linux/mfd/wm831x/otp.h> |
@@ -66,6 +67,7 @@ static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); | |||
66 | 67 | ||
67 | int wm831x_otp_init(struct wm831x *wm831x) | 68 | int wm831x_otp_init(struct wm831x *wm831x) |
68 | { | 69 | { |
70 | char uuid[WM831X_UNIQUE_ID_LEN]; | ||
69 | int ret; | 71 | int ret; |
70 | 72 | ||
71 | ret = device_create_file(wm831x->dev, &dev_attr_unique_id); | 73 | ret = device_create_file(wm831x->dev, &dev_attr_unique_id); |
@@ -73,6 +75,12 @@ int wm831x_otp_init(struct wm831x *wm831x) | |||
73 | dev_err(wm831x->dev, "Unique ID attribute not created: %d\n", | 75 | dev_err(wm831x->dev, "Unique ID attribute not created: %d\n", |
74 | ret); | 76 | ret); |
75 | 77 | ||
78 | ret = wm831x_unique_id_read(wm831x, uuid); | ||
79 | if (ret == 0) | ||
80 | add_device_randomness(uuid, sizeof(uuid)); | ||
81 | else | ||
82 | dev_err(wm831x->dev, "Failed to read UUID: %d\n", ret); | ||
83 | |||
76 | return ret; | 84 | return ret; |
77 | } | 85 | } |
78 | 86 | ||
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index 6a1ca735e935..7312f2651647 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c | |||
@@ -24,11 +24,7 @@ | |||
24 | 24 | ||
25 | static inline unsigned int get_irq_flags(struct resource *res) | 25 | static inline unsigned int get_irq_flags(struct resource *res) |
26 | { | 26 | { |
27 | unsigned int flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED; | 27 | return IRQF_SHARED | (res->flags & IRQF_TRIGGER_MASK); |
28 | |||
29 | flags |= res->flags & IRQF_TRIGGER_MASK; | ||
30 | |||
31 | return flags; | ||
32 | } | 28 | } |
33 | 29 | ||
34 | static struct device *dev; | 30 | static struct device *dev; |
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 59c6245e0421..ea5c6f857ca5 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/mfd/wm831x/core.h> | 24 | #include <linux/mfd/wm831x/core.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | 27 | #include <linux/random.h> | |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * R16416 (0x4020) - RTC Write Counter | 30 | * R16416 (0x4020) - RTC Write Counter |
@@ -96,6 +96,26 @@ struct wm831x_rtc { | |||
96 | unsigned int alarm_enabled:1; | 96 | unsigned int alarm_enabled:1; |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static void wm831x_rtc_add_randomness(struct wm831x *wm831x) | ||
100 | { | ||
101 | int ret; | ||
102 | u16 reg; | ||
103 | |||
104 | /* | ||
105 | * The write counter contains a pseudo-random number which is | ||
106 | * regenerated every time we set the RTC so it should be a | ||
107 | * useful per-system source of entropy. | ||
108 | */ | ||
109 | ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER); | ||
110 | if (ret >= 0) { | ||
111 | reg = ret; | ||
112 | add_device_randomness(®, sizeof(reg)); | ||
113 | } else { | ||
114 | dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n", | ||
115 | ret); | ||
116 | } | ||
117 | } | ||
118 | |||
99 | /* | 119 | /* |
100 | * Read current time and date in RTC | 120 | * Read current time and date in RTC |
101 | */ | 121 | */ |
@@ -431,6 +451,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
431 | alm_irq, ret); | 451 | alm_irq, ret); |
432 | } | 452 | } |
433 | 453 | ||
454 | wm831x_rtc_add_randomness(wm831x); | ||
455 | |||
434 | return 0; | 456 | return 0; |
435 | 457 | ||
436 | err: | 458 | err: |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 6cd414341d5e..6579ffdd8e9b 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -216,8 +216,7 @@ static int ulite_startup(struct uart_port *port) | |||
216 | { | 216 | { |
217 | int ret; | 217 | int ret; |
218 | 218 | ||
219 | ret = request_irq(port->irq, ulite_isr, | 219 | ret = request_irq(port->irq, ulite_isr, IRQF_SHARED, "uartlite", port); |
220 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port); | ||
221 | if (ret) | 220 | if (ret) |
222 | return ret; | 221 | return ret; |
223 | 222 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 821126eb8176..128a804c42f4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
28 | #include <linux/random.h> | ||
28 | 29 | ||
29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
30 | #include <asm/byteorder.h> | 31 | #include <asm/byteorder.h> |
@@ -2181,6 +2182,14 @@ int usb_new_device(struct usb_device *udev) | |||
2181 | /* Tell the world! */ | 2182 | /* Tell the world! */ |
2182 | announce_device(udev); | 2183 | announce_device(udev); |
2183 | 2184 | ||
2185 | if (udev->serial) | ||
2186 | add_device_randomness(udev->serial, strlen(udev->serial)); | ||
2187 | if (udev->product) | ||
2188 | add_device_randomness(udev->product, strlen(udev->product)); | ||
2189 | if (udev->manufacturer) | ||
2190 | add_device_randomness(udev->manufacturer, | ||
2191 | strlen(udev->manufacturer)); | ||
2192 | |||
2184 | device_enable_async_suspend(&udev->dev); | 2193 | device_enable_async_suspend(&udev->dev); |
2185 | 2194 | ||
2186 | /* | 2195 | /* |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 3d28fb976c78..9fd7886cfa9a 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1836,7 +1836,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1836 | /* init to known state, then setup irqs */ | 1836 | /* init to known state, then setup irqs */ |
1837 | udc_reset(dev); | 1837 | udc_reset(dev); |
1838 | udc_reinit (dev); | 1838 | udc_reinit (dev); |
1839 | if (request_irq(pdev->irq, goku_irq, IRQF_SHARED/*|IRQF_SAMPLE_RANDOM*/, | 1839 | if (request_irq(pdev->irq, goku_irq, IRQF_SHARED, |
1840 | driver_name, dev) != 0) { | 1840 | driver_name, dev) != 0) { |
1841 | DBG(dev, "request interrupt %d failed\n", pdev->irq); | 1841 | DBG(dev, "request interrupt %d failed\n", pdev->irq); |
1842 | retval = -EBUSY; | 1842 | retval = -EBUSY; |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 53c093b941e5..907ad3ecb341 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -2201,19 +2201,15 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2201 | 2201 | ||
2202 | #ifdef CONFIG_ARCH_LUBBOCK | 2202 | #ifdef CONFIG_ARCH_LUBBOCK |
2203 | if (machine_is_lubbock()) { | 2203 | if (machine_is_lubbock()) { |
2204 | retval = request_irq(LUBBOCK_USB_DISC_IRQ, | 2204 | retval = request_irq(LUBBOCK_USB_DISC_IRQ, lubbock_vbus_irq, |
2205 | lubbock_vbus_irq, | 2205 | 0, driver_name, dev); |
2206 | IRQF_SAMPLE_RANDOM, | ||
2207 | driver_name, dev); | ||
2208 | if (retval != 0) { | 2206 | if (retval != 0) { |
2209 | pr_err("%s: can't get irq %i, err %d\n", | 2207 | pr_err("%s: can't get irq %i, err %d\n", |
2210 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); | 2208 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); |
2211 | goto err_irq_lub; | 2209 | goto err_irq_lub; |
2212 | } | 2210 | } |
2213 | retval = request_irq(LUBBOCK_USB_IRQ, | 2211 | retval = request_irq(LUBBOCK_USB_IRQ, lubbock_vbus_irq, |
2214 | lubbock_vbus_irq, | 2212 | 0, driver_name, dev); |
2215 | IRQF_SAMPLE_RANDOM, | ||
2216 | driver_name, dev); | ||
2217 | if (retval != 0) { | 2213 | if (retval != 0) { |
2218 | pr_err("%s: can't get irq %i, err %d\n", | 2214 | pr_err("%s: can't get irq %i, err %d\n", |
2219 | driver_name, LUBBOCK_USB_IRQ, retval); | 2215 | driver_name, LUBBOCK_USB_IRQ, retval); |
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 575fc815c932..7a88667742b6 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c | |||
@@ -1576,7 +1576,6 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
1576 | isp->irq_type = IRQF_TRIGGER_FALLING; | 1576 | isp->irq_type = IRQF_TRIGGER_FALLING; |
1577 | } | 1577 | } |
1578 | 1578 | ||
1579 | isp->irq_type |= IRQF_SAMPLE_RANDOM; | ||
1580 | status = request_irq(i2c->irq, isp1301_irq, | 1579 | status = request_irq(i2c->irq, isp1301_irq, |
1581 | isp->irq_type, DRIVER_NAME, isp); | 1580 | isp->irq_type, DRIVER_NAME, isp); |
1582 | if (status < 0) { | 1581 | if (status < 0) { |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index e68a8e53bb59..c5f856a040b9 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -42,7 +42,6 @@ | |||
42 | * | 42 | * |
43 | * IRQF_DISABLED - keep irqs disabled when calling the action handler. | 43 | * IRQF_DISABLED - keep irqs disabled when calling the action handler. |
44 | * DEPRECATED. This flag is a NOOP and scheduled to be removed | 44 | * DEPRECATED. This flag is a NOOP and scheduled to be removed |
45 | * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator | ||
46 | * IRQF_SHARED - allow sharing the irq among several devices | 45 | * IRQF_SHARED - allow sharing the irq among several devices |
47 | * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur | 46 | * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur |
48 | * IRQF_TIMER - Flag to mark this interrupt as timer interrupt | 47 | * IRQF_TIMER - Flag to mark this interrupt as timer interrupt |
@@ -61,7 +60,6 @@ | |||
61 | * resume time. | 60 | * resume time. |
62 | */ | 61 | */ |
63 | #define IRQF_DISABLED 0x00000020 | 62 | #define IRQF_DISABLED 0x00000020 |
64 | #define IRQF_SAMPLE_RANDOM 0x00000040 | ||
65 | #define IRQF_SHARED 0x00000080 | 63 | #define IRQF_SHARED 0x00000080 |
66 | #define IRQF_PROBE_SHARED 0x00000100 | 64 | #define IRQF_PROBE_SHARED 0x00000100 |
67 | #define __IRQF_TIMER 0x00000200 | 65 | #define __IRQF_TIMER 0x00000200 |
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index f1e2527006bd..9a323d12de1c 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h | |||
@@ -39,7 +39,6 @@ struct module; | |||
39 | */ | 39 | */ |
40 | struct irq_desc { | 40 | struct irq_desc { |
41 | struct irq_data irq_data; | 41 | struct irq_data irq_data; |
42 | struct timer_rand_state *timer_rand_state; | ||
43 | unsigned int __percpu *kstat_irqs; | 42 | unsigned int __percpu *kstat_irqs; |
44 | irq_flow_handler_t handle_irq; | 43 | irq_flow_handler_t handle_irq; |
45 | #ifdef CONFIG_IRQ_PREFLOW_FASTEOI | 44 | #ifdef CONFIG_IRQ_PREFLOW_FASTEOI |
diff --git a/include/linux/random.h b/include/linux/random.h index 8f74538c96db..ac621ce886ca 100644 --- a/include/linux/random.h +++ b/include/linux/random.h | |||
@@ -48,13 +48,13 @@ struct rnd_state { | |||
48 | 48 | ||
49 | #ifdef __KERNEL__ | 49 | #ifdef __KERNEL__ |
50 | 50 | ||
51 | extern void rand_initialize_irq(int irq); | 51 | extern void add_device_randomness(const void *, unsigned int); |
52 | |||
53 | extern void add_input_randomness(unsigned int type, unsigned int code, | 52 | extern void add_input_randomness(unsigned int type, unsigned int code, |
54 | unsigned int value); | 53 | unsigned int value); |
55 | extern void add_interrupt_randomness(int irq); | 54 | extern void add_interrupt_randomness(int irq, int irq_flags); |
56 | 55 | ||
57 | extern void get_random_bytes(void *buf, int nbytes); | 56 | extern void get_random_bytes(void *buf, int nbytes); |
57 | extern void get_random_bytes_arch(void *buf, int nbytes); | ||
58 | void generate_random_uuid(unsigned char uuid_out[16]); | 58 | void generate_random_uuid(unsigned char uuid_out[16]); |
59 | 59 | ||
60 | #ifndef MODULE | 60 | #ifndef MODULE |
diff --git a/include/trace/events/random.h b/include/trace/events/random.h new file mode 100644 index 000000000000..422df19de732 --- /dev/null +++ b/include/trace/events/random.h | |||
@@ -0,0 +1,134 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM random | ||
3 | |||
4 | #if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_RANDOM_H | ||
6 | |||
7 | #include <linux/writeback.h> | ||
8 | #include <linux/tracepoint.h> | ||
9 | |||
10 | DECLARE_EVENT_CLASS(random__mix_pool_bytes, | ||
11 | TP_PROTO(const char *pool_name, int bytes, unsigned long IP), | ||
12 | |||
13 | TP_ARGS(pool_name, bytes, IP), | ||
14 | |||
15 | TP_STRUCT__entry( | ||
16 | __field( const char *, pool_name ) | ||
17 | __field( int, bytes ) | ||
18 | __field(unsigned long, IP ) | ||
19 | ), | ||
20 | |||
21 | TP_fast_assign( | ||
22 | __entry->pool_name = pool_name; | ||
23 | __entry->bytes = bytes; | ||
24 | __entry->IP = IP; | ||
25 | ), | ||
26 | |||
27 | TP_printk("%s pool: bytes %d caller %pF", | ||
28 | __entry->pool_name, __entry->bytes, (void *)__entry->IP) | ||
29 | ); | ||
30 | |||
31 | DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes, | ||
32 | TP_PROTO(const char *pool_name, int bytes, unsigned long IP), | ||
33 | |||
34 | TP_ARGS(pool_name, bytes, IP) | ||
35 | ); | ||
36 | |||
37 | DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock, | ||
38 | TP_PROTO(const char *pool_name, int bytes, unsigned long IP), | ||
39 | |||
40 | TP_ARGS(pool_name, bytes, IP) | ||
41 | ); | ||
42 | |||
43 | TRACE_EVENT(credit_entropy_bits, | ||
44 | TP_PROTO(const char *pool_name, int bits, int entropy_count, | ||
45 | int entropy_total, unsigned long IP), | ||
46 | |||
47 | TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP), | ||
48 | |||
49 | TP_STRUCT__entry( | ||
50 | __field( const char *, pool_name ) | ||
51 | __field( int, bits ) | ||
52 | __field( int, entropy_count ) | ||
53 | __field( int, entropy_total ) | ||
54 | __field(unsigned long, IP ) | ||
55 | ), | ||
56 | |||
57 | TP_fast_assign( | ||
58 | __entry->pool_name = pool_name; | ||
59 | __entry->bits = bits; | ||
60 | __entry->entropy_count = entropy_count; | ||
61 | __entry->entropy_total = entropy_total; | ||
62 | __entry->IP = IP; | ||
63 | ), | ||
64 | |||
65 | TP_printk("%s pool: bits %d entropy_count %d entropy_total %d " | ||
66 | "caller %pF", __entry->pool_name, __entry->bits, | ||
67 | __entry->entropy_count, __entry->entropy_total, | ||
68 | (void *)__entry->IP) | ||
69 | ); | ||
70 | |||
71 | TRACE_EVENT(get_random_bytes, | ||
72 | TP_PROTO(int nbytes, unsigned long IP), | ||
73 | |||
74 | TP_ARGS(nbytes, IP), | ||
75 | |||
76 | TP_STRUCT__entry( | ||
77 | __field( int, nbytes ) | ||
78 | __field(unsigned long, IP ) | ||
79 | ), | ||
80 | |||
81 | TP_fast_assign( | ||
82 | __entry->nbytes = nbytes; | ||
83 | __entry->IP = IP; | ||
84 | ), | ||
85 | |||
86 | TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP) | ||
87 | ); | ||
88 | |||
89 | DECLARE_EVENT_CLASS(random__extract_entropy, | ||
90 | TP_PROTO(const char *pool_name, int nbytes, int entropy_count, | ||
91 | unsigned long IP), | ||
92 | |||
93 | TP_ARGS(pool_name, nbytes, entropy_count, IP), | ||
94 | |||
95 | TP_STRUCT__entry( | ||
96 | __field( const char *, pool_name ) | ||
97 | __field( int, nbytes ) | ||
98 | __field( int, entropy_count ) | ||
99 | __field(unsigned long, IP ) | ||
100 | ), | ||
101 | |||
102 | TP_fast_assign( | ||
103 | __entry->pool_name = pool_name; | ||
104 | __entry->nbytes = nbytes; | ||
105 | __entry->entropy_count = entropy_count; | ||
106 | __entry->IP = IP; | ||
107 | ), | ||
108 | |||
109 | TP_printk("%s pool: nbytes %d entropy_count %d caller %pF", | ||
110 | __entry->pool_name, __entry->nbytes, __entry->entropy_count, | ||
111 | (void *)__entry->IP) | ||
112 | ); | ||
113 | |||
114 | |||
115 | DEFINE_EVENT(random__extract_entropy, extract_entropy, | ||
116 | TP_PROTO(const char *pool_name, int nbytes, int entropy_count, | ||
117 | unsigned long IP), | ||
118 | |||
119 | TP_ARGS(pool_name, nbytes, entropy_count, IP) | ||
120 | ); | ||
121 | |||
122 | DEFINE_EVENT(random__extract_entropy, extract_entropy_user, | ||
123 | TP_PROTO(const char *pool_name, int nbytes, int entropy_count, | ||
124 | unsigned long IP), | ||
125 | |||
126 | TP_ARGS(pool_name, nbytes, entropy_count, IP) | ||
127 | ); | ||
128 | |||
129 | |||
130 | |||
131 | #endif /* _TRACE_RANDOM_H */ | ||
132 | |||
133 | /* This part must be outside protection */ | ||
134 | #include <trace/define_trace.h> | ||
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index bdb180325551..131ca176b497 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -133,7 +133,7 @@ irqreturn_t | |||
133 | handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) | 133 | handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) |
134 | { | 134 | { |
135 | irqreturn_t retval = IRQ_NONE; | 135 | irqreturn_t retval = IRQ_NONE; |
136 | unsigned int random = 0, irq = desc->irq_data.irq; | 136 | unsigned int flags = 0, irq = desc->irq_data.irq; |
137 | 137 | ||
138 | do { | 138 | do { |
139 | irqreturn_t res; | 139 | irqreturn_t res; |
@@ -161,7 +161,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) | |||
161 | 161 | ||
162 | /* Fall through to add to randomness */ | 162 | /* Fall through to add to randomness */ |
163 | case IRQ_HANDLED: | 163 | case IRQ_HANDLED: |
164 | random |= action->flags; | 164 | flags |= action->flags; |
165 | break; | 165 | break; |
166 | 166 | ||
167 | default: | 167 | default: |
@@ -172,8 +172,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) | |||
172 | action = action->next; | 172 | action = action->next; |
173 | } while (action); | 173 | } while (action); |
174 | 174 | ||
175 | if (random & IRQF_SAMPLE_RANDOM) | 175 | add_interrupt_randomness(irq, flags); |
176 | add_interrupt_randomness(irq); | ||
177 | 176 | ||
178 | if (!noirqdebug) | 177 | if (!noirqdebug) |
179 | note_interrupt(irq, desc, retval); | 178 | note_interrupt(irq, desc, retval); |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 814c9ef6bba1..0a8e8f059627 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -893,22 +893,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
893 | return -ENOSYS; | 893 | return -ENOSYS; |
894 | if (!try_module_get(desc->owner)) | 894 | if (!try_module_get(desc->owner)) |
895 | return -ENODEV; | 895 | return -ENODEV; |
896 | /* | ||
897 | * Some drivers like serial.c use request_irq() heavily, | ||
898 | * so we have to be careful not to interfere with a | ||
899 | * running system. | ||
900 | */ | ||
901 | if (new->flags & IRQF_SAMPLE_RANDOM) { | ||
902 | /* | ||
903 | * This function might sleep, we want to call it first, | ||
904 | * outside of the atomic block. | ||
905 | * Yes, this might clear the entropy pool if the wrong | ||
906 | * driver is attempted to be loaded, without actually | ||
907 | * installing a new handler, but is this really a problem, | ||
908 | * only the sysadmin is able to do this. | ||
909 | */ | ||
910 | rand_initialize_irq(irq); | ||
911 | } | ||
912 | 896 | ||
913 | /* | 897 | /* |
914 | * Check whether the interrupt nests into another interrupt | 898 | * Check whether the interrupt nests into another interrupt |
@@ -1354,7 +1338,6 @@ EXPORT_SYMBOL(free_irq); | |||
1354 | * Flags: | 1338 | * Flags: |
1355 | * | 1339 | * |
1356 | * IRQF_SHARED Interrupt is shared | 1340 | * IRQF_SHARED Interrupt is shared |
1357 | * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy | ||
1358 | * IRQF_TRIGGER_* Specify active edge(s) or level | 1341 | * IRQF_TRIGGER_* Specify active edge(s) or level |
1359 | * | 1342 | * |
1360 | */ | 1343 | */ |
diff --git a/net/core/dev.c b/net/core/dev.c index 0ebaea16632f..c8569f826b71 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1172,6 +1172,7 @@ static int __dev_open(struct net_device *dev) | |||
1172 | net_dmaengine_get(); | 1172 | net_dmaengine_get(); |
1173 | dev_set_rx_mode(dev); | 1173 | dev_set_rx_mode(dev); |
1174 | dev_activate(dev); | 1174 | dev_activate(dev); |
1175 | add_device_randomness(dev->dev_addr, dev->addr_len); | ||
1175 | } | 1176 | } |
1176 | 1177 | ||
1177 | return ret; | 1178 | return ret; |
@@ -4801,6 +4802,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | |||
4801 | err = ops->ndo_set_mac_address(dev, sa); | 4802 | err = ops->ndo_set_mac_address(dev, sa); |
4802 | if (!err) | 4803 | if (!err) |
4803 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 4804 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
4805 | add_device_randomness(dev->dev_addr, dev->addr_len); | ||
4804 | return err; | 4806 | return err; |
4805 | } | 4807 | } |
4806 | EXPORT_SYMBOL(dev_set_mac_address); | 4808 | EXPORT_SYMBOL(dev_set_mac_address); |
@@ -5579,6 +5581,7 @@ int register_netdevice(struct net_device *dev) | |||
5579 | dev_init_scheduler(dev); | 5581 | dev_init_scheduler(dev); |
5580 | dev_hold(dev); | 5582 | dev_hold(dev); |
5581 | list_netdevice(dev); | 5583 | list_netdevice(dev); |
5584 | add_device_randomness(dev->dev_addr, dev->addr_len); | ||
5582 | 5585 | ||
5583 | /* Notify protocols, that a new device appeared. */ | 5586 | /* Notify protocols, that a new device appeared. */ |
5584 | ret = call_netdevice_notifiers(NETDEV_REGISTER, dev); | 5587 | ret = call_netdevice_notifiers(NETDEV_REGISTER, dev); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 5ff949dc954f..2c5a0a06c4ce 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1381,6 +1381,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1381 | goto errout; | 1381 | goto errout; |
1382 | send_addr_notify = 1; | 1382 | send_addr_notify = 1; |
1383 | modified = 1; | 1383 | modified = 1; |
1384 | add_device_randomness(dev->dev_addr, dev->addr_len); | ||
1384 | } | 1385 | } |
1385 | 1386 | ||
1386 | if (tb[IFLA_MTU]) { | 1387 | if (tb[IFLA_MTU]) { |