1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * This file is part of the Linux kernel. 4 * 5 * Copyright (c) 2011, Intel Corporation 6 * Authors: Fenghua Yu <fenghua.yu@intel.com>, 7 * H. Peter Anvin <hpa@linux.intel.com> 8 */ 9 10 #include <asm/processor.h> 11 #include <asm/archrandom.h> 12 #include <asm/sections.h> 13 14 /* 15 * RDRAND has Built-In-Self-Test (BIST) that runs on every invocation. 16 * Run the instruction a few times as a sanity check. Also make sure 17 * it's not outputting the same value over and over, which has happened 18 * as a result of past CPU bugs. 19 * 20 * If it fails, it is simple to disable RDRAND and RDSEED here. 21 */ 22 23 void x86_init_rdrand(struct cpuinfo_x86 *c) 24 { 25 enum { SAMPLES = 8, MIN_CHANGE = 5 }; 26 unsigned long sample, prev; 27 bool failure = false; 28 size_t i, changed; 29 30 if (!cpu_has(c, X86_FEATURE_RDRAND)) 31 return; 32 33 for (changed = 0, i = 0; i < SAMPLES; ++i) { 34 if (!rdrand_long(&sample)) { 35 failure = true; 36 break; 37 } 38 changed += i && sample != prev; 39 prev = sample; 40 } 41 if (changed < MIN_CHANGE) 42 failure = true; 43 44 if (failure) { 45 clear_cpu_cap(c, X86_FEATURE_RDRAND); 46 clear_cpu_cap(c, X86_FEATURE_RDSEED); 47 pr_emerg("RDRAND is not reliable on this platform; disabling.\n"); 48 } 49 } 50