Commit 3e9a9708 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random

Pull random subsystem patches from Ted Ts'o:
 "This patch series contains a major revamp of how we collect entropy
  from interrupts for /dev/random and /dev/urandom.

  The goal is to addresses weaknesses discussed in the paper "Mining
  your Ps and Qs: Detection of Widespread Weak Keys in Network Devices",
  by Nadia Heninger, Zakir Durumeric, Eric Wustrow, J.  Alex Halderman,
  which will be published in the Proceedings of the 21st Usenix Security
  Symposium, August 2012.  (See https://factorable.net for more
  information and an extended version of the paper.)"

Fix up trivial conflicts due to nearby changes in
drivers/{mfd/ab3100-core.c, usb/gadget/omap_udc.c}

* tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random: (33 commits)
  random: mix in architectural randomness in extract_buf()
  dmi: Feed DMI table to /dev/random driver
  random: Add comment to random_initialize()
  random: final removal of IRQF_SAMPLE_RANDOM
  um: remove IRQF_SAMPLE_RANDOM which is now a no-op
  sparc/ldc: remove IRQF_SAMPLE_RANDOM which is now a no-op
  [ARM] pxa: remove IRQF_SAMPLE_RANDOM which is now a no-op
  board-palmz71: remove IRQF_SAMPLE_RANDOM which is now a no-op
  isp1301_omap: remove IRQF_SAMPLE_RANDOM which is now a no-op
  pxa25x_udc: remove IRQF_SAMPLE_RANDOM which is now a no-op
  omap_udc: remove IRQF_SAMPLE_RANDOM which is now a no-op
  goku_udc: remove IRQF_SAMPLE_RANDOM which was commented out
  uartlite: remove IRQF_SAMPLE_RANDOM which is now a no-op
  drivers: hv: remove IRQF_SAMPLE_RANDOM which is now a no-op
  xen-blkfront: remove IRQF_SAMPLE_RANDOM which is now a no-op
  n2_crypto: remove IRQF_SAMPLE_RANDOM which is now a no-op
  pda_power: remove IRQF_SAMPLE_RANDOM which is now a no-op
  i2c-pmcmsp: remove IRQF_SAMPLE_RANDOM which is now a no-op
  input/serio/hp_sdc.c: remove IRQF_SAMPLE_RANDOM which is now a no-op
  mfd: remove IRQF_SAMPLE_RANDOM which is now a no-op
  ...
parents 941c8726 d2e7c96a
...@@ -70,20 +70,6 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com> ...@@ -70,20 +70,6 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com>
--------------------------- ---------------------------
What: IRQF_SAMPLE_RANDOM
Check: IRQF_SAMPLE_RANDOM
When: July 2009
Why: Many of IRQF_SAMPLE_RANDOM users are technically bogus as entropy
sources in the kernel's current entropy model. To resolve this, every
input point to the kernel's entropy pool needs to better document the
type of entropy source it actually is. This will be replaced with
additional add_*_randomness functions in drivers/char/random.c
Who: Robin Getz <rgetz@blackfin.uclinux.org> & Matt Mackall <mpm@selenic.com>
---------------------------
What: The ieee80211_regdom module parameter What: The ieee80211_regdom module parameter
When: March 2010 / desktop catchup When: March 2010 / desktop catchup
......
...@@ -5682,7 +5682,7 @@ F: Documentation/blockdev/ramdisk.txt ...@@ -5682,7 +5682,7 @@ F: Documentation/blockdev/ramdisk.txt
F: drivers/block/brd.c F: drivers/block/brd.c
RANDOM NUMBER DRIVER RANDOM NUMBER DRIVER
M: Matt Mackall <mpm@selenic.com> M: Theodore Ts'o" <tytso@mit.edu>
S: Maintained S: Maintained
F: drivers/char/random.c F: drivers/char/random.c
......
...@@ -288,8 +288,7 @@ palmz71_gpio_setup(int early) ...@@ -288,8 +288,7 @@ palmz71_gpio_setup(int early)
} }
gpio_direction_input(PALMZ71_USBDETECT_GPIO); gpio_direction_input(PALMZ71_USBDETECT_GPIO);
if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO), if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
palmz71_powercable, IRQF_SAMPLE_RANDOM, palmz71_powercable, 0, "palmz71-cable", NULL))
"palmz71-cable", NULL))
printk(KERN_ERR printk(KERN_ERR
"IRQ request for power cable failed!\n"); "IRQ request for power cable failed!\n");
palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL); palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL);
......
...@@ -456,7 +456,7 @@ static int lubbock_mci_init(struct device *dev, ...@@ -456,7 +456,7 @@ static int lubbock_mci_init(struct device *dev,
init_timer(&mmc_timer); init_timer(&mmc_timer);
mmc_timer.data = (unsigned long) data; mmc_timer.data = (unsigned long) data;
return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int, 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) static int lubbock_mci_get_ro(struct device *dev)
......
...@@ -633,9 +633,8 @@ static struct platform_device bq24022 = { ...@@ -633,9 +633,8 @@ static struct platform_device bq24022 = {
static int magician_mci_init(struct device *dev, static int magician_mci_init(struct device *dev,
irq_handler_t detect_irq, void *data) irq_handler_t detect_irq, void *data)
{ {
return request_irq(IRQ_MAGICIAN_SD, detect_irq, return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED,
IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "mmc card detect", data);
"mmc card detect", data);
} }
static void magician_mci_exit(struct device *dev, void *data) static void magician_mci_exit(struct device *dev, void *data)
......
...@@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, ...@@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int,
int err; int err;
err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM, IRQF_DISABLED | IRQF_TRIGGER_RISING,
"MMC card detect", data); "MMC card detect", data);
if (err) { if (err) {
printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request" printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request"
"MMC card detect IRQ\n"); "MMC card detect IRQ\n");
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/random.h> /* for rand_initialize_irq() */
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/threads.h> #include <linux/threads.h>
......
...@@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name) ...@@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
err = request_irq(lp->cfg.rx_irq, ldc_rx, err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED,
IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
lp->rx_irq_name, lp); lp->rx_irq_name, lp);
if (err) if (err)
return err; return err;
err = request_irq(lp->cfg.tx_irq, ldc_tx, err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED,
IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
lp->tx_irq_name, lp); lp->tx_irq_name, lp);
if (err) { if (err) {
free_irq(lp->cfg.rx_irq, lp); free_irq(lp->cfg.rx_irq, lp);
......
...@@ -362,18 +362,18 @@ static irqreturn_t line_write_interrupt(int irq, void *data) ...@@ -362,18 +362,18 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
int line_setup_irq(int fd, int input, int output, struct line *line, void *data) int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
{ {
const struct line_driver *driver = line->driver; const struct line_driver *driver = line->driver;
int err = 0, flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM; int err = 0;
if (input) if (input)
err = um_request_irq(driver->read_irq, fd, IRQ_READ, err = um_request_irq(driver->read_irq, fd, IRQ_READ,
line_interrupt, flags, line_interrupt, IRQF_SHARED,
driver->read_irq_name, data); driver->read_irq_name, data);
if (err) if (err)
return err; return err;
if (output) if (output)
err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
line_write_interrupt, flags, line_write_interrupt, IRQF_SHARED,
driver->write_irq_name, data); driver->write_irq_name, data);
return err; return err;
} }
...@@ -779,8 +779,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, ...@@ -779,8 +779,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
.stack = stack }); .stack = stack });
if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, IRQF_SHARED, "winch", winch) < 0) {
"winch", winch) < 0) {
printk(KERN_ERR "register_winch_irq - failed to register " printk(KERN_ERR "register_winch_irq - failed to register "
"IRQ\n"); "IRQ\n");
goto out_free; goto out_free;
......
...@@ -774,8 +774,7 @@ static int __init mconsole_init(void) ...@@ -774,8 +774,7 @@ static int __init mconsole_init(void)
register_reboot_notifier(&reboot_notifier); register_reboot_notifier(&reboot_notifier);
err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, IRQF_SHARED, "mconsole", (void *)sock);
"mconsole", (void *)sock);
if (err) { if (err) {
printk(KERN_ERR "Failed to get IRQ for management console\n"); printk(KERN_ERR "Failed to get IRQ for management console\n");
goto out; goto out;
......
...@@ -100,8 +100,7 @@ static int port_accept(struct port_list *port) ...@@ -100,8 +100,7 @@ static int port_accept(struct port_list *port)
.port = port }); .port = port });
if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, IRQF_SHARED, "telnetd", conn)) {
"telnetd", conn)) {
printk(KERN_ERR "port_accept : failed to get IRQ for " printk(KERN_ERR "port_accept : failed to get IRQ for "
"telnetd\n"); "telnetd\n");
goto out_free; goto out_free;
...@@ -184,8 +183,7 @@ void *port_data(int port_num) ...@@ -184,8 +183,7 @@ void *port_data(int port_num)
} }
if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, IRQF_SHARED, "port", port)) {
"port", port)) {
printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
goto out_close; goto out_close;
} }
......
...@@ -131,8 +131,7 @@ static int __init rng_init (void) ...@@ -131,8 +131,7 @@ static int __init rng_init (void)
random_fd = err; random_fd = err;
err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
IRQF_SAMPLE_RANDOM, "random", 0, "random", NULL);
NULL);
if (err) if (err)
goto err_out_cleanup_hw; goto err_out_cleanup_hw;
......
...@@ -50,8 +50,7 @@ int xterm_fd(int socket, int *pid_out) ...@@ -50,8 +50,7 @@ int xterm_fd(int socket, int *pid_out)
init_completion(&data->ready); init_completion(&data->ready);
err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, IRQF_SHARED, "xterm", data);
"xterm", data);
if (err) { if (err) {
printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
"err = %d\n", err); "err = %d\n", err);
......
...@@ -25,8 +25,7 @@ int write_sigio_irq(int fd) ...@@ -25,8 +25,7 @@ int write_sigio_irq(int fd)
int err; int err;
err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
IRQF_SAMPLE_RANDOM, "write sigio", 0, "write sigio", NULL);
NULL);
if (err) { if (err) {
printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " printk(KERN_ERR "write_sigio_irq : um_request_irq failed, "
"err = %d\n", err); "err = %d\n", err);
......
...@@ -888,9 +888,8 @@ static int setup_blkring(struct xenbus_device *dev, ...@@ -888,9 +888,8 @@ static int setup_blkring(struct xenbus_device *dev,
if (err) if (err)
goto fail; goto fail;
err = bind_evtchn_to_irqhandler(info->evtchn, err = bind_evtchn_to_irqhandler(info->evtchn, blkif_interrupt, 0,
blkif_interrupt, "blkif", info);
IRQF_SAMPLE_RANDOM, "blkif", info);
if (err <= 0) { if (err <= 0) {
xenbus_dev_fatal(dev, err, xenbus_dev_fatal(dev, err,
"bind_evtchn_to_irqhandler failed"); "bind_evtchn_to_irqhandler failed");
......
This diff is collapsed.
...@@ -1610,8 +1610,7 @@ static int spu_map_ino(struct platform_device *dev, struct spu_mdesc_info *ip, ...@@ -1610,8 +1610,7 @@ static int spu_map_ino(struct platform_device *dev, struct spu_mdesc_info *ip,
sprintf(p->irq_name, "%s-%d", irq_name, index); sprintf(p->irq_name, "%s-%d", irq_name, index);
return request_irq(p->irq, handler, IRQF_SAMPLE_RANDOM, return request_irq(p->irq, handler, 0, p->irq_name, p);
p->irq_name, p);
} }
static struct kmem_cache *queue_cache[2]; static struct kmem_cache *queue_cache[2];
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/random.h>
#include <asm/dmi.h> #include <asm/dmi.h>
/* /*
...@@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, ...@@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
dmi_table(buf, dmi_len, dmi_num, decode, NULL); dmi_table(buf, dmi_len, dmi_num, decode, NULL);
add_device_randomness(buf, dmi_len);
dmi_iounmap(buf, dmi_len); dmi_iounmap(buf, dmi_len);
return 0; return 0;
} }
......
...@@ -545,8 +545,7 @@ static int vmbus_bus_init(int irq) ...@@ -545,8 +545,7 @@ static int vmbus_bus_init(int irq)
if (ret) if (ret)
goto err_cleanup; goto err_cleanup;
ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, ret = request_irq(irq, vmbus_isr, 0, driver_name, hv_acpi_dev);
driver_name, hv_acpi_dev);
if (ret != 0) { if (ret != 0) {
pr_err("Unable to request IRQ %d\n", pr_err("Unable to request IRQ %d\n",
......
...@@ -306,8 +306,7 @@ static int __devinit pmcmsptwi_probe(struct platform_device *pldev) ...@@ -306,8 +306,7 @@ static int __devinit pmcmsptwi_probe(struct platform_device *pldev)
pmcmsptwi_data.irq = platform_get_irq(pldev, 0); pmcmsptwi_data.irq = platform_get_irq(pldev, 0);
if (pmcmsptwi_data.irq) { if (pmcmsptwi_data.irq) {
rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt, rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, IRQF_SHARED, pldev->name, &pmcmsptwi_data);
pldev->name, &pmcmsptwi_data);
if (rc == 0) { if (rc == 0) {
/* /*
* Enable 'DONE' interrupt only. * Enable 'DONE' interrupt only.
......
...@@ -878,7 +878,7 @@ static int __init hp_sdc_init(void) ...@@ -878,7 +878,7 @@ static int __init hp_sdc_init(void)
#endif #endif
errstr = "IRQ not available for"; 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)) "HP SDC", &hp_sdc))
goto err1; goto err1;
......
...@@ -409,8 +409,6 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data) ...@@ -409,8 +409,6 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data)
u32 fatevent; u32 fatevent;
int err; int err;
add_interrupt_randomness(irq);
err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
event_regs, 3); event_regs, 3);
if (err) if (err)
...@@ -936,8 +934,6 @@ static int __devinit ab3100_probe(struct i2c_client *client, ...@@ -936,8 +934,6 @@ static int __devinit ab3100_probe(struct i2c_client *client,
IRQF_ONESHOT, "ab3100-core", ab3100); IRQF_ONESHOT, "ab3100-core", ab3100);
if (err) if (err)
goto exit_no_irq; goto exit_no_irq;
/* This real unpredictable IRQ is of course sampled for entropy */
rand_initialize_irq(client->irq);
err = abx500_register_ops(&client->dev, &ab3100_ops); err = abx500_register_ops(&client->dev, &ab3100_ops);
if (err) if (err)
......
...@@ -563,8 +563,7 @@ static int tps65010_probe(struct i2c_client *client, ...@@ -563,8 +563,7 @@ static int tps65010_probe(struct i2c_client *client,
*/ */
if (client->irq > 0) { if (client->irq > 0) {
status = request_irq(client->irq, tps65010_irq, status = request_irq(client->irq, tps65010_irq,
IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, IRQF_TRIGGER_FALLING, DRIVER_NAME, tps);
DRIVER_NAME, tps);
if (status < 0) { if (status < 0) {
dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
client->irq, status); client->irq, status);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/random.h>
#include <linux/mfd/wm831x/core.h> #include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/otp.h> #include <linux/mfd/wm831x/otp.h>
...@@ -66,6 +67,7 @@ static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); ...@@ -66,6 +67,7 @@ static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL);
int wm831x_otp_init(struct wm831x *wm831x) int wm831x_otp_init(struct wm831x *wm831x)
{ {
char uuid[WM831X_UNIQUE_ID_LEN];
int ret; int ret;
ret = device_create_file(wm831x->dev, &dev_attr_unique_id); ret = device_create_file(wm831x->dev, &dev_attr_unique_id);
...@@ -73,6 +75,12 @@ int wm831x_otp_init(struct wm831x *wm831x) ...@@ -73,6 +75,12 @@ int wm831x_otp_init(struct wm831x *wm831x)
dev_err(wm831x->dev, "Unique ID attribute not created: %d\n", dev_err(wm831x->dev, "Unique ID attribute not created: %d\n",
ret); ret);
ret = wm831x_unique_id_read(wm831x, uuid);
if (ret == 0)
add_device_randomness(uuid, sizeof(uuid));
else
dev_err(wm831x->dev, "Failed to read UUID: %d\n", ret);
return ret; return ret;
} }
......
...@@ -24,11 +24,7 @@ ...@@ -24,11 +24,7 @@
static inline unsigned int get_irq_flags(struct resource *res) static inline unsigned int get_irq_flags(struct resource *res)
{ {
unsigned int flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED; return IRQF_SHARED | (res->flags & IRQF_TRIGGER_MASK);
flags |= res->flags & IRQF_TRIGGER_MASK;
return flags;
} }
static struct device *dev; static struct device *dev;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/mfd/wm831x/core.h> #include <linux/mfd/wm831x/core.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/random.h>
/* /*
* R16416 (0x4020) - RTC Write Counter * R16416 (0x4020) - RTC Write Counter
...@@ -96,6 +96,26 @@ struct wm831x_rtc { ...@@ -96,6 +96,26 @@ struct wm831x_rtc {
unsigned int alarm_enabled:1; unsigned int alarm_enabled:1;
}; };
static void wm831x_rtc_add_randomness(struct wm831x *wm831x)
{
int ret;
u16 reg;
/*
* The write counter contains a pseudo-random number which is
* regenerated every time we set the RTC so it should be a
* useful per-system source of entropy.
*/
ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER);
if (ret >= 0) {
reg = ret;
add_device_randomness(&reg, sizeof(reg));
} else {
dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n",
ret);
}
}
/* /*
* Read current time and date in RTC * Read current time and date in RTC
*/ */
...@@ -431,6 +451,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev) ...@@ -431,6 +451,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
alm_irq, ret); alm_irq, ret);
} }
wm831x_rtc_add_randomness(wm831x);
return 0; return 0;
err: err:
......
...@@ -216,8 +216,7 @@ static int ulite_startup(struct uart_port *port) ...@@ -216,8 +216,7 @@ static int ulite_startup(struct uart_port *port)
{ {
int ret; int ret;
ret = request_irq(port->irq, ulite_isr, ret = request_irq(port->irq, ulite_isr, IRQF_SHARED, "uartlite", port);
IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port);
if (ret) if (ret)
return ret; return ret;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/random.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -2181,6 +2182,14 @@ int usb_new_device(struct usb_device *udev) ...@@ -2181,6 +2182,14 @@ int usb_new_device(struct usb_device *udev)
/* Tell the world! */ /* Tell the world! */
announce_device(udev); 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); device_enable_async_suspend(&udev->dev);
/* /*
......
...@@ -1836,7 +1836,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1836,7 +1836,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* init to known state, then setup irqs */ /* init to known state, then setup irqs */
udc_reset(dev); udc_reset(dev);
udc_reinit (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) { driver_name, dev) != 0) {
DBG(dev, "request interrupt %d failed\n", pdev->irq); DBG(dev, "request interrupt %d failed\n", pdev->irq);
retval = -EBUSY; retval = -EBUSY;
......
...@@ -2201,19 +2201,15 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ...@@ -2201,19 +2201,15 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
#ifdef CONFIG_ARCH_LUBBOCK #ifdef CONFIG_ARCH_LUBBOCK
if (machine_is_lubbock()) { if (machine_is_lubbock()) {
retval = request_irq(LUBBOCK_USB_DISC_IRQ, retval = request_irq(LUBBOCK_USB_DISC_IRQ, lubbock_vbus_irq,
lubbock_vbus_irq, 0, driver_name, dev);
IRQF_SAMPLE_RANDOM,
driver_name, dev);
if (retval != 0) { if (retval != 0) {
pr_err("%s: can't get irq %i, err %d\n", pr_err("%s: can't get irq %i, err %d\n",
driver_name, LUBBOCK_USB_DISC_IRQ, retval); driver_name, LUBBOCK_USB_DISC_IRQ, retval);
goto err_irq_lub; goto err_irq_lub;
} }
retval = request_irq(LUBBOCK_USB_IRQ, retval = request_irq(LUBBOCK_USB_IRQ, lubbock_vbus_irq,
lubbock_vbus_irq, 0, driver_name, dev);
IRQF_SAMPLE_RANDOM,
driver_name, dev);
if (retval != 0) { if (retval != 0) {
pr_err("%s: can't get irq %i, err %d\n", pr_err("%s: can't get irq %i, err %d\n",
driver_name, LUBBOCK_USB_IRQ, retval); driver_name, LUBBOCK_USB_IRQ, retval);
......
...@@ -1576,7 +1576,6 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) ...@@ -1576,7 +1576,6 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
isp->irq_type = IRQF_TRIGGER_FALLING; isp->irq_type = IRQF_TRIGGER_FALLING;
} }
isp->irq_type |= IRQF_SAMPLE_RANDOM;
status = request_irq(i2c->irq, isp1301_irq, status = request_irq(i2c->irq, isp1301_irq,
isp->irq_type, DRIVER_NAME, isp); isp->irq_type, DRIVER_NAME, isp);
if (status < 0) { if (status < 0) {
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
* *
* IRQF_DISABLED - keep irqs disabled when calling the action handler. * IRQF_DISABLED - keep irqs disabled when calling the action handler.
* DEPRECATED. This flag is a NOOP and scheduled to be removed * 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_SHARED - allow sharing the irq among several devices
* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
* IRQF_TIMER - Flag to mark this interrupt as timer interrupt * IRQF_TIMER - Flag to mark this interrupt as timer interrupt
...@@ -61,7 +60,6 @@ ...@@ -61,7 +60,6 @@
* resume time. * resume time.
*/ */
#define IRQF_DISABLED 0x00000020 #define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
#define IRQF_SHARED 0x00000080 #define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100 #define IRQF_PROBE_SHARED 0x00000100
#define __IRQF_TIMER 0x00000200 #define __IRQF_TIMER 0x00000200
......
...@@ -39,7 +39,6 @@ struct module; ...@@ -39,7 +39,6 @@ struct module;
*/ */
struct irq_desc { struct irq_desc {
struct irq_data irq_data; struct irq_data irq_data;
struct timer_rand_state *timer_rand_state;
unsigned int __percpu *kstat_irqs; unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq; irq_flow_handler_t handle_irq;
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI #ifdef CONFIG_IRQ_PREFLOW_FASTEOI
......
...@@ -48,13 +48,13 @@ struct rnd_state { ...@@ -48,13 +48,13 @@ struct rnd_state {
#ifdef __KERNEL__ #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, extern void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value); 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(void *buf, int nbytes);
extern void get_random_bytes_arch(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]); void generate_random_uuid(unsigned char uuid_out[16]);
#ifndef MODULE #ifndef MODULE
......
#undef TRACE_SYSTEM
#define TRACE_SYSTEM random
#if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_RANDOM_H
#include <linux/writeback.h>
#include <linux/tracepoint.h>
DECLARE_EVENT_CLASS(random__mix_pool_bytes,
TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
TP_ARGS(pool_name, bytes, IP),
TP_STRUCT__entry(
__field( const char *, pool_name )
__field( int, bytes )
__field(unsigned long, IP )
),
TP_fast_assign(
__entry->pool_name = pool_name;
__entry->bytes = bytes;
__entry->IP = IP;
),
TP_printk("%s pool: bytes %d caller %pF",
__entry->pool_name, __entry->bytes, (void *)__entry->IP)
);
DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes,
TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
TP_ARGS(pool_name, bytes, IP)
);
DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
TP_ARGS(pool_name, bytes, IP)
);
TRACE_EVENT(credit_entropy_bits,
TP_PROTO(const char *pool_name, int bits, int entropy_count,
int entropy_total, unsigned long IP),
TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP),
TP_STRUCT__entry(
__field( const char *, pool_name )
__field( int, bits )
__field( int, entropy_count )
__field( int, entropy_total )
__field(unsigned long, IP )
),
TP_fast_assign(
__entry->pool_name = pool_name;
__entry->bits = bits;
__entry->entropy_count = entropy_count;
__entry->entropy_total = entropy_total;
__entry->IP = IP;
),
TP_printk("%s pool: bits %d entropy_count %d entropy_total %d "
"caller %pF", __entry->pool_name, __entry->bits,
__entry->entropy_count, __entry->entropy_total,
(void *)__entry->IP)
);
TRACE_EVENT(get_random_bytes,
TP_PROTO(int nbytes, unsigned long IP),
TP_ARGS(nbytes, IP),
TP_STRUCT__entry(
__field( int, nbytes )
__field(unsigned long, IP )
),
TP_fast_assign(
__entry->nbytes = nbytes;
__entry->IP = IP;
),
TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP)
);
DECLARE_EVENT_CLASS(random__extract_entropy,
TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
unsigned long IP),
TP_ARGS(pool_name, nbytes, entropy_count, IP),
TP_STRUCT__entry(
__field( const char *, pool_name )
__field( int, nbytes )
__field( int, entropy_count )
__field(unsigned long, IP )
),
TP_fast_assign(
__entry->pool_name = pool_name;
__entry->nbytes = nbytes;
__entry->entropy_count = entropy_count;
__entry->IP = IP;
),
TP_printk("%s pool: nbytes %d entropy_count %d caller %pF",
__entry->pool_name, __entry->nbytes, __entry->entropy_count,
(void *)__entry->IP)
);
DEFINE_EVENT(random__extract_entropy, extract_entropy,
TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
unsigned long IP),
TP_ARGS(pool_name, nbytes, entropy_count, IP)
);
DEFINE_EVENT(random__extract_entropy, extract_entropy_user,
TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
unsigned long IP),
TP_ARGS(pool_name, nbytes, entropy_count, IP)
);
#endif /* _TRACE_RANDOM_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
...@@ -133,7 +133,7 @@ irqreturn_t ...@@ -133,7 +133,7 @@ irqreturn_t
handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
{ {
irqreturn_t retval = IRQ_NONE; irqreturn_t retval = IRQ_NONE;
unsigned int random = 0, irq = desc->irq_data.irq; unsigned int flags = 0, irq = desc->irq_data.irq;
do { do {
irqreturn_t res; irqreturn_t res;
...@@ -161,7 +161,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) ...@@ -161,7 +161,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
/* Fall through to add to randomness */ /* Fall through to add to randomness */
case IRQ_HANDLED: case IRQ_HANDLED:
random |= action->flags; flags |= action->flags;
break; break;
default: default:
...@@ -172,8 +172,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) ...@@ -172,8 +172,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
action = action->next; action = action->next;
} while (action); } while (action);
if (random & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq, flags);
add_interrupt_randomness(irq);
if (!noirqdebug) if (!noirqdebug)
note_interrupt(irq, desc, retval); note_interrupt(irq, desc, retval);
......
...@@ -893,22 +893,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) ...@@ -893,22 +893,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
return -ENOSYS; return -ENOSYS;
if (!try_module_get(desc->owner)) if (!try_module_get(desc->owner))
return -ENODEV; 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 * Check whether the interrupt nests into another interrupt
...@@ -1354,7 +1338,6 @@ EXPORT_SYMBOL(free_irq); ...@@ -1354,7 +1338,6 @@ EXPORT_SYMBOL(free_irq);
* Flags: * Flags:
* *
* IRQF_SHARED Interrupt is shared * IRQF_SHARED Interrupt is shared
* IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
* IRQF_TRIGGER_* Specify active edge(s) or level * IRQF_TRIGGER_* Specify active edge(s) or level
* *
*/ */
......
...@@ -1172,6 +1172,7 @@ static int __dev_open(struct net_device *dev) ...@@ -1172,6 +1172,7 @@ static int __dev_open(struct net_device *dev)
net_dmaengine_get(); net_dmaengine_get();
dev_set_rx_mode(dev); dev_set_rx_mode(dev);
dev_activate(dev); dev_activate(dev);
add_device_randomness(dev->dev_addr, dev->addr_len);
} }
return ret; return ret;
...@@ -4801,6 +4802,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) ...@@ -4801,6 +4802,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
err = ops->ndo_set_mac_address(dev, sa); err = ops->ndo_set_mac_address(dev, sa);
if (!err) if (!err)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
add_device_randomness(dev->dev_addr, dev->addr_len);
return err; return err;
} }
EXPORT_SYMBOL(dev_set_mac_address); EXPORT_SYMBOL(dev_set_mac_address);
...@@ -5579,6 +5581,7 @@ int register_netdevice(struct net_device *dev) ...@@ -5579,6 +5581,7 @@ int register_netdevice(struct net_device *dev)
dev_init_scheduler(dev); dev_init_scheduler(dev);
dev_hold(dev); dev_hold(dev);
list_netdevice(dev); list_netdevice(dev);
add_device_randomness(dev->dev_addr, dev->addr_len);
/* Notify protocols, that a new device appeared. */ /* Notify protocols, that a new device appeared. */
ret = call_netdevice_notifiers(NETDEV_REGISTER, dev); ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);
......
...@@ -1381,6 +1381,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, ...@@ -1381,6 +1381,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
goto errout; goto errout;
send_addr_notify = 1; send_addr_notify = 1;
modified = 1; modified = 1;
add_device_randomness(dev->dev_addr, dev->addr_len);
} }
if (tb[IFLA_MTU]) { if (tb[IFLA_MTU]) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment