diff options
| author | Ingo Molnar <[email protected]> | 2014-07-28 10:03:00 +0200 | 
|---|---|---|
| committer | Ingo Molnar <[email protected]> | 2014-07-28 10:03:00 +0200 | 
| commit | ca5bc6cd5de5b53eb8fd6fea39aa3fe2a1e8c3d9 (patch) | |
| tree | 75beaae2d4b6bc654eb28994dd5906d8dcf5ef46 /drivers/char/hw_random/core.c | |
| parent | c1221321b7c25b53204447cff9949a6d5a7ddddc (diff) | |
| parent | d8d28c8f00e84a72e8bee39a85835635417bee49 (diff) | |
Merge branch 'sched/urgent' into sched/core, to merge fixes before applying new changes
Signed-off-by: Ingo Molnar <[email protected]>
Diffstat (limited to 'drivers/char/hw_random/core.c')
| -rw-r--r-- | drivers/char/hw_random/core.c | 47 | 
1 files changed, 39 insertions, 8 deletions
| diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 334601cc81cf..c4419ea1ab07 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -55,16 +55,41 @@ static DEFINE_MUTEX(rng_mutex);  static int data_avail;  static u8 *rng_buffer; +static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size, +			       int wait); +  static size_t rng_buffer_size(void)  {  	return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;  } +static void add_early_randomness(struct hwrng *rng) +{ +	unsigned char bytes[16]; +	int bytes_read; + +	/* +	 * Currently only virtio-rng cannot return data during device +	 * probe, and that's handled in virtio-rng.c itself.  If there +	 * are more such devices, this call to rng_get_data can be +	 * made conditional here instead of doing it per-device. +	 */ +	bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1); +	if (bytes_read > 0) +		add_device_randomness(bytes, bytes_read); +} +  static inline int hwrng_init(struct hwrng *rng)  { -	if (!rng->init) -		return 0; -	return rng->init(rng); +	if (rng->init) { +		int ret; + +		ret =  rng->init(rng); +		if (ret) +			return ret; +	} +	add_early_randomness(rng); +	return 0;  }  static inline void hwrng_cleanup(struct hwrng *rng) @@ -304,8 +329,6 @@ int hwrng_register(struct hwrng *rng)  {  	int err = -EINVAL;  	struct hwrng *old_rng, *tmp; -	unsigned char bytes[16]; -	int bytes_read;  	if (rng->name == NULL ||  	    (rng->data_read == NULL && rng->read == NULL)) @@ -347,9 +370,17 @@ int hwrng_register(struct hwrng *rng)  	INIT_LIST_HEAD(&rng->list);  	list_add_tail(&rng->list, &rng_list); -	bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1); -	if (bytes_read > 0) -		add_device_randomness(bytes, bytes_read); +	if (old_rng && !rng->init) { +		/* +		 * Use a new device's input to add some randomness to +		 * the system.  If this rng device isn't going to be +		 * used right away, its init function hasn't been +		 * called yet; so only use the randomness from devices +		 * that don't need an init callback. +		 */ +		add_early_randomness(rng); +	} +  out_unlock:  	mutex_unlock(&rng_mutex);  out: |