lkml.org 
[lkml]   [2022]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 150/264] hwrng: use rng source with best quality
    Date
    From: Harald Freudenberger <freude@linux.vnet.ibm.com>

    commit 2bbb6983887fefc8026beab01198d30f47b7bd22 upstream.

    This patch rewoks the hwrng to always use the
    rng source with best entropy quality.

    On registation and unregistration the hwrng now
    tries to choose the best (= highest quality value)
    rng source. The handling of the internal list
    of registered rng sources is now always sorted
    by quality and the top most rng chosen.

    Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
    Reviewed-by: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/char/hw_random/core.c | 25 +++++++++++++++++++------
    1 file changed, 19 insertions(+), 6 deletions(-)

    --- a/drivers/char/hw_random/core.c
    +++ b/drivers/char/hw_random/core.c
    @@ -28,6 +28,7 @@

    static struct hwrng *current_rng;
    static struct task_struct *hwrng_fill;
    +/* list of registered rngs, sorted decending by quality */
    static LIST_HEAD(rng_list);
    /* Protects rng_list and current_rng */
    static DEFINE_MUTEX(rng_mutex);
    @@ -416,6 +417,7 @@ int hwrng_register(struct hwrng *rng)
    {
    int err = -EINVAL;
    struct hwrng *old_rng, *tmp;
    + struct list_head *rng_list_ptr;

    if (!rng->name || (!rng->data_read && !rng->read))
    goto out;
    @@ -431,14 +433,25 @@ int hwrng_register(struct hwrng *rng)
    init_completion(&rng->cleanup_done);
    complete(&rng->cleanup_done);

    + /* rng_list is sorted by decreasing quality */
    + list_for_each(rng_list_ptr, &rng_list) {
    + tmp = list_entry(rng_list_ptr, struct hwrng, list);
    + if (tmp->quality < rng->quality)
    + break;
    + }
    + list_add_tail(&rng->list, rng_list_ptr);
    +
    old_rng = current_rng;
    err = 0;
    - if (!old_rng) {
    + if (!old_rng || (rng->quality > old_rng->quality)) {
    + /*
    + * Set new rng as current as the new rng source
    + * provides better entropy quality.
    + */
    err = set_current_rng(rng);
    if (err)
    goto out_unlock;
    }
    - list_add_tail(&rng->list, &rng_list);

    if (old_rng && !rng->init) {
    /*
    @@ -465,12 +478,12 @@ void hwrng_unregister(struct hwrng *rng)
    list_del(&rng->list);
    if (current_rng == rng) {
    drop_current_rng();
    + /* rng_list is sorted by quality, use the best (=first) one */
    if (!list_empty(&rng_list)) {
    - struct hwrng *tail;
    -
    - tail = list_entry(rng_list.prev, struct hwrng, list);
    + struct hwrng *new_rng;

    - set_current_rng(tail);
    + new_rng = list_entry(rng_list.next, struct hwrng, list);
    + set_current_rng(new_rng);
    }
    }


    \
     
     \ /
      Last update: 2022-06-23 18:59    [W:2.678 / U:0.716 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site