All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/3] ARMv8.5-RNG support
@ 2020-01-07 18:35 Mark Brown
  2020-01-07 18:35 ` [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Mark Brown @ 2020-01-07 18:35 UTC (permalink / raw
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel

This series is based on Richard Henderson's previous v7, it addresses
review comments from that version by splitting the boot and runtime
interaction with the core random code so that they are completely
separate and adds a new change that uses the v8.5-RNG extension to seed
KASLR when ARCH_RANDOM is enabled.

Mark Brown (2):
  arm64: random: Add data to pool from setup_arch()
  arm64: Use v8.5-RNG entropy for KASLR seed

Richard Henderson (1):
  arm64: Implement archrandom.h for ARMv8.5-RNG

 Documentation/arm64/cpu-feature-registers.rst |  2 +
 arch/arm64/Kconfig                            | 12 +++
 arch/arm64/include/asm/archrandom.h           | 91 +++++++++++++++++++
 arch/arm64/include/asm/cpucaps.h              |  3 +-
 arch/arm64/include/asm/sysreg.h               |  4 +
 arch/arm64/kernel/cpufeature.c                | 13 +++
 arch/arm64/kernel/kaslr.c                     | 15 ++-
 arch/arm64/kernel/setup.c                     |  2 +
 8 files changed, 140 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/include/asm/archrandom.h

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG
  2020-01-07 18:35 [PATCH v8 0/3] ARMv8.5-RNG support Mark Brown
@ 2020-01-07 18:35 ` Mark Brown
  2020-01-08 17:18   ` Mark Rutland
  2020-01-07 18:35 ` [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
  2020-01-07 18:35 ` [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
  2 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2020-01-07 18:35 UTC (permalink / raw
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel

From: Richard Henderson <richard.henderson@linaro.org>

Expose the ID_AA64ISAR0.RNDR field to userspace, as the RNG system
registers are always available at EL0.

Implement arch_get_random_seed_long using RNDR.  Given that the
TRNG is likely to be a shared resource between cores, and VMs,
do not explicitly force re-seeding with RNDRRS.  In order to avoid
code complexity and potential issues with hetrogenous systems only
provide values after cpufeature has finalized the system capabilities.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
[Modified to only function after cpufeature has finalized the system
capabilities and move all the code into the header -- broonie]
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 Documentation/arm64/cpu-feature-registers.rst |  2 +
 arch/arm64/Kconfig                            | 12 ++++
 arch/arm64/include/asm/archrandom.h           | 67 +++++++++++++++++++
 arch/arm64/include/asm/cpucaps.h              |  3 +-
 arch/arm64/include/asm/sysreg.h               |  4 ++
 arch/arm64/kernel/cpufeature.c                | 13 ++++
 6 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/archrandom.h

diff --git a/Documentation/arm64/cpu-feature-registers.rst b/Documentation/arm64/cpu-feature-registers.rst
index b6e44884e3ad..ce320785fb0c 100644
--- a/Documentation/arm64/cpu-feature-registers.rst
+++ b/Documentation/arm64/cpu-feature-registers.rst
@@ -117,6 +117,8 @@ infrastructure:
      +------------------------------+---------+---------+
      | Name                         |  bits   | visible |
      +------------------------------+---------+---------+
+     | RNDR                         | [63-60] |    y    |
+     +------------------------------+---------+---------+
      | TS                           | [55-52] |    y    |
      +------------------------------+---------+---------+
      | FHM                          | [51-48] |    y    |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1b4476ddb83..835f8158220e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1484,6 +1484,18 @@ config ARM64_PTR_AUTH
 
 endmenu
 
+menu "ARMv8.5 architectural features"
+
+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.
+
+endmenu
+
 config ARM64_SVE
 	bool "ARM Scalable Vector Extension support"
 	default y
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
new file mode 100644
index 000000000000..364177954bef
--- /dev/null
+++ b/arch/arm64/include/asm/archrandom.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARCHRANDOM_H
+#define _ASM_ARCHRANDOM_H
+
+#ifdef CONFIG_ARCH_RANDOM
+
+#include <linux/random.h>
+#include <asm/cpufeature.h>
+
+static inline bool __arm64_rndr(unsigned long *v)
+{
+	bool ok;
+
+	/*
+	 * Reads of RNDR set PSTATE.NZCV to 0b0000 on success,
+	 * and set PSTATE.NZCV to 0b0100 otherwise.
+	 */
+	asm volatile(
+		__mrs_s("%0", SYS_RNDR_EL0) "\n"
+	"	cset %w1, ne\n"
+	: "=r"(*v), "=r"(ok)
+	:
+	: "cc");
+
+	return ok;
+}
+
+static inline bool __must_check arch_get_random_long(unsigned long *v)
+{
+	return false;
+}
+
+static inline bool __must_check arch_get_random_int(unsigned int *v)
+{
+	return false;
+}
+
+static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
+{
+	/*
+	 * Only support the generic interface after we have detected
+	 * the system wide capability, avoiding complexity with the
+	 * cpufeature code and with potential scheduling between CPUs
+	 * with and without the feature.
+	 */
+	if (!cpus_have_const_cap(ARM64_HAS_RNG))
+		return false;
+
+	return __arm64_rndr(v);
+}
+
+
+static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
+{
+	unsigned long val;
+	bool ok = arch_get_random_seed_long(&val);
+
+	*v = val;
+	return ok;
+}
+
+#else
+
+static inline bool __arm64_rndr(unsigned long *v) { return false; }
+
+#endif /* CONFIG_ARCH_RANDOM */
+#endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index b92683871119..515f4fbcbf91 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -56,7 +56,8 @@
 #define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM	46
 #define ARM64_WORKAROUND_1542419		47
 #define ARM64_WORKAROUND_1319367		48
+#define ARM64_HAS_RNG				49
 
-#define ARM64_NCAPS				49
+#define ARM64_NCAPS				50
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 6e919fafb43d..5e718f279469 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -365,6 +365,9 @@
 #define SYS_CTR_EL0			sys_reg(3, 3, 0, 0, 1)
 #define SYS_DCZID_EL0			sys_reg(3, 3, 0, 0, 7)
 
+#define SYS_RNDR_EL0			sys_reg(3, 3, 2, 4, 0)
+#define SYS_RNDRRS_EL0			sys_reg(3, 3, 2, 4, 1)
+
 #define SYS_PMCR_EL0			sys_reg(3, 3, 9, 12, 0)
 #define SYS_PMCNTENSET_EL0		sys_reg(3, 3, 9, 12, 1)
 #define SYS_PMCNTENCLR_EL0		sys_reg(3, 3, 9, 12, 2)
@@ -539,6 +542,7 @@
 			 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
 
 /* id_aa64isar0 */
+#define ID_AA64ISAR0_RNDR_SHIFT		60
 #define ID_AA64ISAR0_TS_SHIFT		52
 #define ID_AA64ISAR0_FHM_SHIFT		48
 #define ID_AA64ISAR0_DP_SHIFT		44
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 04cf64e9f0c9..0fea85228956 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -119,6 +119,7 @@ static void cpu_enable_cnp(struct arm64_cpu_capabilities const *cap);
  * sync with the documentation of the CPU feature register ABI.
  */
 static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_RNDR_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_TS_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_FHM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_DP_SHIFT, 4, 0),
@@ -1566,6 +1567,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
+#endif
+#ifdef CONFIG_ARCH_RANDOM
+	{
+		.desc = "Random Number Generator",
+		.capability = ARM64_HAS_RNG,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64ISAR0_EL1,
+		.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+		.sign = FTR_UNSIGNED,
+		.min_field_value = 1,
+	},
 #endif
 	{},
 };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch()
  2020-01-07 18:35 [PATCH v8 0/3] ARMv8.5-RNG support Mark Brown
  2020-01-07 18:35 ` [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
@ 2020-01-07 18:35 ` Mark Brown
  2020-01-08 17:20   ` Mark Rutland
  2020-01-07 18:35 ` [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
  2 siblings, 1 reply; 10+ messages in thread
From: Mark Brown @ 2020-01-07 18:35 UTC (permalink / raw
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel

Since the arm64 ARCH_RANDOM implementation is not available until
cpufeature has determined the system capabilities it can't be used by
the generic random code to initialize the entropy pool for early use.
Instead explicitly add some data to the pool from setup_arch() if the
boot CPU supports v8.5-RNG, this is the point recommended by the generic
code.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/include/asm/archrandom.h | 24 ++++++++++++++++++++++++
 arch/arm64/kernel/setup.c           |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 364177954bef..1d9b94fa9c45 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -59,9 +59,33 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
 	return ok;
 }
 
+/*
+ * Our ARCH_RANDOM implementation does not function until relatively
+ * late in the boot when cpufeature has detertmined system
+ * capabilities so the core code can't use arch_get_random*() to
+ * initialize, instead we call this function to inject data from
+ * setup_arch() if the boot CPU supports v8.5-RNG.
+ */
+static inline void arm64_add_early_rndr_entropy(void)
+{
+	unsigned long val;
+	int i;
+
+	/* Open code as we run prior to the first call to cpufeature. */
+	val = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
+	if (!((val >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf))
+		return;
+
+	/* Add multiple values to mirror the generic code. */
+	for (i = 0; i < 16; i++)
+		if (__arm64_rndr(&val))
+			add_device_randomness(&val, sizeof(val));
+}
+
 #else
 
 static inline bool __arm64_rndr(unsigned long *v) { return false; }
+static inline void arm64_add_early_rndr_entropy(void) { }
 
 #endif /* CONFIG_ARCH_RANDOM */
 #endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 56f664561754..170842965a32 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -344,6 +344,8 @@ void __init setup_arch(char **cmdline_p)
 	/* Init percpu seeds for random tags after cpus are set up. */
 	kasan_init_tags();
 
+	arm64_add_early_rndr_entropy();
+
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
 	/*
 	 * Make sure init_thread_info.ttbr0 always generates translation
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed
  2020-01-07 18:35 [PATCH v8 0/3] ARMv8.5-RNG support Mark Brown
  2020-01-07 18:35 ` [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
  2020-01-07 18:35 ` [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
@ 2020-01-07 18:35 ` Mark Brown
  2020-01-08 17:21   ` Mark Rutland
  2020-01-08 17:38   ` Ard Biesheuvel
  2 siblings, 2 replies; 10+ messages in thread
From: Mark Brown @ 2020-01-07 18:35 UTC (permalink / raw
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel

When seeding KALSR on a system where we have architecture level random
number generation make use of that entropy, mixing it in with the seed
passed by the bootloader. Since this is run very early in init before
feature detection is complete we open code rather than use archrandom.h.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/kaslr.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 2a11a962e571..fc38c4c25eb6 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -81,7 +81,8 @@ static __init const u8 *kaslr_get_cmdline(void *fdt)
 u64 __init kaslr_early_init(u64 dt_phys)
 {
 	void *fdt;
-	u64 seed, offset, mask, module_range;
+	u64 seed, offset, mask, module_range, ftr;
+	unsigned long raw;
 	const u8 *cmdline, *str;
 	int size;
 
@@ -120,6 +121,18 @@ u64 __init kaslr_early_init(u64 dt_phys)
 		return 0;
 	}
 
+	/*
+	 * Mix in any entropy obtainable architecturally, open coded
+	 * since this runs extremely early.
+	 */
+	if (IS_ENABLED(CONFIG_ARCH_RANDOM)) {
+		ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
+		if ((ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf) {
+			if (__arm64_rndr(&raw))
+				seed += raw;
+		}
+	}
+
 	if (!seed) {
 		kaslr_status = KASLR_DISABLED_NO_SEED;
 		return 0;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG
  2020-01-07 18:35 ` [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
@ 2020-01-08 17:18   ` Mark Rutland
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2020-01-08 17:18 UTC (permalink / raw
  To: Mark Brown
  Cc: suzuki.poulose, Catalin Marinas, ard.biesheuvel,
	Richard Henderson, Will Deacon, linux-arm-kernel

On Tue, Jan 07, 2020 at 06:35:38PM +0000, Mark Brown wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> Expose the ID_AA64ISAR0.RNDR field to userspace, as the RNG system
> registers are always available at EL0.
> 
> Implement arch_get_random_seed_long using RNDR.  Given that the
> TRNG is likely to be a shared resource between cores, and VMs,
> do not explicitly force re-seeding with RNDRRS.  In order to avoid
> code complexity and potential issues with hetrogenous systems only
> provide values after cpufeature has finalized the system capabilities.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> [Modified to only function after cpufeature has finalized the system
> capabilities and move all the code into the header -- broonie]
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  Documentation/arm64/cpu-feature-registers.rst |  2 +
>  arch/arm64/Kconfig                            | 12 ++++
>  arch/arm64/include/asm/archrandom.h           | 67 +++++++++++++++++++
>  arch/arm64/include/asm/cpucaps.h              |  3 +-
>  arch/arm64/include/asm/sysreg.h               |  4 ++
>  arch/arm64/kernel/cpufeature.c                | 13 ++++
>  6 files changed, 100 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/include/asm/archrandom.h
> 
> diff --git a/Documentation/arm64/cpu-feature-registers.rst b/Documentation/arm64/cpu-feature-registers.rst
> index b6e44884e3ad..ce320785fb0c 100644
> --- a/Documentation/arm64/cpu-feature-registers.rst
> +++ b/Documentation/arm64/cpu-feature-registers.rst
> @@ -117,6 +117,8 @@ infrastructure:
>       +------------------------------+---------+---------+
>       | Name                         |  bits   | visible |
>       +------------------------------+---------+---------+
> +     | RNDR                         | [63-60] |    y    |
> +     +------------------------------+---------+---------+
>       | TS                           | [55-52] |    y    |
>       +------------------------------+---------+---------+
>       | FHM                          | [51-48] |    y    |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b1b4476ddb83..835f8158220e 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1484,6 +1484,18 @@ config ARM64_PTR_AUTH
>  
>  endmenu
>  
> +menu "ARMv8.5 architectural features"
> +
> +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.
> +
> +endmenu
> +
>  config ARM64_SVE
>  	bool "ARM Scalable Vector Extension support"
>  	default y
> diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
> new file mode 100644
> index 000000000000..364177954bef
> --- /dev/null
> +++ b/arch/arm64/include/asm/archrandom.h
> @@ -0,0 +1,67 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_ARCHRANDOM_H
> +#define _ASM_ARCHRANDOM_H
> +
> +#ifdef CONFIG_ARCH_RANDOM
> +
> +#include <linux/random.h>
> +#include <asm/cpufeature.h>
> +
> +static inline bool __arm64_rndr(unsigned long *v)
> +{
> +	bool ok;
> +
> +	/*
> +	 * Reads of RNDR set PSTATE.NZCV to 0b0000 on success,
> +	 * and set PSTATE.NZCV to 0b0100 otherwise.
> +	 */
> +	asm volatile(
> +		__mrs_s("%0", SYS_RNDR_EL0) "\n"
> +	"	cset %w1, ne\n"
> +	: "=r"(*v), "=r"(ok)

Nit: missing spacing here, this last line should be:

	: "=r" (*v), "=r (ok)

Otherwise, the patch looks good to me. With that fixed:

Reviewed-by: Mark Rutland <mark.rutland@arm.com>

Thanks for sorting this out!

Mark.

> +	:
> +	: "cc");
> +
> +	return ok;
> +}
> +
> +static inline bool __must_check arch_get_random_long(unsigned long *v)
> +{
> +	return false;
> +}
> +
> +static inline bool __must_check arch_get_random_int(unsigned int *v)
> +{
> +	return false;
> +}
> +
> +static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
> +{
> +	/*
> +	 * Only support the generic interface after we have detected
> +	 * the system wide capability, avoiding complexity with the
> +	 * cpufeature code and with potential scheduling between CPUs
> +	 * with and without the feature.
> +	 */
> +	if (!cpus_have_const_cap(ARM64_HAS_RNG))
> +		return false;
> +
> +	return __arm64_rndr(v);
> +}
> +
> +
> +static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
> +{
> +	unsigned long val;
> +	bool ok = arch_get_random_seed_long(&val);
> +
> +	*v = val;
> +	return ok;
> +}
> +
> +#else
> +
> +static inline bool __arm64_rndr(unsigned long *v) { return false; }
> +
> +#endif /* CONFIG_ARCH_RANDOM */
> +#endif /* _ASM_ARCHRANDOM_H */
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index b92683871119..515f4fbcbf91 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -56,7 +56,8 @@
>  #define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM	46
>  #define ARM64_WORKAROUND_1542419		47
>  #define ARM64_WORKAROUND_1319367		48
> +#define ARM64_HAS_RNG				49
>  
> -#define ARM64_NCAPS				49
> +#define ARM64_NCAPS				50
>  
>  #endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 6e919fafb43d..5e718f279469 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -365,6 +365,9 @@
>  #define SYS_CTR_EL0			sys_reg(3, 3, 0, 0, 1)
>  #define SYS_DCZID_EL0			sys_reg(3, 3, 0, 0, 7)
>  
> +#define SYS_RNDR_EL0			sys_reg(3, 3, 2, 4, 0)
> +#define SYS_RNDRRS_EL0			sys_reg(3, 3, 2, 4, 1)
> +
>  #define SYS_PMCR_EL0			sys_reg(3, 3, 9, 12, 0)
>  #define SYS_PMCNTENSET_EL0		sys_reg(3, 3, 9, 12, 1)
>  #define SYS_PMCNTENCLR_EL0		sys_reg(3, 3, 9, 12, 2)
> @@ -539,6 +542,7 @@
>  			 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
>  
>  /* id_aa64isar0 */
> +#define ID_AA64ISAR0_RNDR_SHIFT		60
>  #define ID_AA64ISAR0_TS_SHIFT		52
>  #define ID_AA64ISAR0_FHM_SHIFT		48
>  #define ID_AA64ISAR0_DP_SHIFT		44
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 04cf64e9f0c9..0fea85228956 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -119,6 +119,7 @@ static void cpu_enable_cnp(struct arm64_cpu_capabilities const *cap);
>   * sync with the documentation of the CPU feature register ABI.
>   */
>  static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
> +	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_RNDR_SHIFT, 4, 0),
>  	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_TS_SHIFT, 4, 0),
>  	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_FHM_SHIFT, 4, 0),
>  	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_DP_SHIFT, 4, 0),
> @@ -1566,6 +1567,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.sign = FTR_UNSIGNED,
>  		.min_field_value = 1,
>  	},
> +#endif
> +#ifdef CONFIG_ARCH_RANDOM
> +	{
> +		.desc = "Random Number Generator",
> +		.capability = ARM64_HAS_RNG,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.matches = has_cpuid_feature,
> +		.sys_reg = SYS_ID_AA64ISAR0_EL1,
> +		.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
> +		.sign = FTR_UNSIGNED,
> +		.min_field_value = 1,
> +	},
>  #endif
>  	{},
>  };
> -- 
> 2.20.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch()
  2020-01-07 18:35 ` [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
@ 2020-01-08 17:20   ` Mark Rutland
  2020-01-08 17:36     ` Mark Brown
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2020-01-08 17:20 UTC (permalink / raw
  To: Mark Brown
  Cc: suzuki.poulose, Catalin Marinas, ard.biesheuvel,
	Richard Henderson, Will Deacon, linux-arm-kernel

On Tue, Jan 07, 2020 at 06:35:39PM +0000, Mark Brown wrote:
> Since the arm64 ARCH_RANDOM implementation is not available until
> cpufeature has determined the system capabilities it can't be used by
> the generic random code to initialize the entropy pool for early use.
> Instead explicitly add some data to the pool from setup_arch() if the
> boot CPU supports v8.5-RNG, this is the point recommended by the generic
> code.

This structure looks good to me.

> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  arch/arm64/include/asm/archrandom.h | 24 ++++++++++++++++++++++++
>  arch/arm64/kernel/setup.c           |  2 ++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
> index 364177954bef..1d9b94fa9c45 100644
> --- a/arch/arm64/include/asm/archrandom.h
> +++ b/arch/arm64/include/asm/archrandom.h
> @@ -59,9 +59,33 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
>  	return ok;
>  }
>  
> +/*
> + * Our ARCH_RANDOM implementation does not function until relatively
> + * late in the boot when cpufeature has detertmined system
> + * capabilities so the core code can't use arch_get_random*() to
> + * initialize, instead we call this function to inject data from
> + * setup_arch() if the boot CPU supports v8.5-RNG.
> + */
> +static inline void arm64_add_early_rndr_entropy(void)

Can we mark this as __init so that people aren't tempted to use it at
runtime? I realsie it's inline, but it's at least something sparse can
check.

> +{
> +	unsigned long val;
> +	int i;
> +
> +	/* Open code as we run prior to the first call to cpufeature. */
> +	val = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
> +	if (!((val >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf))
> +		return;
> +
> +	/* Add multiple values to mirror the generic code. */
> +	for (i = 0; i < 16; i++)
> +		if (__arm64_rndr(&val))
> +			add_device_randomness(&val, sizeof(val));
> +}

Given the next patch also needs to check the I reckon it is worth
factoring the ID register check into a helper:

/* Used on the boot CPU before the CPU feature framework is up */
static inline bool __init __early_cpu_has_rndr(void)
{
	unsigned long ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
	return (ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf;
}

> +
>  #else
>  
>  static inline bool __arm64_rndr(unsigned long *v) { return false; }
> +static inline void arm64_add_early_rndr_entropy(void) { }

... with a stub here:

static inline bool __init __early_cpu_has_rndr(void) { return false; }

... so the KASLR code can just check __early_cpu_has_rndr().

Thanks,
Mark.

>  
>  #endif /* CONFIG_ARCH_RANDOM */
>  #endif /* _ASM_ARCHRANDOM_H */
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 56f664561754..170842965a32 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -344,6 +344,8 @@ void __init setup_arch(char **cmdline_p)
>  	/* Init percpu seeds for random tags after cpus are set up. */
>  	kasan_init_tags();
>  
> +	arm64_add_early_rndr_entropy();
> +
>  #ifdef CONFIG_ARM64_SW_TTBR0_PAN
>  	/*
>  	 * Make sure init_thread_info.ttbr0 always generates translation
> -- 
> 2.20.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed
  2020-01-07 18:35 ` [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
@ 2020-01-08 17:21   ` Mark Rutland
  2020-01-08 17:38   ` Ard Biesheuvel
  1 sibling, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2020-01-08 17:21 UTC (permalink / raw
  To: Mark Brown
  Cc: suzuki.poulose, Catalin Marinas, ard.biesheuvel,
	Richard Henderson, Will Deacon, linux-arm-kernel

On Tue, Jan 07, 2020 at 06:35:40PM +0000, Mark Brown wrote:
> When seeding KALSR on a system where we have architecture level random
> number generation make use of that entropy, mixing it in with the seed
> passed by the bootloader. Since this is run very early in init before
> feature detection is complete we open code rather than use archrandom.h.
> 
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  arch/arm64/kernel/kaslr.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
> index 2a11a962e571..fc38c4c25eb6 100644
> --- a/arch/arm64/kernel/kaslr.c
> +++ b/arch/arm64/kernel/kaslr.c
> @@ -81,7 +81,8 @@ static __init const u8 *kaslr_get_cmdline(void *fdt)
>  u64 __init kaslr_early_init(u64 dt_phys)
>  {
>  	void *fdt;
> -	u64 seed, offset, mask, module_range;
> +	u64 seed, offset, mask, module_range, ftr;
> +	unsigned long raw;
>  	const u8 *cmdline, *str;
>  	int size;
>  
> @@ -120,6 +121,18 @@ u64 __init kaslr_early_init(u64 dt_phys)
>  		return 0;
>  	}
>  
> +	/*
> +	 * Mix in any entropy obtainable architecturally, open coded
> +	 * since this runs extremely early.
> +	 */
> +	if (IS_ENABLED(CONFIG_ARCH_RANDOM)) {
> +		ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
> +		if ((ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf) {
> +			if (__arm64_rndr(&raw))
> +				seed += raw;
> +		}
> +	}

This looks good. If we add the helper I suggest in patch 2, we can
reduce this down to:

	/* Mix in any entropy obtainable architecturally */
	if (__early_cpu_has_rndr()) {
		unsigned long raw;
		if (__arm64_rndr(&raw))
			seed += raw;
	}

... which keeps all the RNG bits in one place.

Thanks,
Mark.

> +
>  	if (!seed) {
>  		kaslr_status = KASLR_DISABLED_NO_SEED;
>  		return 0;
> -- 
> 2.20.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch()
  2020-01-08 17:20   ` Mark Rutland
@ 2020-01-08 17:36     ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2020-01-08 17:36 UTC (permalink / raw
  To: Mark Rutland
  Cc: suzuki.poulose, Catalin Marinas, ard.biesheuvel,
	Richard Henderson, Will Deacon, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 879 bytes --]

On Wed, Jan 08, 2020 at 05:20:41PM +0000, Mark Rutland wrote:
> On Tue, Jan 07, 2020 at 06:35:39PM +0000, Mark Brown wrote:

> > +	/* Add multiple values to mirror the generic code. */
> > +	for (i = 0; i < 16; i++)
> > +		if (__arm64_rndr(&val))
> > +			add_device_randomness(&val, sizeof(val));
> > +}

> Given the next patch also needs to check the I reckon it is worth
> factoring the ID register check into a helper:

> /* Used on the boot CPU before the CPU feature framework is up */
> static inline bool __init __early_cpu_has_rndr(void)
> {
> 	unsigned long ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
> 	return (ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf;
> }

There was also some suggestion about making a generic helper that takes
the register and bitfield to look at.

At some point I do also start to question if we're really winning with
all this stuff static inline...

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed
  2020-01-07 18:35 ` [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
  2020-01-08 17:21   ` Mark Rutland
@ 2020-01-08 17:38   ` Ard Biesheuvel
  2020-01-08 17:44     ` Mark Brown
  1 sibling, 1 reply; 10+ messages in thread
From: Ard Biesheuvel @ 2020-01-08 17:38 UTC (permalink / raw
  To: Mark Brown
  Cc: Mark Rutland, Catalin Marinas, Richard Henderson, Will Deacon,
	linux-arm-kernel

On Tue, 7 Jan 2020 at 19:38, Mark Brown <broonie@kernel.org> wrote:
>
> When seeding KALSR on a system where we have architecture level random
> number generation make use of that entropy, mixing it in with the seed
> passed by the bootloader. Since this is run very early in init before
> feature detection is complete we open code rather than use archrandom.h.
>
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  arch/arm64/kernel/kaslr.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
> index 2a11a962e571..fc38c4c25eb6 100644
> --- a/arch/arm64/kernel/kaslr.c
> +++ b/arch/arm64/kernel/kaslr.c
> @@ -81,7 +81,8 @@ static __init const u8 *kaslr_get_cmdline(void *fdt)
>  u64 __init kaslr_early_init(u64 dt_phys)
>  {
>         void *fdt;
> -       u64 seed, offset, mask, module_range;
> +       u64 seed, offset, mask, module_range, ftr;
> +       unsigned long raw;
>         const u8 *cmdline, *str;
>         int size;
>
> @@ -120,6 +121,18 @@ u64 __init kaslr_early_init(u64 dt_phys)
>                 return 0;
>         }
>
> +       /*
> +        * Mix in any entropy obtainable architecturally, open coded
> +        * since this runs extremely early.
> +        */
> +       if (IS_ENABLED(CONFIG_ARCH_RANDOM)) {
> +               ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
> +               if ((ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf) {
> +                       if (__arm64_rndr(&raw))
> +                               seed += raw;

Using addition rather than xor to combine seeds is slightly
unidiomatic, so if you are doing this for a specific reason, it would
be good to mention it.

On a system that implements these instructions, the existing seed is
likely to come from the same source, but the ZF flag should catch any
cases where the output is stale (which unfortunately is a thing that
the spec does not ban). So using add instead of xor to mitigate
against correlated seeds seems both unnecessary and insufficient at
the same time, if that was the intention.


> +               }
> +       }
> +
>         if (!seed) {
>                 kaslr_status = KASLR_DISABLED_NO_SEED;
>                 return 0;
> --
> 2.20.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed
  2020-01-08 17:38   ` Ard Biesheuvel
@ 2020-01-08 17:44     ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2020-01-08 17:44 UTC (permalink / raw
  To: Ard Biesheuvel
  Cc: Mark Rutland, Catalin Marinas, Richard Henderson, Will Deacon,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 485 bytes --]

On Wed, Jan 08, 2020 at 06:38:48PM +0100, Ard Biesheuvel wrote:
> On Tue, 7 Jan 2020 at 19:38, Mark Brown <broonie@kernel.org> wrote:

> > +               if ((ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf) {
> > +                       if (__arm64_rndr(&raw))
> > +                               seed += raw;

> Using addition rather than xor to combine seeds is slightly
> unidiomatic, so if you are doing this for a specific reason, it would
> be good to mention it.

No particular reason.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-01-08 17:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-07 18:35 [PATCH v8 0/3] ARMv8.5-RNG support Mark Brown
2020-01-07 18:35 ` [PATCH v8 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
2020-01-08 17:18   ` Mark Rutland
2020-01-07 18:35 ` [PATCH v8 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
2020-01-08 17:20   ` Mark Rutland
2020-01-08 17:36     ` Mark Brown
2020-01-07 18:35 ` [PATCH v8 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
2020-01-08 17:21   ` Mark Rutland
2020-01-08 17:38   ` Ard Biesheuvel
2020-01-08 17:44     ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.