Skip to content


x86, random: Verify RDRAND functionality and allow it to be disabled
Browse files Browse the repository at this point in the history
If the CPU declares that RDRAND is available, go through a guranteed
reseed sequence, and make sure that it is actually working (producing
data.)   If it does not, disable the CPU feature flag.

Allow RDRAND to be disabled on the command line (as opposed to at
compile time) for a user who has special requirements with regards to
random numbers.

Signed-off-by: H. Peter Anvin <>
Cc: Matt Mackall <>
Cc: Herbert Xu <>
Cc: "Theodore Ts'o" <>
  • Loading branch information
H. Peter Anvin committed Jul 31, 2011
1 parent 628c624 commit 49d859d
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Documentation/kernel-parameters.txt
Expand Up @@ -1764,6 +1764,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.

noresidual [PPC] Don't use residual data on PReP machines.

nordrand [X86] Disable the direct use of the RDRAND
instruction even if it is supported by the
processor. RDRAND is still available to user
space applications.

noresume [SWSUSP] Disables resume and restores original swap

Expand Down
2 changes: 2 additions & 0 deletions arch/x86/include/asm/archrandom.h
Expand Up @@ -70,4 +70,6 @@ GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);


extern void x86_init_rdrand(struct cpuinfo_x86 *c);

#endif /* ASM_X86_ARCHRANDOM_H */
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/Makefile
Expand Up @@ -15,6 +15,7 @@ CFLAGS_common.o := $(nostackp)
obj-y := intel_cacheinfo.o scattered.o topology.o
obj-y += proc.o capflags.o powerflags.o common.o
obj-y += vmware.o hypervisor.o sched.o mshyperv.o
obj-y += rdrand.o

obj-$(CONFIG_X86_32) += bugs.o
obj-$(CONFIG_X86_64) += bugs_64.o
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/cpu/common.c
Expand Up @@ -15,6 +15,7 @@
#include <asm/stackprotector.h>
#include <asm/perf_event.h>
#include <asm/mmu_context.h>
#include <asm/archrandom.h>
#include <asm/hypervisor.h>
#include <asm/processor.h>
#include <asm/sections.h>
Expand Down Expand Up @@ -857,6 +858,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)


* Clear/Set all flags overriden by options, need do it
Expand Down
73 changes: 73 additions & 0 deletions arch/x86/kernel/cpu/rdrand.c
@@ -0,0 +1,73 @@
* This file is part of the Linux kernel.
* Copyright (c) 2011, Intel Corporation
* Authors: Fenghua Yu <>,
* H. Peter Anvin <>
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

#include <asm/processor.h>
#include <asm/archrandom.h>
#include <asm/sections.h>

static int __init x86_rdrand_setup(char *s)
return 1;
__setup("nordrand", x86_rdrand_setup);

/* We can't use arch_get_random_long() here since alternatives haven't run */
static inline int rdrand_long(unsigned long *v)
int ok;
asm volatile("1: " RDRAND_LONG "\n\t"
"jc 2f\n\t"
"decl %0\n\t"
"jnz 1b\n\t"
: "=r" (ok), "=a" (*v)
return ok;

* Force a reseed cycle; we are architecturally guaranteed a reseed
* after no more than 512 128-bit chunks of random data. This also
* acts as a test of the CPU capability.
#define RESEED_LOOP ((512*128)/sizeof(unsigned long))

void __cpuinit x86_init_rdrand(struct cpuinfo_x86 *c)
unsigned long tmp;
int i, count, ok;

if (!cpu_has(c, X86_FEATURE_RDRAND))
return; /* Nothing to do */

for (count = i = 0; i < RESEED_LOOP; i++) {
ok = rdrand_long(&tmp);
if (ok)

if (count != RESEED_LOOP)
clear_cpu_cap(c, X86_FEATURE_RDRAND);

0 comments on commit 49d859d

Please sign in to comment.