summaryrefslogtreecommitdiff
path: root/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig8
-rw-r--r--arch/arm64/include/asm/archrandom.h112
-rw-r--r--arch/arm64/kernel/cpufeature.c2
3 files changed, 47 insertions, 75 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 340e61199057..95839c8d7229 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1895,14 +1895,6 @@ config ARM64_E0PD
This option enables E0PD for TTBR1 where available.
-config ARCH_RANDOM
- bool "Enable support for random number generation"
- default y
- help
- Random number generation (part of the ARMv8.5 Extensions)
- provides a high bandwidth, cryptographically secure
- hardware random number generator.
-
config ARM64_AS_HAS_MTE
# Initial support for MTE went in binutils 2.32.0, checked with
# ".arch armv8.5-a+memtag" below. However, this was incomplete
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 3a6b6d38c5b8..109e2a4454be 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -2,8 +2,6 @@
#ifndef _ASM_ARCHRANDOM_H
#define _ASM_ARCHRANDOM_H
-#ifdef CONFIG_ARCH_RANDOM
-
#include <linux/arm-smccc.h>
#include <linux/bug.h>
#include <linux/kernel.h>
@@ -60,7 +58,7 @@ static inline bool __arm64_rndrrs(unsigned long *v)
return ok;
}
-static inline bool __must_check arch_get_random_long(unsigned long *v)
+static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs)
{
/*
* Only support the generic interface after we have detected
@@ -68,27 +66,15 @@ static inline bool __must_check arch_get_random_long(unsigned long *v)
* cpufeature code and with potential scheduling between CPUs
* with and without the feature.
*/
- if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
- return true;
- return false;
-}
-
-static inline bool __must_check arch_get_random_int(unsigned int *v)
-{
- if (cpus_have_const_cap(ARM64_HAS_RNG)) {
- unsigned long val;
-
- if (__arm64_rndr(&val)) {
- *v = val;
- return true;
- }
- }
- return false;
+ if (max_longs && cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+ return 1;
+ return 0;
}
-static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
+static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs)
{
- struct arm_smccc_res res;
+ if (!max_longs)
+ return 0;
/*
* We prefer the SMCCC call, since its semantics (return actual
@@ -97,10 +83,23 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
* (the output of a pseudo RNG freshly seeded by a TRNG).
*/
if (smccc_trng_available) {
- arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res);
+ struct arm_smccc_res res;
+
+ max_longs = min_t(size_t, 3, max_longs);
+ arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, max_longs * 64, &res);
if ((int)res.a0 >= 0) {
- *v = res.a3;
- return true;
+ switch (max_longs) {
+ case 3:
+ *v++ = res.a1;
+ fallthrough;
+ case 2:
+ *v++ = res.a2;
+ fallthrough;
+ case 1:
+ *v++ = res.a3;
+ break;
+ }
+ return max_longs;
}
}
@@ -110,32 +109,9 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
* enough to implement this API if no other entropy source exists.
*/
if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
- return true;
+ return 1;
- return false;
-}
-
-static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
-{
- struct arm_smccc_res res;
- unsigned long val;
-
- if (smccc_trng_available) {
- arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 32, &res);
- if ((int)res.a0 >= 0) {
- *v = res.a3 & GENMASK(31, 0);
- return true;
- }
- }
-
- if (cpus_have_const_cap(ARM64_HAS_RNG)) {
- if (__arm64_rndrrs(&val)) {
- *v = val;
- return true;
- }
- }
-
- return false;
+ return 0;
}
static inline bool __init __early_cpu_has_rndr(void)
@@ -145,34 +121,40 @@ static inline bool __init __early_cpu_has_rndr(void)
return (ftr >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf;
}
-static inline bool __init __must_check
-arch_get_random_seed_long_early(unsigned long *v)
+static inline size_t __init __must_check
+arch_get_random_seed_longs_early(unsigned long *v, size_t max_longs)
{
WARN_ON(system_state != SYSTEM_BOOTING);
+ if (!max_longs)
+ return 0;
+
if (smccc_trng_available) {
struct arm_smccc_res res;
- arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res);
+ max_longs = min_t(size_t, 3, max_longs);
+ arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, max_longs * 64, &res);
if ((int)res.a0 >= 0) {
- *v = res.a3;
- return true;
+ switch (max_longs) {
+ case 3:
+ *v++ = res.a1;
+ fallthrough;
+ case 2:
+ *v++ = res.a2;
+ fallthrough;
+ case 1:
+ *v++ = res.a3;
+ break;
+ }
+ return max_longs;
}
}
if (__early_cpu_has_rndr() && __arm64_rndr(v))
- return true;
-
- return false;
-}
-#define arch_get_random_seed_long_early arch_get_random_seed_long_early
+ return 1;
-#else /* !CONFIG_ARCH_RANDOM */
-
-static inline bool __init smccc_probe_trng(void)
-{
- return false;
+ return 0;
}
+#define arch_get_random_seed_longs_early arch_get_random_seed_longs_early
-#endif /* CONFIG_ARCH_RANDOM */
#endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index ad64cab0a2ba..907401e4fffb 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2502,7 +2502,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.cpu_enable = cpu_enable_e0pd,
},
#endif
-#ifdef CONFIG_ARCH_RANDOM
{
.desc = "Random Number Generator",
.capability = ARM64_HAS_RNG,
@@ -2514,7 +2513,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sign = FTR_UNSIGNED,
.min_field_value = 1,
},
-#endif
#ifdef CONFIG_ARM64_BTI
{
.desc = "Branch Target Identification",