lkml.org 
[lkml]   [2011]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    SubjectRe: [PATCH 1/2] random: Add support for architectural random hooks
    So here is my counter-suggestion

    NOTE NOTE NOTE! This is completely and utterly untested. I didn't
    actually check how big the "rdrand" and "setc" instructions are, so
    the ASM_NOP4 there is just a random "I guess two 'xor' instructions
    are four bytes shorter than the rdrand/setc instructions are".

    So please don't take this as a serious patch that should be applied,
    but instead take it as a serious alternative *approach*.

    Note that with the default inline function in <asm-generic/random.h>
    is designed so that architectures that use it (this patch does *not*
    contain the architecture glue to enable it) will compile the loop in
    random.c entirely away. No test, no nothing.

    Comments?

    (Btw, even on x86, assuming the concept works and the ASM_NOP4 is
    corrected to the right length, we'd need to support older assemblers
    that don't understand the "rdrand" instruction, so it would need to be
    done as a explicit byte sequence).

    Again, TOTALLY UNTESTED. Concept patch only!! There may be seriously
    stupid bugs here, but the point is that it should make it easy for an
    architecture to have a "get a word of random data quickly".

    Linus
    commit 218603412aad073a04ea815858b98f6c33ab30d2
    Author: Linus Torvalds <torvalds@linux-foundation.org>
    Date: Sat Jul 30 15:06:16 2011 -1000

    EXAMPLE 'RDRAND' PATCH

    NOT FOR REAL CONSUMPTION!
    ---
    arch/x86/include/asm/random.h | 23 +++++++++++++++++++++++
    drivers/char/random.c | 15 +++++++++++++++
    include/asm-generic/random.h | 13 +++++++++++++
    3 files changed, 51 insertions(+), 0 deletions(-)

    diff --git a/arch/x86/include/asm/random.h b/arch/x86/include/asm/random.h
    new file mode 100644
    index 000000000000..f6fbd3340608
    --- /dev/null
    +++ b/arch/x86/include/asm/random.h
    @@ -0,0 +1,23 @@
    +#ifndef _X86_RANDOM_H
    +#define _X86_RANDOM_H
    +
    +#include <asm/alternative.h>
    +
    +static inline int arch_get_random_word(unsigned long *word)
    +{
    + int ret;
    +
    + alternative_io("xor %0,%0; xor %1,%1" ASM_NOP4,
    + "rdrand %1; setcc %0",
    + X86_FEATURE_PERFCTR_CORE,
    + ASM_OUTPUT2("=a" (ret), "=d" (*word)),
    + "i" (0) /* fake input */);
    + /*
    + * We return 0 if CF is clear of if the CPU
    + * doesn't support RDRAND, otherwise we return
    + * 8 (for 8 bytes of data).
    + */
    + return ret & 8;
    +}
    +
    +#endif
    diff --git a/drivers/char/random.c b/drivers/char/random.c
    index 729281961f22..e335ec96bf88 100644
    --- a/drivers/char/random.c
    +++ b/drivers/char/random.c
    @@ -257,6 +257,7 @@
    #include <asm/uaccess.h>
    #include <asm/irq.h>
    #include <asm/io.h>
    +#include <asm/random.h>

    /*
    * Configuration information
    @@ -865,6 +866,20 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
    xfer_secondary_pool(r, nbytes);
    nbytes = account(r, nbytes, min, reserved);

    + /* Use fast CPU random words if available */
    + while (nbytes) {
    + unsigned long word;
    + int bytes = arch_get_random_word(&word);
    + if (!bytes)
    + break;
    + if (bytes > nbytes)
    + bytes = nbytes;
    + memcpy(buf, &word, bytes);
    + nbytes -= bytes;
    + buf += bytes;
    + ret += bytes;
    + }
    +
    while (nbytes) {
    extract_buf(r, tmp);

    diff --git a/include/asm-generic/random.h b/include/asm-generic/random.h
    new file mode 100644
    index 000000000000..e9be12ba86fa
    --- /dev/null
    +++ b/include/asm-generic/random.h
    @@ -0,0 +1,13 @@
    +#ifndef _ASM_RANDOM_H
    +#define _ASM_RANDOM_H
    +
    +/*
    + * Architecture random data in low bytes of "word", return how
    + * many bytes were filled in. Default implementation: none.
    + */
    +static inline int arch_get_random_word(unsigned long *word)
    +{
    + return 0;
    +}
    +
    +#endif
    \
     
     \ /
      Last update: 2011-07-31 03:17    [W:0.025 / U:0.936 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site