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 4 : void x86_init_rdrand(struct cpuinfo_x86 *c) 31 : { 32 4 : unsigned int changed = 0; 33 4 : unsigned long tmp, prev; 34 4 : int i; 35 : 36 4 : if (!cpu_has(c, X86_FEATURE_RDRAND)) 37 4 : return; 38 : 39 36 : for (i = 0; i < SANITY_CHECK_LOOPS; i++) { 40 64 : 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 36 : for (i = 0; i < SANITY_CHECK_LOOPS; i++) { 53 64 : if (rdrand_long(&tmp)) { 54 32 : if (prev != tmp) 55 32 : changed++; 56 : 57 : prev = tmp; 58 : } 59 : } 60 : 61 4 : 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