Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp462194pxb; Thu, 5 Nov 2020 04:59:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJxz4hovwoTnoEW+aIjjrPUeEfvjTtPcc1+WS3TElAe7stwzp+kyYDarK7+ESbkKgamRNJyx X-Received: by 2002:a05:6402:4cb:: with SMTP id n11mr2407217edw.296.1604581180096; Thu, 05 Nov 2020 04:59:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604581180; cv=none; d=google.com; s=arc-20160816; b=R4G03jebCORqOdHS+sBNj2ezcJebUZveXW88CbWEp05srMioSQDj/5/6VeA2CK12qs BKf3Faga6UvqFFmGrlH288CnJDW870dXCb2n6Btwe/hxhsRc5SkBJjAytzCWr7YFE8zb Fx9LkNG/FPP6S+Dy6YFiFi4p4GCbQMzfHhR5K7AjeDdH+B6ux83QvInFjcGOwIlUO062 iKYhWODK17MgzXzHYibmJC+gPPJ5EyLeRvG2IiFwqxqfnOC+dzZIqhDq0lPWI+K54x0o 1EgYRhV5cWhdvTIR24zXHrXlRxtBZ319V257sPxq+ovXWp9vZvBiibOg/fBlViq6Hr3f 9XVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from; bh=nFwd7L8b2ME99M/x8bTNj2cAnKJ4Gc60X1NIwwGNcWo=; b=N4TkjbSxe8YVnNmYpJoiTOEDeUm6huGq2YGho52r3ygTIz1w+TpfmeM0qy+5C4MPdo /2lSmInc/KScloaAm4MvlYNNTv9rZd8an8nc8YMmUkwpiPLy7IAEMjsEeOlYPuIK/Dj2 PttVqzjkVY+pmvRARDs1o8wcawzECLFL2ZkBIVYN2ozzJSO/iiYvPyCfNBbv/Yu5nBam BnrO4SXpjl/FO0Irhj5Pmi/7nTkTZXPzY9Z2thOT7+Pw9/dgRTwIFdjeSB9dBfve7o0O a299cMZ6b57q6q+SSAWTSmzzFsLeTNEM3UblggLRsjeWHKqV3Ou9bVgxqPBoKtDMKzfM UybA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q25si997248edr.490.2020.11.05.04.59.17; Thu, 05 Nov 2020 04:59:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730992AbgKEM5U (ORCPT + 99 others); Thu, 5 Nov 2020 07:57:20 -0500 Received: from foss.arm.com ([217.140.110.172]:60146 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730948AbgKEM5N (ORCPT ); Thu, 5 Nov 2020 07:57:13 -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 E69AD142F; Thu, 5 Nov 2020 04:57:12 -0800 (PST) Received: from donnerap.arm.com (donnerap.cambridge.arm.com [10.1.195.35]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4869E3F73C; Thu, 5 Nov 2020 04:57:11 -0800 (PST) From: Andre Przywara To: Will Deacon , Catalin Marinas , Ard Biesheuvel , Russell King Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, Sudeep Holla , Mark Rutland , Mark Brown , Lorenzo Pieralisi , Linus Walleij Subject: [PATCH v2 4/5] arm64: Add support for SMCCC TRNG entropy source Date: Thu, 5 Nov 2020 12:56:55 +0000 Message-Id: <20201105125656.25259-5-andre.przywara@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201105125656.25259-1-andre.przywara@arm.com> References: <20201105125656.25259-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The ARM architected TRNG firmware interface, described in ARM spec DEN0098, defines an ARM SMCCC based interface to a true random number generator, provided by firmware. This can be discovered via the SMCCC >=v1.1 interface, and provides up to 192 bits of entropy per call. Hook this SMC call into arm64's arch_get_random_*() implementation, coming to the rescue when the CPU does not implement the ARM v8.5 RNG system registers. For the detection, we piggy back on the PSCI/SMCCC discovery (which gives us the conduit to use (hvc/smc)), then try to call the ARM_SMCCC_TRNG_VERSION function, which returns -1 if this interface is not implemented. Signed-off-by: Andre Przywara --- arch/arm64/include/asm/archrandom.h | 53 ++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h index abe07c21da8e..03744f688ca1 100644 --- a/arch/arm64/include/asm/archrandom.h +++ b/arch/arm64/include/asm/archrandom.h @@ -4,13 +4,24 @@ #ifdef CONFIG_ARCH_RANDOM +#include #include #include #include +#define ARM_SMCCC_TRNG_MIN_VERSION 0x10000UL + +extern bool smccc_trng_available; + static inline bool __init smccc_probe_trng(void) { - return false; + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_VERSION, &res); + if ((s32)res.a0 < 0) + return false; + + return res.a0 >= ARM_SMCCC_TRNG_MIN_VERSION; } static inline bool __arm64_rndr(unsigned long *v) @@ -43,26 +54,52 @@ static inline bool __must_check arch_get_random_int(unsigned int *v) static inline bool __must_check arch_get_random_seed_long(unsigned long *v) { + struct arm_smccc_res res; + /* * 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; + if (cpus_have_const_cap(ARM64_HAS_RNG)) + return __arm64_rndr(v); - return __arm64_rndr(v); -} + if (smccc_trng_available) { + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res); + if ((int)res.a0 < 0) + return false; + *v = res.a3; + return true; + } + + return false; +} static inline bool __must_check arch_get_random_seed_int(unsigned int *v) { + struct arm_smccc_res res; unsigned long val; - bool ok = arch_get_random_seed_long(&val); - *v = val; - return ok; + if (cpus_have_const_cap(ARM64_HAS_RNG)) { + if (arch_get_random_seed_long(&val)) { + *v = val; + return true; + } + return false; + } + + if (smccc_trng_available) { + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 32, &res); + if ((int)res.a0 < 0) + return false; + + *v = res.a3 & GENMASK(31, 0); + return true; + } + + return false; } static inline bool __init __early_cpu_has_rndr(void) -- 2.17.1