Mention branches and keyring.
[releases.git] / x86 / kernel / cpu / rdrand.c
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 }