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>