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]) { |
