Re: [PATCH 09/10] x86, asm: Use CC_SET()/CC_OUT() and static_cpu_has() in archrandom.h

2016-06-07 Thread Andy Lutomirski
On Tue, Jun 7, 2016 at 4:31 PM, H. Peter Anvin  wrote:
> Use CC_SET()/CC_OUT() and static_cpu_has().  This produces code good
> enough to eliminate ad hoc use of alternatives in ,
> greatly simplifying the code.

Looks reasonable.


[PATCH 09/10] x86, asm: Use CC_SET()/CC_OUT() and static_cpu_has() in archrandom.h

2016-06-07 Thread H. Peter Anvin
Use CC_SET()/CC_OUT() and static_cpu_has().  This produces code good
enough to eliminate ad hoc use of alternatives in ,
greatly simplifying the code.

Signed-off-by: H. Peter Anvin 
---
 arch/x86/include/asm/archrandom.h | 113 --
 1 file changed, 47 insertions(+), 66 deletions(-)

diff --git a/arch/x86/include/asm/archrandom.h 
b/arch/x86/include/asm/archrandom.h
index ab6f599..654da36 100644
--- a/arch/x86/include/asm/archrandom.h
+++ b/arch/x86/include/asm/archrandom.h
@@ -40,96 +40,77 @@
 # define RDSEED_LONG   RDSEED_INT
 #endif
 
-#ifdef CONFIG_ARCH_RANDOM
+/* Unconditional execution of RDRAND and RDSEED */
 
-/* Instead of arch_get_random_long() when alternatives haven't run. */
 static inline bool rdrand_long(unsigned long *v)
 {
-   int ok;
-   asm volatile("1: " RDRAND_LONG "\n\t"
-"jc 2f\n\t"
-"decl %0\n\t"
-"jnz 1b\n\t"
-"2:"
-: "=r" (ok), "=a" (*v)
-: "0" (RDRAND_RETRY_LOOPS));
-   return !!ok;
+   bool ok;
+   unsigned int retry = RDRAND_RETRY_LOOPS;
+   do {
+   asm volatile(RDRAND_LONG "\n\t"
+CC_SET(c)
+: CC_OUT(c) (ok), "=a" (*v));
+   if (ok)
+   return true;
+   } while (--retry);
+   return false;
+}
+
+static inline bool rdrand_int(unsigned int *v)
+{
+   bool ok;
+   unsigned int retry = RDRAND_RETRY_LOOPS;
+   do {
+   asm volatile(RDRAND_INT "\n\t"
+CC_SET(c)
+: CC_OUT(c) (ok), "=a" (*v));
+   if (ok)
+   return true;
+   } while (--retry);
+   return false;
 }
 
-/* A single attempt at RDSEED */
 static inline bool rdseed_long(unsigned long *v)
 {
bool ok;
asm volatile(RDSEED_LONG "\n\t"
-"setc %0"
-: "=qm" (ok), "=a" (*v));
+CC_SET(c)
+: CC_OUT(c) (ok), "=a" (*v));
return ok;
 }
 
-#define GET_RANDOM(name, type, rdrand, nop)\
-static inline bool name(type *v)   \
-{  \
-   int ok; \
-   alternative_io("movl $0, %0\n\t"\
-  nop, \
-  "\n1: " rdrand "\n\t"\
-  "jc 2f\n\t"  \
-  "decl %0\n\t"\
-  "jnz 1b\n\t" \
-  "2:",\
-  X86_FEATURE_RDRAND,  \
-  ASM_OUTPUT2("=r" (ok), "=a" (*v)),   \
-  "0" (RDRAND_RETRY_LOOPS));   \
-   return !!ok;\
-}
-
-#define GET_SEED(name, type, rdseed, nop)  \
-static inline bool name(type *v)   \
-{  \
-   bool ok;\
-   alternative_io("movb $0, %0\n\t"\
-  nop, \
-  rdseed "\n\t"\
-  "setc %0",   \
-  X86_FEATURE_RDSEED,  \
-  ASM_OUTPUT2("=q" (ok), "=a" (*v)));  \
-   return ok;  \
+static inline bool rdseed_int(unsigned int *v)
+{
+   bool ok;
+   asm volatile(RDSEED_INT "\n\t"
+CC_SET(c)
+: CC_OUT(c) (ok), "=a" (*v));
+   return ok;
 }
 
-#ifdef CONFIG_X86_64
-
-GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP5);
-GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP4);
-
-GET_SEED(arch_get_random_seed_long, unsigned long, RDSEED_LONG, ASM_NOP5);
-GET_SEED(arch_get_random_seed_int, unsigned int, RDSEED_INT, ASM_NOP4);
-
-#else
-
-GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP3);
-GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);
-
-GET_SEED(arch_get_random_seed_long, unsigned long, RDSEED_LONG, ASM_NOP4);
-GET_SEED(arch_get_random_seed_int, unsigned int, RDSEED_INT, ASM_NOP4);
-
-#endif /* CONFIG_X86_64 */
-
+/* Conditional execution based on CPU type */
 #define arch_has_random()  static_cpu_has(X86_FEATURE_RDRAND)
 #define arch_has_random_seed() static_cpu_has(X86_FEATURE_RDSEED)
 
-#else
+static inline bool arch_get_random_long(unsigned long *v)
+{
+   ret