Page MenuHomeFreeBSD

D20192.id.diff
No OneTemporary

D20192.id.diff

Index: head/sys/dev/random/ivy.c
===================================================================
--- head/sys/dev/random/ivy.c
+++ head/sys/dev/random/ivy.c
@@ -44,11 +44,13 @@
#include <machine/md_var.h>
#include <machine/specialreg.h>
+#include <x86/ifunc.h>
#include <dev/random/randomdev.h>
#define RETRY_COUNT 10
+static bool has_rdrand, has_rdseed;
static u_int random_ivy_read(void *, u_int);
static struct random_source random_ivy = {
@@ -57,10 +59,9 @@
.rs_read = random_ivy_read
};
-static inline int
-ivy_rng_store(u_long *buf)
+static int
+x86_rdrand_store(u_long *buf)
{
-#ifdef __GNUCLIKE_ASM
u_long rndval;
int retry;
@@ -75,11 +76,40 @@
: "+r" (retry), "=r" (rndval) : : "cc");
*buf = rndval;
return (retry);
-#else /* __GNUCLIKE_ASM */
- return (0);
-#endif
}
+static int
+x86_rdseed_store(u_long *buf)
+{
+ u_long rndval;
+ int retry;
+
+ retry = RETRY_COUNT;
+ __asm __volatile(
+ "1:\n\t"
+ "rdseed %1\n\t" /* read randomness into rndval */
+ "jc 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 */
+ "2:"
+ : "+r" (retry), "=r" (rndval) : : "cc");
+ *buf = rndval;
+ return (retry);
+}
+
+DEFINE_IFUNC(static, int, x86_rng_store, (u_long *buf), static)
+{
+ has_rdrand = (cpu_feature2 & CPUID2_RDRAND);
+ has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
+
+ if (has_rdseed)
+ return (x86_rdseed_store);
+ else if (has_rdrand)
+ return (x86_rdrand_store);
+ else
+ return (NULL);
+}
+
/* It is required that buf length is a multiple of sizeof(u_long). */
static u_int
random_ivy_read(void *buf, u_int c)
@@ -90,7 +120,7 @@
KASSERT(c % sizeof(*b) == 0, ("partial read %d", c));
b = buf;
for (count = c; count > 0; count -= sizeof(*b)) {
- if (ivy_rng_store(&rndval) == 0)
+ if (x86_rng_store(&rndval) == 0)
break;
*b++ = rndval;
}
@@ -104,14 +134,14 @@
switch (type) {
case MOD_LOAD:
- if (cpu_feature2 & CPUID2_RDRAND) {
+ if (has_rdrand || has_rdseed) {
random_source_register(&random_ivy);
printf("random: fast provider: \"%s\"\n", random_ivy.rs_ident);
}
break;
case MOD_UNLOAD:
- if (cpu_feature2 & CPUID2_RDRAND)
+ if (has_rdrand || has_rdseed)
random_source_deregister(&random_ivy);
break;

File Metadata

Mime Type
text/plain
Expires
Fri, Jul 24, 3:09 AM (14 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35427173
Default Alt Text
D20192.id.diff (2 KB)

Event Timeline