From 25f3ce6a509ff9e3a354303023cb2028e9f83b95 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 29 Oct 2019 18:59:32 +0000 Subject: [PATCH] base/dispatch.c, etc.: Replace inline assembler for the `rdrand' fix. --- base/dispatch-x86ish.S | 43 +++++++++++++++++++++++++++++++++++++++++++ base/dispatch.c | 24 +++--------------------- debian/catacomb2.symbols | 1 + 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/base/dispatch-x86ish.S b/base/dispatch-x86ish.S index 2c267b62..3e2d4c83 100644 --- a/base/dispatch-x86ish.S +++ b/base/dispatch-x86ish.S @@ -153,4 +153,47 @@ FUNC(dispatch_x86ish_xmmregisters_p) ret ENDFUNC +///-------------------------------------------------------------------------- +/// Checking `rdrand'. + +FUNC(dispatch_x86ish_rdrand) + // Enter with one argument: a pointer X_OUT to a 32-bit word. Try to + // generate a random word using `rdrand'. If successful, set *X_OUT + // to the generated word, and return zero; otherwise, return -1. + +#if CPUFAM_X86 +# define X_OUT edx +# define COUNT ecx + mov X_OUT, [SP + 4] +#endif +#if CPUFAM_AMD64 && ABI_SYSV +# define X_OUT rdi +# define COUNT ecx +#endif +#if CPUFAM_AMD64 && ABI_WIN +# define X_OUT rcx +# define COUNT edx +#endif + endprologue + + mov COUNT, 16 // fairly persistent +0: rdrand eax + jc 9f + dec COUNT + jnz 0b + + // Failed to come up with a random value. + mov eax, -1 + ret + + // Success. +9: mov [X_OUT], eax + xor eax, eax + ret + +#undef X_OUT +#undef COUNT + +ENDFUNC + ///----- That's all, folks -------------------------------------------------- diff --git a/base/dispatch.c b/base/dispatch.c index 459302f0..65ea2d25 100644 --- a/base/dispatch.c +++ b/base/dispatch.c @@ -54,6 +54,7 @@ struct cpuid { unsigned a, b, c, d; }; extern int dispatch_x86ish_cpuid(struct cpuid *, unsigned a, unsigned c); extern int dispatch_x86ish_xmmregisters_p(void); +extern int dispatch_x86ish_rdrand(unsigned *); static void cpuid(struct cpuid *cc, unsigned a, unsigned c) { @@ -110,25 +111,6 @@ static int xmm_registers_available_p(void) * that it's already been verified to be safe to issue. */ -#ifdef __GNUC__ -static int rdrand(unsigned *x) -{ - int i, rc; - unsigned _t; - - i = 16; - __asm__ ("" : "=g" (_t)); - __asm__ ("0: rdrand %2; jc 1f; decl %1; jnz 0b\n" - "mov $-1, %0; jmp 9f\n" - "1: movl %2, (%3); xorl %0, %0\n" - "9:" - : "=r" (rc), "+r" (i), "+r" (_t) - : "r" (x) - : "cc"); - return (rc); -} -#endif - static int rdrand_works_p(void) { unsigned ref, x, i; @@ -137,9 +119,9 @@ static int rdrand_works_p(void) * will fail with probability %$2^{-128}$% with a truly random generator, * which seems fair enough. */ - if (rdrand(&ref)) goto fail; + if (dispatch_x86ish_rdrand(&ref)) goto fail; for (i = 0; i < 4; i++) { - if (rdrand(&x)) goto fail; + if (dispatch_x86ish_rdrand(&x)) goto fail; if (x != ref) goto not_stuck; } dispatch_debug("RDRAND always returns 0x%08x!", ref); diff --git a/debian/catacomb2.symbols b/debian/catacomb2.symbols index 772d218e..33d5915a 100644 --- a/debian/catacomb2.symbols +++ b/debian/catacomb2.symbols @@ -24,6 +24,7 @@ libcatacomb.so.2 catacomb2 #MINVER# cpu_feature_p@Base 2.2.3 dispatch_debug@Base 2.2.3 (optional|arch=i386 amd64)dispatch_x86ish_cpuid@Base 2.5.0 + (optional|arch=i386 amd64)dispatch_x86ish_rdrand@Base 2.5.99~ (optional|arch=i386 amd64)dispatch_x86ish_xmmregisters_p@Base 2.5.0 ## regdump (available with `--enable-asm-debug') -- 2.11.0