From c02620fb25914382a898928524448d3cd3df1e89 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 5 Jan 2022 14:10:54 +0000 Subject: [PATCH] ANDROID: KVM: arm64: relay entropy requests from protected guests directly to secure As pKVM does not trust the host, it should not be involved in the handling of, or be able to observe the response to entropy requests issues by protected guests. When an SMC-based implementation of the ARM SMCCC TRNG interface is present, pass any HVC-based requests directly on to the secure firmware. Co-developed-by: Ard Biesheuvel Signed-off-by: Ard Biesheuvel Signed-off-by: Will Deacon Bug: 209580772 Change-Id: Ica492ce49fd059a62ecc31bb7ac13c9adb773a08 Signed-off-by: Will Deacon --- arch/arm64/include/asm/kvm_hyp.h | 1 + arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/hyp/nvhe/pkvm.c | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 0e18b4716d7d..2f99074111aa 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -124,4 +124,5 @@ extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val); extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val); extern unsigned long kvm_nvhe_sym(__icache_flags); +extern bool kvm_nvhe_sym(smccc_trng_available); #endif /* __ARM64_KVM_HYP_H__ */ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 76215b22285b..37dbfbd695a9 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1990,6 +1990,7 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits) kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1); kvm_nvhe_sym(__icache_flags) = __icache_flags; + kvm_nvhe_sym(smccc_trng_available) = smccc_trng_available; ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP); if (ret) diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index cd844471b221..57e1304c3713 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -1137,6 +1137,35 @@ static bool pkvm_install_ioguard_page(struct kvm_vcpu *vcpu, u64 *exit_code) return true; } +bool smccc_trng_available; + +static bool pkvm_forward_trng(struct kvm_vcpu *vcpu) +{ + u32 fn = smccc_get_function(vcpu); + struct arm_smccc_res res; + unsigned long arg1 = 0; + + /* + * Forward TRNG calls to EL3, as we can't trust the host to handle + * these for us. + */ + switch (fn) { + case ARM_SMCCC_TRNG_FEATURES: + case ARM_SMCCC_TRNG_RND32: + case ARM_SMCCC_TRNG_RND64: + arg1 = smccc_get_arg1(vcpu); + fallthrough; + case ARM_SMCCC_TRNG_VERSION: + case ARM_SMCCC_TRNG_GET_UUID: + arm_smccc_1_1_smc(fn, arg1, &res); + smccc_set_retval(vcpu, res.a0, res.a1, res.a2, res.a3); + memzero_explicit(&res, sizeof(res)); + break; + } + + return true; +} + /* * Handler for protected VM HVC calls. * @@ -1193,6 +1222,11 @@ bool kvm_handle_pvm_hvc64(struct kvm_vcpu *vcpu, u64 *exit_code) return pkvm_memshare_call(vcpu, exit_code); case ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID: return pkvm_memunshare_call(vcpu); + case ARM_SMCCC_TRNG_VERSION ... ARM_SMCCC_TRNG_RND32: + case ARM_SMCCC_TRNG_RND64: + if (smccc_trng_available) + return pkvm_forward_trng(vcpu); + break; default: return pkvm_handle_psci(vcpu); }