summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2012-09-19 20:19:32 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2012-09-19 20:19:32 +0000
commitfc93de489a744428bec79e8eee015b6f781ac79c (patch)
tree01108c8959c2577fdb5ae00c9524e076ac5a3623 /sys/arch
parente1482512e90dcff64ca6dd0cd88aad37e711af76 (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.c10
-rw-r--r--sys/arch/amd64/amd64/cpu.c33
-rw-r--r--sys/arch/amd64/amd64/identcpu.c6
-rw-r--r--sys/arch/i386/i386/autoconf.c11
-rw-r--r--sys/arch/i386/i386/cpu.c25
-rw-r--r--sys/arch/i386/i386/machdep.c9
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;