Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_*

The hardware RNG on POWER8 and POWER7+ can be relatively slow, since
it can only supply one 64-bit value per microsecond. Currently we
read it in arch_get_random_long(), but that slows down reading from
/dev/urandom since the code in random.c calls arch_get_random_long()
for every longword read from /dev/urandom.

Since the hardware RNG supplies high-quality entropy on every read, it
matches the semantics of arch_get_random_seed_long() better than those
of arch_get_random_long(). Therefore this commit makes the code use
the POWER8/7+ hardware RNG only for arch_get_random_seed_{long,int}
and not for arch_get_random_{long,int}.

This won't affect any other PowerPC-based platforms because none of
them currently support a hardware RNG. To make it clear that the
ppc_md function pointer is used for arch_get_random_seed_*, we rename
it from get_random_long to get_random_seed.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Paul Mackerras and committed by
Michael Ellerman
01c9348c 1c2cb594

+17 -17
+14 -14
arch/powerpc/include/asm/archrandom.h
··· 7 7 8 8 static inline int arch_get_random_long(unsigned long *v) 9 9 { 10 - if (ppc_md.get_random_long) 11 - return ppc_md.get_random_long(v); 12 - 13 10 return 0; 14 11 } 15 12 16 13 static inline int arch_get_random_int(unsigned int *v) 14 + { 15 + return 0; 16 + } 17 + 18 + static inline int arch_get_random_seed_long(unsigned long *v) 19 + { 20 + if (ppc_md.get_random_seed) 21 + return ppc_md.get_random_seed(v); 22 + 23 + return 0; 24 + } 25 + static inline int arch_get_random_seed_int(unsigned int *v) 17 26 { 18 27 unsigned long val; 19 28 int rc; ··· 36 27 37 28 static inline int arch_has_random(void) 38 29 { 39 - return !!ppc_md.get_random_long; 30 + return 0; 40 31 } 41 32 42 - static inline int arch_get_random_seed_long(unsigned long *v) 43 - { 44 - return 0; 45 - } 46 - static inline int arch_get_random_seed_int(unsigned int *v) 47 - { 48 - return 0; 49 - } 50 33 static inline int arch_has_random_seed(void) 51 34 { 52 - return 0; 35 + return !!ppc_md.get_random_seed; 53 36 } 54 - 55 37 #endif /* CONFIG_ARCH_RANDOM */ 56 38 57 39 #ifdef CONFIG_PPC_POWERNV
+1 -1
arch/powerpc/include/asm/machdep.h
··· 249 249 #endif 250 250 251 251 #ifdef CONFIG_ARCH_RANDOM 252 - int (*get_random_long)(unsigned long *v); 252 + int (*get_random_seed)(unsigned long *v); 253 253 #endif 254 254 }; 255 255
+1 -1
arch/powerpc/platforms/powernv/rng.c
··· 128 128 129 129 pr_info_once("Registering arch random hook.\n"); 130 130 131 - ppc_md.get_random_long = powernv_get_random_long; 131 + ppc_md.get_random_seed = powernv_get_random_long; 132 132 133 133 return 0; 134 134 }
+1 -1
arch/powerpc/platforms/pseries/rng.c
··· 38 38 39 39 pr_info("Registering arch random hook.\n"); 40 40 41 - ppc_md.get_random_long = pseries_get_random_long; 41 + ppc_md.get_random_seed = pseries_get_random_long; 42 42 43 43 return 0; 44 44 }