0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <asm/processor.h>
0011 #include <asm/archrandom.h>
0012 #include <asm/sections.h>
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 void x86_init_rdrand(struct cpuinfo_x86 *c)
0024 {
0025 enum { SAMPLES = 8, MIN_CHANGE = 5 };
0026 unsigned long sample, prev;
0027 bool failure = false;
0028 size_t i, changed;
0029
0030 if (!cpu_has(c, X86_FEATURE_RDRAND))
0031 return;
0032
0033 for (changed = 0, i = 0; i < SAMPLES; ++i) {
0034 if (!rdrand_long(&sample)) {
0035 failure = true;
0036 break;
0037 }
0038 changed += i && sample != prev;
0039 prev = sample;
0040 }
0041 if (changed < MIN_CHANGE)
0042 failure = true;
0043
0044 if (failure) {
0045 clear_cpu_cap(c, X86_FEATURE_RDRAND);
0046 clear_cpu_cap(c, X86_FEATURE_RDSEED);
0047 pr_emerg("RDRAND is not reliable on this platform; disabling.\n");
0048 }
0049 }