Branch data Line data Source code
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 : 0 : static int __init x86_rdrand_setup(char *s) 15 : : { 16 : 0 : setup_clear_cpu_cap(X86_FEATURE_RDRAND); 17 : 0 : setup_clear_cpu_cap(X86_FEATURE_RDSEED); 18 : 0 : return 1; 19 : : } 20 : : __setup("nordrand", x86_rdrand_setup); 21 : : 22 : : /* 23 : : * RDRAND has Built-In-Self-Test (BIST) that runs on every invocation. 24 : : * Run the instruction a few times as a sanity check. 25 : : * If it fails, it is simple to disable RDRAND here. 26 : : */ 27 : : #define SANITY_CHECK_LOOPS 8 28 : : 29 : : #ifdef CONFIG_ARCH_RANDOM 30 : 30 : void x86_init_rdrand(struct cpuinfo_x86 *c) 31 : : { 32 : 30 : unsigned int changed = 0; 33 : 30 : unsigned long tmp, prev; 34 : 30 : int i; 35 : : 36 [ - + ]: 30 : if (!cpu_has(c, X86_FEATURE_RDRAND)) 37 : : return; 38 : : 39 [ # # ]: 0 : for (i = 0; i < SANITY_CHECK_LOOPS; i++) { 40 [ # # ]: 0 : if (!rdrand_long(&tmp)) { 41 : 0 : clear_cpu_cap(c, X86_FEATURE_RDRAND); 42 [ # # ]: 0 : pr_warn_once("rdrand: disabled\n"); 43 : 0 : return; 44 : : } 45 : : } 46 : : 47 : : /* 48 : : * Stupid sanity-check whether RDRAND does *actually* generate 49 : : * some at least random-looking data. 50 : : */ 51 : : prev = tmp; 52 [ # # ]: 0 : for (i = 0; i < SANITY_CHECK_LOOPS; i++) { 53 [ # # ]: 0 : if (rdrand_long(&tmp)) { 54 [ # # ]: 0 : if (prev != tmp) 55 : 0 : changed++; 56 : : 57 : : prev = tmp; 58 : : } 59 : : } 60 : : 61 [ # # # # ]: 0 : if (WARN_ON_ONCE(!changed)) 62 : 0 : pr_emerg( 63 : : "RDRAND gives funky smelling output, might consider not using it by booting with \"nordrand\""); 64 : : 65 : : } 66 : : #endif