Commit | Line | Data |
---|---|---|
a61127c2 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
628c6246 PA |
2 | /* |
3 | * This file is part of the Linux kernel. | |
4 | * | |
d20f78d2 | 5 | * Copyright (c) 2011-2014, Intel Corporation |
628c6246 PA |
6 | * Authors: Fenghua Yu <fenghua.yu@intel.com>, |
7 | * H. Peter Anvin <hpa@linux.intel.com> | |
628c6246 PA |
8 | */ |
9 | ||
10 | #ifndef ASM_X86_ARCHRANDOM_H | |
11 | #define ASM_X86_ARCHRANDOM_H | |
12 | ||
13 | #include <asm/processor.h> | |
14 | #include <asm/cpufeature.h> | |
628c6246 PA |
15 | |
16 | #define RDRAND_RETRY_LOOPS 10 | |
17 | ||
3b290398 | 18 | /* Unconditional execution of RDRAND and RDSEED */ |
628c6246 | 19 | |
1640a7b9 | 20 | static inline bool __must_check rdrand_long(unsigned long *v) |
5bfce5ef | 21 | { |
3b290398 PA |
22 | bool ok; |
23 | unsigned int retry = RDRAND_RETRY_LOOPS; | |
24 | do { | |
3d81b3d1 | 25 | asm volatile("rdrand %[out]" |
3b290398 | 26 | CC_SET(c) |
3d81b3d1 | 27 | : CC_OUT(c) (ok), [out] "=r" (*v)); |
3b290398 PA |
28 | if (ok) |
29 | return true; | |
30 | } while (--retry); | |
31 | return false; | |
32 | } | |
33 | ||
1640a7b9 | 34 | static inline bool __must_check rdseed_long(unsigned long *v) |
d20f78d2 | 35 | { |
117780ee | 36 | bool ok; |
3d81b3d1 | 37 | asm volatile("rdseed %[out]" |
3b290398 | 38 | CC_SET(c) |
3d81b3d1 | 39 | : CC_OUT(c) (ok), [out] "=r" (*v)); |
d20f78d2 PA |
40 | return ok; |
41 | } | |
42 | ||
3b290398 PA |
43 | /* |
44 | * These are the generic interfaces; they must not be declared if the | |
9592eef7 | 45 | * stubs in <linux/random.h> are to be invoked. |
3b290398 | 46 | */ |
5bfce5ef | 47 | |
d349ab99 | 48 | static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs) |
3b290398 | 49 | { |
d349ab99 | 50 | return max_longs && static_cpu_has(X86_FEATURE_RDRAND) && rdrand_long(v) ? 1 : 0; |
3b290398 PA |
51 | } |
52 | ||
d349ab99 | 53 | static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs) |
3b290398 | 54 | { |
d349ab99 | 55 | return max_longs && static_cpu_has(X86_FEATURE_RDSEED) && rdseed_long(v) ? 1 : 0; |
3b290398 | 56 | } |
628c6246 | 57 | |
9592eef7 JD |
58 | #ifndef CONFIG_UML |
59 | void x86_init_rdrand(struct cpuinfo_x86 *c); | |
60 | #endif | |
3b290398 | 61 | |
628c6246 | 62 | #endif /* ASM_X86_ARCHRANDOM_H */ |