Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * This file is part of the Linux kernel.
0004  *
0005  * Copyright (c) 2011, Intel Corporation
0006  * Authors: Fenghua Yu <fenghua.yu@intel.com>,
0007  *          H. Peter Anvin <hpa@linux.intel.com>
0008  */
0009 
0010 #include <asm/processor.h>
0011 #include <asm/archrandom.h>
0012 #include <asm/sections.h>
0013 
0014 /*
0015  * RDRAND has Built-In-Self-Test (BIST) that runs on every invocation.
0016  * Run the instruction a few times as a sanity check. Also make sure
0017  * it's not outputting the same value over and over, which has happened
0018  * as a result of past CPU bugs.
0019  *
0020  * If it fails, it is simple to disable RDRAND and RDSEED here.
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 }