// SPDX-License-Identifier: GPL-2.0-only1/*2* This file is part of the Linux kernel.3*4* Copyright (c) 2011, Intel Corporation5* Authors: Fenghua Yu <[email protected]>,6* H. Peter Anvin <[email protected]>7*/8#include <linux/printk.h>910#include <asm/processor.h>11#include <asm/archrandom.h>12#include <asm/sections.h>1314/*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 sure17* it's not outputting the same value over and over, which has happened18* as a result of past CPU bugs.19*20* If it fails, it is simple to disable RDRAND and RDSEED here.21*/2223void x86_init_rdrand(struct cpuinfo_x86 *c)24{25enum { SAMPLES = 8, MIN_CHANGE = 5 };26unsigned long sample, prev;27bool failure = false;28size_t i, changed;2930if (!cpu_has(c, X86_FEATURE_RDRAND))31return;3233for (changed = 0, i = 0; i < SAMPLES; ++i) {34if (!rdrand_long(&sample)) {35failure = true;36break;37}38changed += i && sample != prev;39prev = sample;40}41if (changed < MIN_CHANGE)42failure = true;4344if (failure) {45clear_cpu_cap(c, X86_FEATURE_RDRAND);46clear_cpu_cap(c, X86_FEATURE_RDSEED);47pr_emerg("RDRAND is not reliable on this platform; disabling.\n");48}49}505152