Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Oct 2013 07:57:59 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r256670 - head/sys/dev/random
Message-ID:  <201310170757.r9H7vxBM023145@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Oct 17 07:57:58 2013
New Revision: 256670
URL: http://svnweb.freebsd.org/changeset/base/256670

Log:
  Utilize the stronger guarantees on the call arguments from the
  harvester, which now always calls hwrngs with the buffer length
  multiple of the word size.  This allows to remove the excessive memory
  accesses to temporary buffer when saving the entropy word.
  
  Streamline the assembly and unify it between i386 and amd64.
  
  Reviewed by:	markm, des
  Approved by:	so (des)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/dev/random/ivy.c

Modified: head/sys/dev/random/ivy.c
==============================================================================
--- head/sys/dev/random/ivy.c	Thu Oct 17 07:40:21 2013	(r256669)
+++ head/sys/dev/random/ivy.c	Thu Oct 17 07:57:58 2013	(r256670)
@@ -1,8 +1,12 @@
 /*-
+ * Copyright (c) 2013 The FreeBSD Foundation
  * Copyright (c) 2013 David E. O'Brien <obrien@NUXI.org>
  * Copyright (c) 2012 Konstantin Belousov <kib@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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310170757.r9H7vxBM023145>