diff mbox series

[v10,1/3] arm64: Implement archrandom.h for ARMv8.5-RNG

Message ID 20200110122341.8445-2-broonie@kernel.org (mailing list archive)
State New, archived
Headers show
Series ARMv8.5-RNG support | expand

Commit Message

Mark Brown Jan. 10, 2020, 12:23 p.m. UTC
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>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
---
 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

Comments

Will Deacon Jan. 14, 2020, 5:44 p.m. UTC | #1
On Fri, Jan 10, 2020 at 12:23:39PM +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>
> Reviewed-by: Mark Rutland <mark.rutland@arm.com>
> ---
>  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

In which case, should we also add an HWCAP for this?

Will
Ard Biesheuvel Jan. 15, 2020, 7:40 a.m. UTC | #2
On Tue, 14 Jan 2020 at 18:44, Will Deacon <will@kernel.org> wrote:
>
> On Fri, Jan 10, 2020 at 12:23:39PM +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>
> > Reviewed-by: Mark Rutland <mark.rutland@arm.com>
> > ---
> >  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
>
> In which case, should we also add an HWCAP for this?
>

Isn't this covered by the 'cpuid' HWCAP? We can't prevent EL0 from
accessing these system registers anyway, even if we wanted to.
Will Deacon Jan. 15, 2020, 9:16 a.m. UTC | #3
On Wed, Jan 15, 2020 at 08:40:46AM +0100, Ard Biesheuvel wrote:
> On Tue, 14 Jan 2020 at 18:44, Will Deacon <will@kernel.org> wrote:
> >
> > On Fri, Jan 10, 2020 at 12:23:39PM +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>
> > > Reviewed-by: Mark Rutland <mark.rutland@arm.com>
> > > ---
> > >  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
> >
> > In which case, should we also add an HWCAP for this?
> >
> 
> Isn't this covered by the 'cpuid' HWCAP? We can't prevent EL0 from
> accessing these system registers anyway, even if we wanted to.

I see your argument, but I was just going on the side of consistency because
we're continuing to expose other features as HWCAPs when the capability is
just a proxy for the cpuid field. I was in favour of stopping the addition
of such HWCAPs years ago, but I couldn't convince Catalin ;)

The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
our hand forced.

Will
Ard Biesheuvel Jan. 15, 2020, 9:24 a.m. UTC | #4
On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:
>
> On Wed, Jan 15, 2020 at 08:40:46AM +0100, Ard Biesheuvel wrote:
> > On Tue, 14 Jan 2020 at 18:44, Will Deacon <will@kernel.org> wrote:
> > >
> > > On Fri, Jan 10, 2020 at 12:23:39PM +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>
> > > > Reviewed-by: Mark Rutland <mark.rutland@arm.com>
> > > > ---
> > > >  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
> > >
> > > In which case, should we also add an HWCAP for this?
> > >
> >
> > Isn't this covered by the 'cpuid' HWCAP? We can't prevent EL0 from
> > accessing these system registers anyway, even if we wanted to.
>
> I see your argument, but I was just going on the side of consistency because
> we're continuing to expose other features as HWCAPs when the capability is
> just a proxy for the cpuid field. I was in favour of stopping the addition
> of such HWCAPs years ago, but I couldn't convince Catalin ;)
>
> The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
> our hand forced.
>

I don't have a strong opinion either way.
Mark Brown Jan. 15, 2020, 11:07 a.m. UTC | #5
On Wed, Jan 15, 2020 at 10:24:21AM +0100, Ard Biesheuvel wrote:
> On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:

> > I see your argument, but I was just going on the side of consistency because
> > we're continuing to expose other features as HWCAPs when the capability is
> > just a proxy for the cpuid field. I was in favour of stopping the addition
> > of such HWCAPs years ago, but I couldn't convince Catalin ;)

> > The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
> > our hand forced.

> I don't have a strong opinion either way.

Me either, or at least not enough to object to doing it - Will?
Catalin?
Will Deacon Jan. 15, 2020, 11:16 a.m. UTC | #6
On Wed, Jan 15, 2020 at 11:07:20AM +0000, Mark Brown wrote:
> On Wed, Jan 15, 2020 at 10:24:21AM +0100, Ard Biesheuvel wrote:
> > On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:
> 
> > > I see your argument, but I was just going on the side of consistency because
> > > we're continuing to expose other features as HWCAPs when the capability is
> > > just a proxy for the cpuid field. I was in favour of stopping the addition
> > > of such HWCAPs years ago, but I couldn't convince Catalin ;)
> 
> > > The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
> > > our hand forced.
> 
> > I don't have a strong opinion either way.
> 
> Me either, or at least not enough to object to doing it - Will?
> Catalin?

Unless we all agree to stop adding new HWCAPs, then I think you may as well
add a new one here (i.e. I don't think this discussion should derail your
work).

Will
Catalin Marinas Jan. 15, 2020, 2:26 p.m. UTC | #7
On Wed, Jan 15, 2020 at 11:07:20AM +0000, Mark Brown wrote:
> On Wed, Jan 15, 2020 at 10:24:21AM +0100, Ard Biesheuvel wrote:
> > On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:
> 
> > > I see your argument, but I was just going on the side of consistency because
> > > we're continuing to expose other features as HWCAPs when the capability is
> > > just a proxy for the cpuid field. I was in favour of stopping the addition
> > > of such HWCAPs years ago, but I couldn't convince Catalin ;)
> 
> > > The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
> > > our hand forced.
> 
> > I don't have a strong opinion either way.
> 
> Me either, or at least not enough to object to doing it - Will?
> Catalin?

Until the ifunc resolver can work with CPUID, I think we should keep
adding HWCAPn bits. We can revisit this with the toolchain people before
introducing HWCAP3.
Richard Henderson Jan. 16, 2020, 12:23 a.m. UTC | #8
On 1/15/20 4:26 AM, Catalin Marinas wrote:
> On Wed, Jan 15, 2020 at 11:07:20AM +0000, Mark Brown wrote:
>> On Wed, Jan 15, 2020 at 10:24:21AM +0100, Ard Biesheuvel wrote:
>>> On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:
>>
>>>> I see your argument, but I was just going on the side of consistency because
>>>> we're continuing to expose other features as HWCAPs when the capability is
>>>> just a proxy for the cpuid field. I was in favour of stopping the addition
>>>> of such HWCAPs years ago, but I couldn't convince Catalin ;)
>>
>>>> The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
>>>> our hand forced.
>>
>>> I don't have a strong opinion either way.
>>
>> Me either, or at least not enough to object to doing it - Will?
>> Catalin?
> 
> Until the ifunc resolver can work with CPUID, I think we should keep
> adding HWCAPn bits. We can revisit this with the toolchain people before
> introducing HWCAP3.

Why would the ifunc resolver not be able to use HWCAP_CPUID?

The first argument to the ifunc resolver, apparently since the beginning of
time (2013-11-25 7520ff8c744a), AT_HWCAP has been passed directly as the first
argument.

That means HWCAP_CPUID, present in AT_HWCAP, can always be tested directly.  At
which point one can access architected registers, with no dynamic linker
relocations, to make further decisions.  Admittedly there's a trap to the OS
involved, but there is *far* too much info in those registers to copy
everything to HWCAPn.

The current state of affairs, as of glibc-2.30, is that the first argument is
augmented to include a _IFUNC_ARG_HWCAP bit, which indicates the presence of a
second argument, a pointer to struct __ifunc_arg_t.  This struct does include a
size field, allowing the struct to be extended in future.

That said, speaking as a toolchain guy, you should conserve HWCAP2 bits so
that, by preference, you do not need to introduce AT_HWCAP3.  Or at least delay
adding it.


r~
Catalin Marinas Jan. 16, 2020, 11:02 a.m. UTC | #9
On Wed, Jan 15, 2020 at 02:23:39PM -1000, Richard Henderson wrote:
> On 1/15/20 4:26 AM, Catalin Marinas wrote:
> > On Wed, Jan 15, 2020 at 11:07:20AM +0000, Mark Brown wrote:
> >> On Wed, Jan 15, 2020 at 10:24:21AM +0100, Ard Biesheuvel wrote:
> >>> On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:
> >>
> >>>> I see your argument, but I was just going on the side of consistency because
> >>>> we're continuing to expose other features as HWCAPs when the capability is
> >>>> just a proxy for the cpuid field. I was in favour of stopping the addition
> >>>> of such HWCAPs years ago, but I couldn't convince Catalin ;)
> >>
> >>>> The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
> >>>> our hand forced.
> >>
> >>> I don't have a strong opinion either way.
> >>
> >> Me either, or at least not enough to object to doing it - Will?
> >> Catalin?
> > 
> > Until the ifunc resolver can work with CPUID, I think we should keep
> > adding HWCAPn bits. We can revisit this with the toolchain people before
> > introducing HWCAP3.
> 
> Why would the ifunc resolver not be able to use HWCAP_CPUID?

It can indeed check the HWCAP_CPUID but I haven't seen any plans to
implement the next part, actual use of an MRS instruction to read the
corresponding ID_AA64* regs. This MRS emulation was requested by (some
of) the toolchain people, even the architecture gained a feature to
simplify the emulation, but followed by complete silence from the
toolchain folk.

> That said, speaking as a toolchain guy, you should conserve HWCAP2 bits so
> that, by preference, you do not need to introduce AT_HWCAP3.  Or at least delay
> adding it.

We still have some time before AT_HWCAP3. Also, we have 32-bit spare in
both HWCAP and HWCAP2 which we can use. IIRC we didn't go into the top
32-bit of HWCAP because we were still debating whether ILP32 makes
sense (and now I'm 100% convinced it doesn't ;)).
Ard Biesheuvel Jan. 16, 2020, 11:10 a.m. UTC | #10
On Thu, 16 Jan 2020 at 12:02, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Wed, Jan 15, 2020 at 02:23:39PM -1000, Richard Henderson wrote:
> > On 1/15/20 4:26 AM, Catalin Marinas wrote:
> > > On Wed, Jan 15, 2020 at 11:07:20AM +0000, Mark Brown wrote:
> > >> On Wed, Jan 15, 2020 at 10:24:21AM +0100, Ard Biesheuvel wrote:
> > >>> On Wed, 15 Jan 2020 at 10:16, Will Deacon <will@kernel.org> wrote:
> > >>
> > >>>> I see your argument, but I was just going on the side of consistency because
> > >>>> we're continuing to expose other features as HWCAPs when the capability is
> > >>>> just a proxy for the cpuid field. I was in favour of stopping the addition
> > >>>> of such HWCAPs years ago, but I couldn't convince Catalin ;)
> > >>
> > >>>> The way I see it, we'll soon run out of HWCAP2 bits and then we'll have
> > >>>> our hand forced.
> > >>
> > >>> I don't have a strong opinion either way.
> > >>
> > >> Me either, or at least not enough to object to doing it - Will?
> > >> Catalin?
> > >
> > > Until the ifunc resolver can work with CPUID, I think we should keep
> > > adding HWCAPn bits. We can revisit this with the toolchain people before
> > > introducing HWCAP3.
> >
> > Why would the ifunc resolver not be able to use HWCAP_CPUID?
>
> It can indeed check the HWCAP_CPUID but I haven't seen any plans to
> implement the next part, actual use of an MRS instruction to read the
> corresponding ID_AA64* regs. This MRS emulation was requested by (some
> of) the toolchain people, even the architecture gained a feature to
> simplify the emulation, but followed by complete silence from the
> toolchain folk.
>

But what infrastructure would the toolchain folks need to provide
here? An ifunc resolver would simply do

void generic_func(...);
void foo_func(...);

void *resolve_foo(long hwcap)
{
   if (hwcap & HWCAP_CPUID) {
       long l;
       asm ("mrs %1, ID_AA64_...") : "=r"(l));
       if (l has 'foo')
         return foo_func;
   }
   return generic_func;
}

so all that is needed for using ID registers to do ifunc resolution is
already there.


> > That said, speaking as a toolchain guy, you should conserve HWCAP2 bits so
> > that, by preference, you do not need to introduce AT_HWCAP3.  Or at least delay
> > adding it.
>
> We still have some time before AT_HWCAP3. Also, we have 32-bit spare in
> both HWCAP and HWCAP2 which we can use. IIRC we didn't go into the top
> 32-bit of HWCAP because we were still debating whether ILP32 makes
> sense (and now I'm 100% convinced it doesn't ;)).
>
> --
> Catalin
Catalin Marinas Jan. 16, 2020, 11:40 a.m. UTC | #11
On Thu, Jan 16, 2020 at 12:10:28PM +0100, Ard Biesheuvel wrote:
> On Thu, 16 Jan 2020 at 12:02, Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Wed, Jan 15, 2020 at 02:23:39PM -1000, Richard Henderson wrote:
> > > On 1/15/20 4:26 AM, Catalin Marinas wrote:
> > > > Until the ifunc resolver can work with CPUID, I think we should keep
> > > > adding HWCAPn bits. We can revisit this with the toolchain people before
> > > > introducing HWCAP3.
> > >
> > > Why would the ifunc resolver not be able to use HWCAP_CPUID?
> >
> > It can indeed check the HWCAP_CPUID but I haven't seen any plans to
> > implement the next part, actual use of an MRS instruction to read the
> > corresponding ID_AA64* regs. This MRS emulation was requested by (some
> > of) the toolchain people, even the architecture gained a feature to
> > simplify the emulation, but followed by complete silence from the
> > toolchain folk.
> 
> But what infrastructure would the toolchain folks need to provide
> here? An ifunc resolver would simply do
> 
> void generic_func(...);
> void foo_func(...);
> 
> void *resolve_foo(long hwcap)
> {
>    if (hwcap & HWCAP_CPUID) {
>        long l;
>        asm ("mrs %1, ID_AA64_...") : "=r"(l));
>        if (l has 'foo')
>          return foo_func;
>    }
>    return generic_func;
> }
> 
> so all that is needed for using ID registers to do ifunc resolution is
> already there.

If you write the resolver yourself, it should work. I was thinking of
function multiversioning (which I thought using ifunc behind the scenes)
but I'm not sure what the aarch64 support level is (in gcc or clang).

Anyway, I'm not aware of anyone using the MRS emulation (maybe they do
and I haven't heard). I guess it doesn't help that we keep adding HWCAP
bits ;).
diff mbox series

Patch

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..5ea5a1ce5a5f
--- /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
 	{},
 };