svn commit: r257491 - stable/10/sys/dev/random
Konstantin Belousov
kib at FreeBSD.org
Fri Nov 1 06:26:38 UTC 2013
Author: kib
Date: Fri Nov 1 06:26:37 2013
New Revision: 257491
URL: http://svnweb.freebsd.org/changeset/base/257491
Log:
MFC r256670:
Rewrite RDRAND support:
Remove the excessive memory accesses to temporary buffer.
Streamline the assembly and unify it between i386 and amd64.
Approved by: re (glebius)
Modified:
stable/10/sys/dev/random/ivy.c
Directory Properties:
stable/10/sys/ (props changed)
Modified: stable/10/sys/dev/random/ivy.c
==============================================================================
--- stable/10/sys/dev/random/ivy.c Fri Nov 1 05:03:47 2013 (r257490)
+++ stable/10/sys/dev/random/ivy.c Fri Nov 1 06:26:37 2013 (r257491)
@@ -1,8 +1,12 @@
/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
* Copyright (c) 2013 David E. O'Brien <obrien at NUXI.org>
* Copyright (c) 2012 Konstantin Belousov <kib at FreeBSD.org>
* All rights reserved.
*
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -58,26 +62,25 @@ static struct random_hardware_source ran
};
static inline int
-ivy_rng_store(uint64_t *tmp)
+ivy_rng_store(long *buf)
{
#ifdef __GNUCLIKE_ASM
- uint32_t count;
+ long tmp;
+ int retry;
+ retry = RETRY_COUNT;
__asm __volatile(
-#ifdef __amd64__
- "rdrand\t%%rax\n\t"
- "jnc\t1f\n\t"
- "movq\t%%rax,%1\n\t"
- "movl\t$8,%%eax\n"
-#else /* i386 */
- "rdrand\t%%eax\n\t"
- "jnc\t1f\n\t"
- "movl\t%%eax,%1\n\t"
- "movl\t$4,%%eax\n"
-#endif
- "1:\n" /* %eax is cleared by processor on failure */
- : "=a" (count), "=g" (*tmp) : "a" (0) : "cc");
- return (count);
+ "1:\n\t"
+ "rdrand %2\n\t" /* read randomness into tmp */
+ "jb 2f\n\t" /* CF is set on success, exit retry loop */
+ "dec %0\n\t" /* otherwise, retry-- */
+ "jne 1b\n\t" /* and loop if retries are not exhausted */
+ "jmp 3f\n" /* failure, retry is 0, used as return value */
+ "2:\n\t"
+ "mov %2,%1\n\t" /* *buf = tmp */
+ "3:"
+ : "+q" (retry), "=m" (*buf), "=q" (tmp) : : "cc");
+ return (retry);
#else /* __GNUCLIKE_ASM */
return (0);
#endif
@@ -86,23 +89,13 @@ ivy_rng_store(uint64_t *tmp)
static int
random_ivy_read(void *buf, int c)
{
- uint8_t *b;
- int count, ret, retry;
- uint64_t tmp;
-
- b = buf;
- for (count = c; count > 0; count -= ret) {
- for (retry = 0; retry < RETRY_COUNT; retry++) {
- ret = ivy_rng_store(&tmp);
- if (ret != 0)
- break;
- }
- if (ret == 0)
+ long *b;
+ int count;
+
+ KASSERT(c % sizeof(long) == 0, ("partial read %d", c));
+ for (b = buf, count = c; count > 0; count -= sizeof(long), b++) {
+ if (ivy_rng_store(b) == 0)
break;
- if (ret > count)
- ret = count;
- memcpy(b, &tmp, ret);
- b += ret;
}
return (c - count);
}
More information about the svn-src-all
mailing list