Received: by 2002:a25:1104:0:0:0:0:0 with SMTP id 4csp91763ybr; Fri, 22 May 2020 01:39:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwby1uDJ9hVn54SWHYPlP/Q8U2NtwCdaMPkpwW5BlKV589NwQ1dL2sJtiib2J32m/wAR8z2 X-Received: by 2002:a17:906:2b8a:: with SMTP id m10mr7318041ejg.183.1590136799041; Fri, 22 May 2020 01:39:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590136799; cv=none; d=google.com; s=arc-20160816; b=d1RzFrpiepYFRzSZ/JnE3bJmTmAu3NC4qdwtasMz/8ZDgYHlFGE+WAMg7N0FXuOmTb azsTw48h5ga65hAZSuxIswXMqmTHvliCJDHnKtTrUlgoF+RKK5tFps/Ox9F6zSggWGOB X71eT0HcbWArb1EuvE+4YsMy8El1CJa8lmKZZkE0sDsrU2o/7ykaLhn/OC18hbPSgQdg 34/MFaWBfoVCbT1YTbkKScBHtO+wsc+5vkzh4rZtVRX5WmLg4Ty4s7Yu5ci1dMB04BGD jYwwW2+JG4zOPwwpmBwIA7fg2Uay1ynDsEbivYPMZBzM9bnPO/UYInqQL3ubfmam29WZ XquA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=BYYyh2iKdLcquZM0Cz6oCNg8qpF7zWpZRBydb7nE4aM=; b=zcW27wu5O/11wgl9+XOAKWwAs5CcY1w0ApJdPwwXDUuyGq/BO031lqYO59BL49h9M4 Vgf+C4bSjC6tYTwYJOBVtRySqFCUl1yY04QsMHucke7SWl8gbtcORIWEHckGO0q7bxGN DQK9Smagz5iEfixR163xzZEzOX1r/EMEiRz5QtPAUWgKSA+chlFCr53OSUSvDRXY+XCC VeSogsZf2cM29ckKgbzHfCF0zUmi38+nYGnL/TO7MRx4I7Ph81eABE0jijgq8uYJPs5O mVJs9LFb2ILLvX16rrpGzhovMZp9Un+c2h9cGkzK7r/x2hrJPeDXs1r8LVwuQwW7E5DY ZgJg== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id jz6si4755240ejb.327.2020.05.22.01.39.36; Fri, 22 May 2020 01:39:59 -0700 (PDT) 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729663AbgEVIhs (ORCPT + 99 others); Fri, 22 May 2020 04:37:48 -0400 Received: from foss.arm.com ([217.140.110.172]:59262 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729535AbgEVIhr (ORCPT ); Fri, 22 May 2020 04:37:47 -0400 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 8873C1042; Fri, 22 May 2020 01:37:46 -0700 (PDT) Received: from entos-d05.shanghai.arm.com (entos-d05.shanghai.arm.com [10.169.40.35]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 11AE73F52E; Fri, 22 May 2020 01:37:39 -0700 (PDT) From: Jianyong Wu To: netdev@vger.kernel.org, yangbo.lu@nxp.com, john.stultz@linaro.org, tglx@linutronix.de, pbonzini@redhat.com, sean.j.christopherson@intel.com, maz@kernel.org, richardcochran@gmail.com, Mark.Rutland@arm.com, will@kernel.org, suzuki.poulose@arm.com, steven.price@arm.com Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, Steve.Capper@arm.com, Kaly.Xin@arm.com, justin.he@arm.com, Wei.Chen@arm.com, jianyong.wu@arm.com, nd@arm.com Subject: [RFC PATCH v12 01/11] arm64: Probe for the presence of KVM hypervisor services during boot Date: Fri, 22 May 2020 16:37:14 +0800 Message-Id: <20200522083724.38182-2-jianyong.wu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200522083724.38182-1-jianyong.wu@arm.com> References: <20200522083724.38182-1-jianyong.wu@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Will Deacon Although the SMCCC specification provides some limited functionality for describing the presence of hypervisor and firmware services, this is generally applicable only to functions designated as "Arm Architecture Service Functions" and no portable discovery mechanism is provided for standard hypervisor services, despite having a designated range of function identifiers reserved by the specification. In an attempt to avoid the need for additional firmware changes every time a new function is added, introduce a UID to identify the service provider as being compatible with KVM. Once this has been established, additional services can be discovered via a feature bitmap. Cc: Marc Zyngier Signed-off-by: Will Deacon Signed-off-by: Jianyong Wu --- arch/arm64/include/asm/hypervisor.h | 11 +++++++++ arch/arm64/kernel/setup.c | 36 +++++++++++++++++++++++++++++ include/linux/arm-smccc.h | 26 +++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h index f9cc1d021791..91e4bd890819 100644 --- a/arch/arm64/include/asm/hypervisor.h +++ b/arch/arm64/include/asm/hypervisor.h @@ -2,6 +2,17 @@ #ifndef _ASM_ARM64_HYPERVISOR_H #define _ASM_ARM64_HYPERVISOR_H +#include #include +static inline bool kvm_arm_hyp_service_available(u32 func_id) +{ + extern DECLARE_BITMAP(__kvm_arm_hyp_services, ARM_SMCCC_KVM_NUM_FUNCS); + + if (func_id >= ARM_SMCCC_KVM_NUM_FUNCS) + return -EINVAL; + + return test_bit(func_id, __kvm_arm_hyp_services); +} + #endif diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 3fd2c11c09fc..80bb78953df2 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -276,6 +277,40 @@ arch_initcall(reserve_memblock_reserved_regions); u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; +DECLARE_BITMAP(__kvm_arm_hyp_services, ARM_SMCCC_KVM_NUM_FUNCS) = { }; + +static void __init kvm_init_hyp_services(void) +{ + int i; + struct arm_smccc_res res; + + if (psci_ops.smccc_version == SMCCC_VERSION_1_0) + return; + + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res); + if (res.a0 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 || + res.a1 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 || + res.a2 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 || + res.a3 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3) + return; + + memset(&res, 0, sizeof(res)); + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID, &res); + for (i = 0; i < 32; ++i) { + if (res.a0 & (i)) + set_bit(i + (32 * 0), __kvm_arm_hyp_services); + if (res.a1 & (i)) + set_bit(i + (32 * 1), __kvm_arm_hyp_services); + if (res.a2 & (i)) + set_bit(i + (32 * 2), __kvm_arm_hyp_services); + if (res.a3 & (i)) + set_bit(i + (32 * 3), __kvm_arm_hyp_services); + } + + pr_info("KVM hypervisor services detected (0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n", + res.a3, res.a2, res.a1, res.a0); +} + void __init setup_arch(char **cmdline_p) { init_mm.start_code = (unsigned long) _text; @@ -344,6 +379,7 @@ void __init setup_arch(char **cmdline_p) else psci_acpi_init(); + kvm_init_hyp_services(); init_bootcpu_ops(); smp_init_cpus(); smp_build_mpidr_hash(); diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 59494df0f55b..bdc0124a064a 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -46,11 +46,14 @@ #define ARM_SMCCC_OWNER_OEM 3 #define ARM_SMCCC_OWNER_STANDARD 4 #define ARM_SMCCC_OWNER_STANDARD_HYP 5 +#define ARM_SMCCC_OWNER_VENDOR_HYP 6 #define ARM_SMCCC_OWNER_TRUSTED_APP 48 #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 #define ARM_SMCCC_OWNER_TRUSTED_OS 50 #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 +#define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01 + #define ARM_SMCCC_QUIRK_NONE 0 #define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ @@ -77,6 +80,29 @@ ARM_SMCCC_SMC_32, \ 0, 0x7fff) +#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_FUNC_QUERY_CALL_UID) + +/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */ +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU + +/* KVM "vendor specific" services */ +#define ARM_SMCCC_KVM_FUNC_FEATURES 0 +#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 +#define ARM_SMCCC_KVM_NUM_FUNCS 128 + +#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_FEATURES) + #ifndef __ASSEMBLY__ #include -- 2.17.1