Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp723702pxu; Wed, 6 Jan 2021 02:39:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJzBbhZiUeqk20oYmXac9s9wcu9abFgueK463QOtZhdLHSi9fqmuFESz8HTCfBFgpv9amski X-Received: by 2002:a17:906:c83b:: with SMTP id dd27mr2512090ejb.356.1609929550093; Wed, 06 Jan 2021 02:39:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609929550; cv=none; d=google.com; s=arc-20160816; b=jHDbxLfrskEYgVUwzvuqCOMpUVFuE5e6tEY6bNkGu2msMuN2N1PSPjeujchTrB/cYB wcCOv8mLD54iX4fKgcqS3R65CfjKt9XL1TFmAccmx1qLYYj/5uKf/j+QfYWHYhKh7VPO LA2RzjyP5kZXOVSi+Mrje+YjJ7S8lz/QBOsUSIrAyKnbVoupsgbE0P3ElK7pdlORPS26 a52ckntqonvDmlDO8XGgxwNq85e2c9RZVCfH6YzjJ1u8dO1c1f6nAw3RioxsqFFTiJIK NV/6PBD6vCDHLAm8hTSN1rEGzRyR50IkTbx8Nkif/a+mHcJpAvMYaaKb4tKMvBqgG6yu K2Zw== 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=cuhXh4lIO+hYmS8bQrYBczoojSDZv9ooh8jOo+gHvOk=; b=Bd1lni/solLQM75mzTi5kf3O+lVMB8sUjdZv6nGlW+WinxlwA4JNOaEVH/zMR4REJ4 OJ0M88d3ttHipBU9Y0Y9QRRAMzVuOnc4/6cBFy1tgVBuPhBtaZRarWexpNTWKFWywDhe AffrecJ4LCfnwA0QmKNHAq8u7UTHVi2B/pwoWn/bnGRLsltDc9NO/UCzF6KIbJVwIwkq JSB5qUs+oKhA4Xkyzo3Nlt6Ttn8F4L2FCyBywdfrolfZmpHMSSwPuWPOK34lW/6X4K1m 2NYR/0oaYbj/6xW4zWTopSPSlpF2lDzdKfR7YtiEAaNTtJfxAYWVJZssnr384OIL5lJe 5exA== 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 f21si778192eds.396.2021.01.06.02.38.42; Wed, 06 Jan 2021 02:39:10 -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 S1726287AbhAFKgd (ORCPT + 99 others); Wed, 6 Jan 2021 05:36:33 -0500 Received: from foss.arm.com ([217.140.110.172]:38792 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726216AbhAFKgd (ORCPT ); Wed, 6 Jan 2021 05:36:33 -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 46D9A11B3; Wed, 6 Jan 2021 02:35: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 67CBC3F719; Wed, 6 Jan 2021 02:35:10 -0800 (PST) From: Andre Przywara To: Will Deacon , Catalin Marinas , Ard Biesheuvel , Russell King , Marc Zyngier Cc: Theodore Ts'o , Sudeep Holla , Mark Rutland , Mark Brown , Lorenzo Pieralisi , Linus Walleij , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org Subject: [PATCH v6 5/5] KVM: arm64: implement the TRNG hypervisor call Date: Wed, 6 Jan 2021 10:34:53 +0000 Message-Id: <20210106103453.152275-6-andre.przywara@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210106103453.152275-1-andre.przywara@arm.com> References: <20210106103453.152275-1-andre.przywara@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ard Biesheuvel Provide a hypervisor implementation of the ARM architected TRNG firmware interface described in ARM spec DEN0098. All function IDs are implemented, including both 32-bit and 64-bit versions of the TRNG_RND service, which is the centerpiece of the API. The API is backed by the kernel's entropy pool only, to avoid guests draining more precious direct entropy sources. Signed-off-by: Ard Biesheuvel [Andre: minor fixes, drop arch_get_random() usage] Signed-off-by: Andre Przywara --- arch/arm64/include/asm/kvm_host.h | 2 + arch/arm64/kvm/Makefile | 2 +- arch/arm64/kvm/hypercalls.c | 6 +++ arch/arm64/kvm/trng.c | 85 +++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/kvm/trng.c diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 11beda85ee7e..271c79914afd 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -748,4 +748,6 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); #define kvm_vcpu_has_pmu(vcpu) \ (test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features)) +int kvm_trng_call(struct kvm_vcpu *vcpu); + #endif /* __ARM64_KVM_HOST_H__ */ diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 60fd181df624..8d2b9984ac36 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -16,7 +16,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ inject_fault.o va_layout.o handle_exit.o \ guest.o debug.o reset.o sys_regs.o \ vgic-sys-reg-v3.o fpsimd.o pmu.o \ - arch_timer.o \ + arch_timer.o trng.o\ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ vgic/vgic-v3.o vgic/vgic-v4.o \ diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 25ea4ecb6449..ead21b98b620 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -71,6 +71,12 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) if (gpa != GPA_INVALID) val = gpa; break; + case ARM_SMCCC_TRNG_VERSION: + case ARM_SMCCC_TRNG_FEATURES: + case ARM_SMCCC_TRNG_GET_UUID: + case ARM_SMCCC_TRNG_RND32: + case ARM_SMCCC_TRNG_RND64: + return kvm_trng_call(vcpu); default: return kvm_psci_call(vcpu); } diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c new file mode 100644 index 000000000000..99bdd7103c9c --- /dev/null +++ b/arch/arm64/kvm/trng.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2020 Arm Ltd. + +#include +#include + +#include + +#include + +#define ARM_SMCCC_TRNG_VERSION_1_0 0x10000UL + +/* Those values are deliberately separate from the generic SMCCC definitions. */ +#define TRNG_SUCCESS 0UL +#define TRNG_NOT_SUPPORTED ((unsigned long)-1) +#define TRNG_INVALID_PARAMETER ((unsigned long)-2) +#define TRNG_NO_ENTROPY ((unsigned long)-3) + +#define TRNG_MAX_BITS64 192 + +static const uuid_t arm_smc_trng_uuid __aligned(4) = UUID_INIT( + 0x0d21e000, 0x4384, 0x11eb, 0x80, 0x70, 0x52, 0x44, 0x55, 0x4e, 0x5a, 0x4c); + +static int kvm_trng_do_rnd(struct kvm_vcpu *vcpu, int size) +{ + DECLARE_BITMAP(bits, TRNG_MAX_BITS64); + u32 num_bits = smccc_get_arg1(vcpu); + int i; + + if (num_bits > 3 * size) { + smccc_set_retval(vcpu, TRNG_INVALID_PARAMETER, 0, 0, 0); + return 1; + } + + /* get as many bits as we need to fulfil the request */ + for (i = 0; i < DIV_ROUND_UP(num_bits, BITS_PER_LONG); i++) + bits[i] = get_random_long(); + + bitmap_clear(bits, num_bits, TRNG_MAX_BITS64 - num_bits); + + if (size == 32) + smccc_set_retval(vcpu, TRNG_SUCCESS, lower_32_bits(bits[1]), + upper_32_bits(bits[0]), lower_32_bits(bits[0])); + else + smccc_set_retval(vcpu, TRNG_SUCCESS, bits[2], bits[1], bits[0]); + + memzero_explicit(bits, sizeof(bits)); + return 1; +} + +int kvm_trng_call(struct kvm_vcpu *vcpu) +{ + const __le32 *u = (__le32 *)arm_smc_trng_uuid.b; + u32 func_id = smccc_get_function(vcpu); + unsigned long val = TRNG_NOT_SUPPORTED; + int size = 64; + + switch (func_id) { + case ARM_SMCCC_TRNG_VERSION: + val = ARM_SMCCC_TRNG_VERSION_1_0; + break; + case ARM_SMCCC_TRNG_FEATURES: + switch (smccc_get_arg1(vcpu)) { + case ARM_SMCCC_TRNG_VERSION: + case ARM_SMCCC_TRNG_FEATURES: + case ARM_SMCCC_TRNG_GET_UUID: + case ARM_SMCCC_TRNG_RND32: + case ARM_SMCCC_TRNG_RND64: + val = TRNG_SUCCESS; + } + break; + case ARM_SMCCC_TRNG_GET_UUID: + smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]), + le32_to_cpu(u[2]), le32_to_cpu(u[3])); + return 1; + case ARM_SMCCC_TRNG_RND32: + size = 32; + fallthrough; + case ARM_SMCCC_TRNG_RND64: + return kvm_trng_do_rnd(vcpu, size); + } + + smccc_set_retval(vcpu, val, 0, 0, 0); + return 1; +} -- 2.17.1