aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/rdrand.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/rdrand.c')
-rw-r--r--arch/x86/kernel/cpu/rdrand.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c
index 136ac74dee82..819d94982e07 100644
--- a/arch/x86/kernel/cpu/rdrand.c
+++ b/arch/x86/kernel/cpu/rdrand.c
@@ -33,28 +33,27 @@ static int __init x86_rdrand_setup(char *s)
33__setup("nordrand", x86_rdrand_setup); 33__setup("nordrand", x86_rdrand_setup);
34 34
35/* 35/*
36 * Force a reseed cycle; we are architecturally guaranteed a reseed 36 * RDRAND has Built-In-Self-Test (BIST) that runs on every invocation.
37 * after no more than 512 128-bit chunks of random data. This also 37 * Run the instruction a few times as a sanity check.
38 * acts as a test of the CPU capability. 38 * If it fails, it is simple to disable RDRAND here.
39 */ 39 */
40#define RESEED_LOOP ((512*128)/sizeof(unsigned long)) 40#define SANITY_CHECK_LOOPS 8
41 41
42void x86_init_rdrand(struct cpuinfo_x86 *c) 42void x86_init_rdrand(struct cpuinfo_x86 *c)
43{ 43{
44#ifdef CONFIG_ARCH_RANDOM 44#ifdef CONFIG_ARCH_RANDOM
45 unsigned long tmp; 45 unsigned long tmp;
46 int i, count, ok; 46 int i;
47 47
48 if (!cpu_has(c, X86_FEATURE_RDRAND)) 48 if (!cpu_has(c, X86_FEATURE_RDRAND))
49 return; /* Nothing to do */ 49 return;
50 50
51 for (count = i = 0; i < RESEED_LOOP; i++) { 51 for (i = 0; i < SANITY_CHECK_LOOPS; i++) {
52 ok = rdrand_long(&tmp); 52 if (!rdrand_long(&tmp)) {
53 if (ok) 53 clear_cpu_cap(c, X86_FEATURE_RDRAND);
54 count++; 54 printk_once(KERN_WARNING "rdrand: disabled\n");
55 return;
56 }
55 } 57 }
56
57 if (count != RESEED_LOOP)
58 clear_cpu_cap(c, X86_FEATURE_RDRAND);
59#endif 58#endif
60} 59}