From: Mark Rutland <mark.rutland@arm.com>
To: Richard Henderson <richard.henderson@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org,
linux-crypto@vger.kernel.org, ard.biesheuvel@linaro.org
Subject: Re: [PATCH v5] arm64: Implement archrandom.h for ARMv8.5-RNG
Date: Fri, 8 Nov 2019 14:30:26 +0000 [thread overview]
Message-ID: <20191108143025.GD11465@lakrids.cambridge.arm.com> (raw)
In-Reply-To: <20191108135751.3218-1-rth@twiddle.net>
On Fri, Nov 08, 2019 at 02:57:51PM +0100, Richard Henderson 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.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> v2: Use __mrs_s and fix missing cc clobber (Mark),
> Log rng failures with pr_warn (Mark),
When I suggested this, I meant in the probe path.
Since it can legitimately fail at runtime, I don't think it's worth
logging there. Maybe it's worth recording stats, but the generic wrapper
could do that.
[...]
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 80f459ad0190..456d5c461cbf 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),
If we're going to expose this to userspace, it must be a system feature.
If all the boto CPUs have the feature, we'll advertise it to userspace,
and therefore must mandate it for late-onlined CPUs.
> 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),
> @@ -1565,6 +1566,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_WEAK_LOCAL_CPU_FEATURE,
As above, if we're advertisting this to userspace and/or VMs, this must
be a system-wide feature, and cannot be a weak local 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
> {},
> };
> diff --git a/arch/arm64/kernel/random.c b/arch/arm64/kernel/random.c
> new file mode 100644
> index 000000000000..e7ff29dd637c
> --- /dev/null
> +++ b/arch/arm64/kernel/random.c
> @@ -0,0 +1,82 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Random number generation using ARMv8.5-RNG.
> + */
> +
> +#include <linux/random.h>
> +#include <linux/ratelimit.h>
> +#include <linux/printk.h>
> +#include <linux/preempt.h>
> +#include <asm/cpufeature.h>
> +
> +static inline bool has_random(void)
> +{
> + /*
> + * We "have" RNG if either
> + * (1) every cpu in the system has RNG, or
> + * (2) in a non-preemptible context, current cpu has RNG.
> + *
> + * Case 1 is the expected case when RNG is deployed, but
> + * case 2 is present as a backup. Case 2 has two effects:
> + * (A) rand_initialize() is able to use the instructions
> + * when present in the boot cpu, which happens before
> + * secondary cpus are enabled and before features are
> + * resolved for the full system.
> + * (B) add_interrupt_randomness() is able to use the
> + * instructions when present on the current cpu, in case
> + * some big/little system only has RNG on big cpus.
> + *
> + * We can use __cpus_have_const_cap because we then fall
> + * back to checking the current cpu.
> + */
> + return __cpus_have_const_cap(ARM64_HAS_RNG) ||
> + (!preemptible() && this_cpu_has_cap(ARM64_HAS_RNG));
> +}
We don't bother with special-casing local handling mismatch like this
for other features. I'd ratehr that:
* On the boot CPU, prior to detecting secondaries, we can seed the usual
pool with the RNG if the boot CPU has it.
* Once secondaries are up, if the feature is present system-wide, we can
make use of the feature as a system-wide feature. If not, we don't use
the RNG.
[...]
> +bool arch_get_random_long(unsigned long *v)
> +{
> + bool ok;
> +
> + if (!has_random())
> + return false;
> +
> + /*
> + * 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: place a space between the constraint and the bracketed variable, as
we do elsewhere.
> + :
> + : "cc");
> +
> + if (unlikely(!ok))
> + pr_warn_ratelimited("cpu%d: sys_rndr failed\n",
> + read_cpuid_id());
> + return ok;
> +}
... so this can be:
bool arch_get_random_long(unsigned long *v)
{
bool ok;
if (!cpus_have_const_cap(ARM64_HAS_RNG))
return false;
/*
* 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;
}
...with similar for arch_get_random_seed_long().
[...]
> config RANDOM_TRUST_CPU
> bool "Trust the CPU manufacturer to initialize Linux's CRNG"
> - depends on X86 || S390 || PPC
> + depends on X86 || S390 || PPC || ARM64
Can't that depend on ARCH_RANDOM instead?
Thanks,
Mark.
next prev parent reply other threads:[~2019-11-08 14:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-08 13:57 [PATCH v5] arm64: Implement archrandom.h for ARMv8.5-RNG Richard Henderson
2019-11-08 14:30 ` Mark Rutland [this message]
2019-11-09 9:04 ` Richard Henderson
2019-11-12 9:52 ` Mark Rutland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191108143025.GD11465@lakrids.cambridge.arm.com \
--to=mark.rutland@arm.com \
--cc=ard.biesheuvel@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-crypto@vger.kernel.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).