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    [from the cache]
©2003-2011 Jasper Spaans