diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 9aa61e2..374afcb 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -213,7 +213,8 @@ dev/lindev/lindev.c optional lindev dev/nfe/if_nfe.c optional nfe pci dev/nve/if_nve.c optional nve pci dev/nvram/nvram.c optional nvram isa -dev/random/nehemiah.c optional random +dev/random/ivy.c optional random ivy_rng +dev/random/nehemiah.c optional random padlock_rng dev/qlxgb/qla_dbg.c optional qlxgb pci dev/qlxgb/qla_hw.c optional qlxgb pci dev/qlxgb/qla_ioctl.c optional qlxgb pci diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index f3de163..b592437 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -226,7 +226,8 @@ dev/nfe/if_nfe.c optional nfe pci dev/nve/if_nve.c optional nve pci dev/nvram/nvram.c optional nvram isa dev/pcf/pcf_isa.c optional pcf -dev/random/nehemiah.c optional random +dev/random/ivy.c optional random ivy_rng +dev/random/nehemiah.c optional random padlock_rng dev/sbni/if_sbni.c optional sbni dev/sbni/if_sbni_isa.c optional sbni isa dev/sbni/if_sbni_pci.c optional sbni pci diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index 31d1650..6914ff6 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -68,3 +68,6 @@ XENHVM opt_global.h # options for the Intel C600 SAS driver (isci) ISCI_LOGGING opt_isci.h + +PADLOCK_RNG opt_cpu.h +IVY_RNG opt_cpu.h diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index 3638266..9b942ba 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -123,3 +123,6 @@ XENHVM opt_global.h # options for the Intel C600 SAS driver (isci) ISCI_LOGGING opt_isci.h + +PADLOCK_RNG opt_cpu.h +IVY_RNG opt_cpu.h diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c new file mode 100644 index 0000000..3f9de2d --- /dev/null +++ b/sys/dev/random/ivy.c @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2012 Konstantin Belousov + * 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 +__FBSDID("$FreeBSD$"); + +#include "opt_cpu.h" + +#ifdef IVY_RNG + +#include +#include +#include +#include +#include +#include +#include + +#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 b9f52e7..f3afa89 100644 --- a/sys/dev/random/nehemiah.c +++ b/sys/dev/random/nehemiah.c @@ -28,6 +28,10 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cpu.h" + +#ifdef PADLOCK_RNG + #include #include #include @@ -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 b35fb3f..0000000 --- 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 0bbfd95..085aa09 100644 --- a/sys/dev/random/probe.c +++ b/sys/dev/random/probe.c @@ -28,12 +28,15 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cpu.h" + #include #include +#include +#include #include #include #include -#include #include #if defined(__amd64__) || (defined(__i386__) && !defined(PC98)) @@ -45,7 +48,15 @@ __FBSDID("$FreeBSD$"); #include #include -#include + +#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 +67,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 } diff --git a/sys/modules/random/Makefile b/sys/modules/random/Makefile index 746f45a..ad14899 100644 --- a/sys/modules/random/Makefile +++ b/sys/modules/random/Makefile @@ -8,10 +8,11 @@ KMOD= random SRCS= randomdev.c probe.c .if ${MACHINE} == "amd64" || ${MACHINE} == "i386" SRCS+= nehemiah.c +SRCS+= ivy.c .endif SRCS+= randomdev_soft.c yarrow.c hash.c SRCS+= rijndael-alg-fst.c rijndael-api-fst.c sha2.c -SRCS+= bus_if.h device_if.h vnode_if.h +SRCS+= bus_if.h device_if.h vnode_if.h opt_cpu.h CFLAGS+= -I${.CURDIR}/../..