diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2012-09-19 20:19:32 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2012-09-19 20:19:32 +0000 |
commit | fc93de489a744428bec79e8eee015b6f781ac79c (patch) | |
tree | 01108c8959c2577fdb5ae00c9524e076ac5a3623 /sys/arch | |
parent | e1482512e90dcff64ca6dd0cd88aad37e711af76 (diff) |
Add support for the rdrand instruction found in recent Intel processors.
Joint work with naddy@
ok naddy@ deraadt@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/autoconf.c | 10 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 33 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/identcpu.c | 6 | ||||
-rw-r--r-- | sys/arch/i386/i386/autoconf.c | 11 | ||||
-rw-r--r-- | sys/arch/i386/i386/cpu.c | 25 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 9 |
6 files changed, 88 insertions, 6 deletions
diff --git a/sys/arch/amd64/amd64/autoconf.c b/sys/arch/amd64/amd64/autoconf.c index 4cab84c0534..55f241ffe90 100644 --- a/sys/arch/amd64/amd64/autoconf.c +++ b/sys/arch/amd64/amd64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.38 2012/07/13 14:43:28 mlarkin Exp $ */ +/* $OpenBSD: autoconf.c,v 1.39 2012/09/19 20:19:31 jsg Exp $ */ /* $NetBSD: autoconf.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -97,6 +97,10 @@ extern struct timeout viac3_rnd_tmo; extern int viac3_rnd_present; void viac3_rnd(void *); +extern struct timeout rdrand_tmo; +extern int has_rdrand; +void rdrand(void *); + #ifdef CRYPTO void viac3_crypto_setup(void); extern int amd64_has_xcrypt; @@ -143,6 +147,10 @@ cpu_configure(void) timeout_set(&viac3_rnd_tmo, viac3_rnd, &viac3_rnd_tmo); viac3_rnd(&viac3_rnd_tmo); } + if (has_rdrand) { + timeout_set(&rdrand_tmo, rdrand, &rdrand_tmo); + rdrand(&rdrand_tmo); + } #ifdef CRYPTO /* * Also, if the chip has crypto available, enable it. diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index 493dbc99706..213923825b6 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.50 2012/07/09 15:25:39 deraadt Exp $ */ +/* $OpenBSD: cpu.c,v 1.51 2012/09/19 20:19:31 jsg Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -101,6 +101,7 @@ #include <dev/ic/mc146818reg.h> #include <amd64/isa/nvram.h> #include <dev/isa/isareg.h> +#include <dev/rndvar.h> int cpu_match(struct device *, void *, void *); void cpu_attach(struct device *, struct device *, void *); @@ -725,3 +726,33 @@ patinit(struct cpu_info *ci) wrmsr(MSR_CR_PAT, reg); pmap_pg_wc = PG_WC; } + +struct timeout rdrand_tmo; +void rdrand(void *); + +void +rdrand(void *v) +{ + struct timeout *tmo = v; + union { + uint64_t u64; + uint32_t u32[2]; + } r; + uint64_t valid; + int i; + + for (i = 0; i < 2; i++) { + __asm __volatile( + "xor %1, %1\n\t" + "rdrand %0\n\t" + "rcl $1, %1\n" + : "=r" (r.u64), "=r" (valid) ); + + if (valid) { + add_true_randomness(r.u32[0]); + add_true_randomness(r.u32[1]); + } + } + + timeout_add_msec(tmo, 10); +} diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index 84806873a76..f6fc27f61b9 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: identcpu.c,v 1.38 2012/09/07 22:02:34 naddy Exp $ */ +/* $OpenBSD: identcpu.c,v 1.39 2012/09/19 20:19:31 jsg Exp $ */ /* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /* @@ -52,6 +52,7 @@ int amd64_has_xcrypt; #ifdef CRYPTO int amd64_has_aesni; #endif +int has_rdrand; const struct { u_int32_t bit; @@ -432,6 +433,9 @@ identifycpu(struct cpu_info *ci) if (cpu_ecxfeature & CPUIDECX_AES) amd64_has_aesni = 1; + + if (cpu_ecxfeature & CPUIDECX_RDRAND) + has_rdrand = 1; } if (!strncmp(mycpu_model, "Intel", 5)) { u_int32_t cflushsz; diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index 1ce58a3fec2..f5429788cf6 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.90 2012/07/13 14:50:10 mlarkin Exp $ */ +/* $OpenBSD: autoconf.c,v 1.91 2012/09/19 20:19:31 jsg Exp $ */ /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ /*- @@ -89,6 +89,10 @@ extern struct timeout viac3_rnd_tmo; extern int viac3_rnd_present; void viac3_rnd(void *); +extern struct timeout rdrand_tmo; +extern int has_rdrand; +void rdrand(void *); + #ifdef CRYPTO void viac3_crypto_setup(void); extern int i386_has_xcrypt; @@ -143,6 +147,11 @@ cpu_configure(void) timeout_set(&viac3_rnd_tmo, viac3_rnd, &viac3_rnd_tmo); viac3_rnd(&viac3_rnd_tmo); } + if (has_rdrand) { + timeout_set(&rdrand_tmo, rdrand, &rdrand_tmo); + rdrand(&rdrand_tmo); + } + #ifdef CRYPTO /* * Also, if the chip has crypto available, enable it. diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c index 40840056c30..d3cd2a90e13 100644 --- a/sys/arch/i386/i386/cpu.c +++ b/sys/arch/i386/i386/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.44 2012/07/09 15:25:37 deraadt Exp $ */ +/* $OpenBSD: cpu.c,v 1.45 2012/09/19 20:19:31 jsg Exp $ */ /* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */ /*- @@ -102,6 +102,7 @@ #include <dev/ic/mc146818reg.h> #include <i386/isa/nvram.h> #include <dev/isa/isareg.h> +#include <dev/rndvar.h> int cpu_match(struct device *, void *, void *); void cpu_attach(struct device *, struct device *, void *); @@ -384,6 +385,28 @@ patinit(struct cpu_info *ci) pmap_pg_wc = PG_WC; } +struct timeout rdrand_tmo; +void rdrand(void *); + +void +rdrand(void *v) +{ + struct timeout *tmo = v; + uint32_t r, valid; + int i; + + for (i = 0; i < 4; i++) { + __asm __volatile( + "xor %1, %1\n\t" + "rdrand %0\n\t" + "rcl $1, %1\n" + : "=r" (r), "=r" (valid) ); + if (valid) + add_true_randomness(r); + } + + timeout_add_msec(tmo, 10); +} #ifdef MULTIPROCESSOR void diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index e76449d9090..97591d87adb 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.511 2012/08/24 02:49:23 guenther Exp $ */ +/* $OpenBSD: machdep.c,v 1.512 2012/09/19 20:19:31 jsg Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -306,6 +306,8 @@ int allowaperture = 0; #endif #endif +int has_rdrand; + void winchip_cpu_setup(struct cpu_info *); void amd_family5_setperf_setup(struct cpu_info *); void amd_family5_setup(struct cpu_info *); @@ -1906,6 +1908,11 @@ identifycpu(struct cpu_info *ci) } } + if (ci->ci_flags & CPUF_PRIMARY) { + if (cpu_ecxfeature & CPUIDECX_RDRAND) + has_rdrand = 1; + } + #ifndef SMALL_KERNEL if (cpuspeed != 0 && cpu_cpuspeed == NULL) cpu_cpuspeed = pentium_cpuspeed; |