Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp2587759ybx; Fri, 8 Nov 2019 06:30:59 -0800 (PST) X-Google-Smtp-Source: APXvYqztdvEZpR8AowOGzvRUiB+pV3FfgeKnjLsFB68D6REQFGI4Of71qo0YfgfEleOG9a6Yq0it X-Received: by 2002:a50:fa83:: with SMTP id w3mr10355778edr.272.1573223459157; Fri, 08 Nov 2019 06:30:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573223459; cv=none; d=google.com; s=arc-20160816; b=WGfvfFvrAxMmqkDWC6odtQRTl4WMZuIuIDKxbaHDPFDi7jafE+GLK8DiiTBlNYiHJM aL3RQOcy/NUsdMyZyH/J1QmBLCwU2bLo0UJ3Xw9cpPew5qBj7Y1H/4FwMSWgH3OQD2Om SFI6km5FWPe+m4mzJQQHTYSACCYdQ98laV6WqfSFlmnAo5/keVBmfMMLgB1UQvRojhyI BrcCZOWLUatepUd0MPf6jia6kw6trRLnkuh+pVbphch2Epw2rj3/cdnxBLtb0dE3+rd2 ZZhvU8+HAnJkeAhNYNDVBAA/RrKE8FuzObVRAinqUTQrBL+UjQmDahpNUPNLNx4QSY7W xkOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=7vrlOol8fjOA21sGJU4j7feWykTfO9Gtd8cLp+9WnuQ=; b=gVeX9WGIOqBoM/SFjluLttJj+vyFvZr0Na2wM0Yh4itSkr7s0qfIQAmoGPYHmMvOHj I/UqNcNe//Uz1KqmoL8SYF0XGLy084MhjH1Sw/WIaXT73Jtb/jELJUKuYDUAj+th0awI Q4W/J9G5vZVS1KaX3ciJYs9KJjPTj/mKLNoQRBiS8QPd+N4ZntkWyyGton1b7rjcPEWr Nt4gKAA4yKebudnMkQGtGVMpXCPkmEpIA0V8QHh2HPo4gk5U+EtOH8/2t1gkQUZccdyN ZOv+ryM5zUuXk5SzHnGYB301aPMDMP5t7+80yPlnwe4aG5xB+tFlANuFkPA89DaMospy Tjxg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r17si4446494edx.257.2019.11.08.06.30.34; Fri, 08 Nov 2019 06:30:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726129AbfKHOaa (ORCPT + 99 others); Fri, 8 Nov 2019 09:30:30 -0500 Received: from foss.arm.com ([217.140.110.172]:44316 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726036AbfKHOa3 (ORCPT ); Fri, 8 Nov 2019 09:30:29 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0EE0D46A; Fri, 8 Nov 2019 06:30:29 -0800 (PST) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5C4DE3F719; Fri, 8 Nov 2019 06:30:28 -0800 (PST) Date: Fri, 8 Nov 2019 14:30:26 +0000 From: Mark Rutland To: Richard Henderson 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 Message-ID: <20191108143025.GD11465@lakrids.cambridge.arm.com> References: <20191108135751.3218-1-rth@twiddle.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191108135751.3218-1-rth@twiddle.net> User-Agent: Mutt/1.11.1+11 (2f07cb52) (2018-12-01) Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org On Fri, Nov 08, 2019 at 02:57:51PM +0100, Richard Henderson wrote: > From: Richard Henderson > > Expose the ID_AA64ISAR0.RNDR field to userspace, as the > RNG system registers are always available at EL0. > > Signed-off-by: Richard Henderson > --- > 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 > +#include > +#include > +#include > +#include > + > +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.