diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2012-09-05 13:18:51 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2012-09-05 13:18:51 +0000 |
| commit | ef9461ba0e07fe9e0858bc624001342c17f2918c (patch) | |
| tree | 4e5e06d435f26a7ff60ca89f3247cc53bec9401b /sys/dev/random | |
| parent | f379b823bc963a6e1c98128fcd65569576134ca4 (diff) | |
Notes
Diffstat (limited to 'sys/dev/random')
| -rw-r--r-- | sys/dev/random/ivy.c | 117 | ||||
| -rw-r--r-- | sys/dev/random/nehemiah.c | 6 | ||||
| -rw-r--r-- | sys/dev/random/nehemiah.h | 29 | ||||
| -rw-r--r-- | sys/dev/random/probe.c | 36 |
4 files changed, 156 insertions, 32 deletions
diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c new file mode 100644 index 000000000000..3f9de2d29cfa --- /dev/null +++ b/sys/dev/random/ivy.c @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_cpu.h" + +#ifdef IVY_RNG + +#include <sys/param.h> +#include <sys/time.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/selinfo.h> +#include <sys/systm.h> +#include <dev/random/randomdev.h> + +#define RETRY_COUNT 10 + +static void random_ivy_init(void); +static void random_ivy_deinit(void); +static int random_ivy_read(void *, int); + +struct random_systat random_ivy = { + .ident = "Hardware, Intel IvyBridge+ RNG", + .init = random_ivy_init, + .deinit = random_ivy_deinit, + .read = random_ivy_read, + .write = (random_write_func_t *)random_null_func, + .reseed = (random_reseed_func_t *)random_null_func, + .seeded = 1, +}; + +static inline int +ivy_rng_store(long *tmp) +{ +#ifdef __GNUCLIKE_ASM + uint32_t count; + + __asm __volatile( +#ifdef __amd64__ + ".byte\t0x48,0x0f,0xc7,0xf0\n\t" /* rdrand %rax */ + "jnc\t1f\n\t" + "movq\t%%rax,%1\n\t" + "movl\t$8,%%eax\n" +#else /* i386 */ + ".byte\t0x0f,0xc7,0xf0\n\t" /* rdrand %eax */ + "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); +#else /* __GNUCLIKE_ASM */ + return (0); +#endif +} + +static void +random_ivy_init(void) +{ +} + +void +random_ivy_deinit(void) +{ +} + +static int +random_ivy_read(void *buf, int c) +{ + char *b; + long tmp; + int count, res, retry; + + for (count = c, b = buf; count > 0; count -= res, b += res) { + for (retry = 0; retry < RETRY_COUNT; retry++) { + res = ivy_rng_store(&tmp); + if (res != 0) + break; + } + if (res == 0) + break; + if (res > count) + res = count; + memcpy(b, &tmp, res); + } + return (c - count); +} + +#endif diff --git a/sys/dev/random/nehemiah.c b/sys/dev/random/nehemiah.c index b9f52e783417..f3afa89fcf89 100644 --- a/sys/dev/random/nehemiah.c +++ b/sys/dev/random/nehemiah.c @@ -28,6 +28,10 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_cpu.h" + +#ifdef PADLOCK_RNG + #include <sys/param.h> #include <sys/time.h> #include <sys/lock.h> @@ -203,3 +207,5 @@ random_nehemiah_read(void *buf, int c) mtx_unlock(&random_nehemiah_mtx); return (c); } + +#endif diff --git a/sys/dev/random/nehemiah.h b/sys/dev/random/nehemiah.h deleted file mode 100644 index b35fb3fb2262..000000000000 --- a/sys/dev/random/nehemiah.h +++ /dev/null @@ -1,29 +0,0 @@ -/*- - * Copyright (c) 2000-2004 Mark R V Murray - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -extern struct random_systat random_nehemiah; diff --git a/sys/dev/random/probe.c b/sys/dev/random/probe.c index 0bbfd95c68d8..3edfe09d1e87 100644 --- a/sys/dev/random/probe.c +++ b/sys/dev/random/probe.c @@ -28,12 +28,17 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#if defined(__amd64__) || (defined(__i386__) && !defined(PC98)) +#include "opt_cpu.h" +#endif + #include <sys/types.h> #include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> #include <sys/malloc.h> #include <sys/random.h> #include <sys/selinfo.h> -#include <sys/stdint.h> #include <sys/sysctl.h> #if defined(__amd64__) || (defined(__i386__) && !defined(PC98)) @@ -45,7 +50,15 @@ __FBSDID("$FreeBSD$"); #include <dev/random/randomdev.h> #include <dev/random/randomdev_soft.h> -#include <dev/random/nehemiah.h> + +#if defined(__amd64__) || (defined(__i386__) && !defined(PC98)) +#ifdef PADLOCK_RNG +extern struct random_systat random_nehemiah; +#endif +#ifdef IVY_RNG +extern struct random_systat random_ivy; +#endif +#endif void random_ident_hardware(struct random_systat *systat) @@ -56,8 +69,25 @@ random_ident_hardware(struct random_systat *systat) /* Then go looking for hardware */ #if defined(__amd64__) || (defined(__i386__) && !defined(PC98)) +#ifdef PADLOCK_RNG if (via_feature_rng & VIA_HAS_RNG) { - *systat = random_nehemiah; + int enable; + + enable = 1; + TUNABLE_INT_FETCH("hw.nehemiah_rng_enable", &enable); + if (enable) + *systat = random_nehemiah; + } +#endif +#ifdef IVY_RNG + if (cpu_feature2 & CPUID2_RDRAND) { + int enable; + + enable = 1; + TUNABLE_INT_FETCH("hw.ivy_rng_enable", &enable); + if (enable) + *systat = random_ivy; } #endif +#endif } |
