Skip to content

Commit 92051a1

Browse files
committed
Merge branch 'for-next/rng' into for-next/core
* for-next/rng: arm64: random: implement arch_get_random_int/_long based on RNDR
2 parents b5ef94f + 35bde68 commit 92051a1

1 file changed

Lines changed: 39 additions & 6 deletions

File tree

arch/arm64/include/asm/archrandom.h

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,47 @@ static inline bool __arm64_rndr(unsigned long *v)
4242
return ok;
4343
}
4444

45+
static inline bool __arm64_rndrrs(unsigned long *v)
46+
{
47+
bool ok;
48+
49+
/*
50+
* Reads of RNDRRS set PSTATE.NZCV to 0b0000 on success,
51+
* and set PSTATE.NZCV to 0b0100 otherwise.
52+
*/
53+
asm volatile(
54+
__mrs_s("%0", SYS_RNDRRS_EL0) "\n"
55+
" cset %w1, ne\n"
56+
: "=r" (*v), "=r" (ok)
57+
:
58+
: "cc");
59+
60+
return ok;
61+
}
62+
4563
static inline bool __must_check arch_get_random_long(unsigned long *v)
4664
{
65+
/*
66+
* Only support the generic interface after we have detected
67+
* the system wide capability, avoiding complexity with the
68+
* cpufeature code and with potential scheduling between CPUs
69+
* with and without the feature.
70+
*/
71+
if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
72+
return true;
4773
return false;
4874
}
4975

5076
static inline bool __must_check arch_get_random_int(unsigned int *v)
5177
{
78+
if (cpus_have_const_cap(ARM64_HAS_RNG)) {
79+
unsigned long val;
80+
81+
if (__arm64_rndr(&val)) {
82+
*v = val;
83+
return true;
84+
}
85+
}
5286
return false;
5387
}
5488

@@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
71105
}
72106

73107
/*
74-
* Only support the generic interface after we have detected
75-
* the system wide capability, avoiding complexity with the
76-
* cpufeature code and with potential scheduling between CPUs
77-
* with and without the feature.
108+
* RNDRRS is not backed by an entropy source but by a DRBG that is
109+
* reseeded after each invocation. This is not a 100% fit but good
110+
* enough to implement this API if no other entropy source exists.
78111
*/
79-
if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
112+
if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
80113
return true;
81114

82115
return false;
@@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
96129
}
97130

98131
if (cpus_have_const_cap(ARM64_HAS_RNG)) {
99-
if (__arm64_rndr(&val)) {
132+
if (__arm64_rndrrs(&val)) {
100133
*v = val;
101134
return true;
102135
}

0 commit comments

Comments
 (0)