Skip to content

Commit 142a27f

Browse files
prasannatsmherbertx
authored andcommitted
hwrng: core - Reset user selected rng by writing "" to rng_current
User is able to select a chosen rng by writing its name to rng_current but there is no way to reset it without unbinding the rng. Let user write "" to rng_current and delesect the chosen rng. Signed-off-by: PrasannaKumar Muralidharan <[email protected]> reviewed-by: Harald Freudenberger <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent c2afad6 commit 142a27f

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

drivers/char/hw_random/core.c

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -292,26 +292,48 @@ static struct miscdevice rng_miscdev = {
292292
.groups = rng_dev_groups,
293293
};
294294

295+
static int enable_best_rng(void)
296+
{
297+
int ret = -ENODEV;
298+
299+
BUG_ON(!mutex_is_locked(&rng_mutex));
300+
301+
/* rng_list is sorted by quality, use the best (=first) one */
302+
if (!list_empty(&rng_list)) {
303+
struct hwrng *new_rng;
304+
305+
new_rng = list_entry(rng_list.next, struct hwrng, list);
306+
ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
307+
if (!ret)
308+
cur_rng_set_by_user = 0;
309+
}
310+
311+
return ret;
312+
}
313+
295314
static ssize_t hwrng_attr_current_store(struct device *dev,
296315
struct device_attribute *attr,
297316
const char *buf, size_t len)
298317
{
299-
int err;
318+
int err = -ENODEV;
300319
struct hwrng *rng;
301320

302321
err = mutex_lock_interruptible(&rng_mutex);
303322
if (err)
304323
return -ERESTARTSYS;
305-
err = -ENODEV;
306-
list_for_each_entry(rng, &rng_list, list) {
307-
if (sysfs_streq(rng->name, buf)) {
308-
err = 0;
309-
cur_rng_set_by_user = 1;
310-
if (rng != current_rng)
324+
325+
if (sysfs_streq(buf, "")) {
326+
err = enable_best_rng();
327+
} else {
328+
list_for_each_entry(rng, &rng_list, list) {
329+
if (sysfs_streq(rng->name, buf)) {
330+
cur_rng_set_by_user = 1;
311331
err = set_current_rng(rng);
312-
break;
332+
break;
333+
}
313334
}
314335
}
336+
315337
mutex_unlock(&rng_mutex);
316338

317339
return err ? : len;
@@ -493,17 +515,8 @@ void hwrng_unregister(struct hwrng *rng)
493515
mutex_lock(&rng_mutex);
494516

495517
list_del(&rng->list);
496-
if (current_rng == rng) {
497-
drop_current_rng();
498-
cur_rng_set_by_user = 0;
499-
/* rng_list is sorted by quality, use the best (=first) one */
500-
if (!list_empty(&rng_list)) {
501-
struct hwrng *new_rng;
502-
503-
new_rng = list_entry(rng_list.next, struct hwrng, list);
504-
set_current_rng(new_rng);
505-
}
506-
}
518+
if (current_rng == rng)
519+
enable_best_rng();
507520

508521
if (list_empty(&rng_list)) {
509522
mutex_unlock(&rng_mutex);

0 commit comments

Comments
 (0)