50 lines · 1.2 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * This file is part of the Linux kernel. * * Copyright (c) 2011, Intel Corporation * Authors: Fenghua Yu <fenghua.yu@intel.com>, *          H. Peter Anvin <hpa@linux.intel.com> */#include <linux/printk.h> #include <asm/processor.h>#include <asm/archrandom.h>#include <asm/sections.h> /* * RDRAND has Built-In-Self-Test (BIST) that runs on every invocation. * Run the instruction a few times as a sanity check. Also make sure * it's not outputting the same value over and over, which has happened * as a result of past CPU bugs. * * If it fails, it is simple to disable RDRAND and RDSEED here. */ void x86_init_rdrand(struct cpuinfo_x86 *c){	enum { SAMPLES = 8, MIN_CHANGE = 5 };	unsigned long sample, prev;	bool failure = false;	size_t i, changed; 	if (!cpu_has(c, X86_FEATURE_RDRAND))		return; 	for (changed = 0, i = 0; i < SAMPLES; ++i) {		if (!rdrand_long(&sample)) {			failure = true;			break;		}		changed += i && sample != prev;		prev = sample;	}	if (changed < MIN_CHANGE)		failure = true; 	if (failure) {		clear_cpu_cap(c, X86_FEATURE_RDRAND);		clear_cpu_cap(c, X86_FEATURE_RDSEED);		pr_emerg("RDRAND is not reliable on this platform; disabling.\n");	}}