| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * This file is part of the Linux kernel. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2011, Intel Corporation |
|---|
| 5 | 6 | * Authors: Fenghua Yu <fenghua.yu@intel.com>, |
|---|
| 6 | 7 | * H. Peter Anvin <hpa@linux.intel.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 9 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 10 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 13 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 14 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 15 | | - * more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 18 | | - * this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 19 | | - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
|---|
| 20 | | - * |
|---|
| 21 | 8 | */ |
|---|
| 22 | 9 | |
|---|
| 23 | 10 | #include <asm/processor.h> |
|---|
| .. | .. |
|---|
| 42 | 29 | #ifdef CONFIG_ARCH_RANDOM |
|---|
| 43 | 30 | void x86_init_rdrand(struct cpuinfo_x86 *c) |
|---|
| 44 | 31 | { |
|---|
| 45 | | - unsigned long tmp; |
|---|
| 32 | + unsigned int changed = 0; |
|---|
| 33 | + unsigned long tmp, prev; |
|---|
| 46 | 34 | int i; |
|---|
| 47 | 35 | |
|---|
| 48 | 36 | if (!cpu_has(c, X86_FEATURE_RDRAND)) |
|---|
| .. | .. |
|---|
| 55 | 43 | return; |
|---|
| 56 | 44 | } |
|---|
| 57 | 45 | } |
|---|
| 46 | + |
|---|
| 47 | + /* |
|---|
| 48 | + * Stupid sanity-check whether RDRAND does *actually* generate |
|---|
| 49 | + * some at least random-looking data. |
|---|
| 50 | + */ |
|---|
| 51 | + prev = tmp; |
|---|
| 52 | + for (i = 0; i < SANITY_CHECK_LOOPS; i++) { |
|---|
| 53 | + if (rdrand_long(&tmp)) { |
|---|
| 54 | + if (prev != tmp) |
|---|
| 55 | + changed++; |
|---|
| 56 | + |
|---|
| 57 | + prev = tmp; |
|---|
| 58 | + } |
|---|
| 59 | + } |
|---|
| 60 | + |
|---|
| 61 | + if (WARN_ON_ONCE(!changed)) |
|---|
| 62 | + pr_emerg( |
|---|
| 63 | +"RDRAND gives funky smelling output, might consider not using it by booting with \"nordrand\""); |
|---|
| 64 | + |
|---|
| 58 | 65 | } |
|---|
| 59 | 66 | #endif |
|---|