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