]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: arm64: Add ARM64_KVM_PROTECTED_MODE CPU capability
authorDavid Brazdil <dbrazdil@google.com>
Wed, 2 Dec 2020 18:40:58 +0000 (18:40 +0000)
committerMarc Zyngier <maz@kernel.org>
Fri, 4 Dec 2020 08:44:19 +0000 (08:44 +0000)
Expose the boolean value whether the system is running with KVM in
protected mode (nVHE + kernel param). CPU capability was selected over
a global variable to allow use in alternatives.

Signed-off-by: David Brazdil <dbrazdil@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20201202184122.26046-3-dbrazdil@google.com
arch/arm64/include/asm/cpucaps.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/virt.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kvm/arm.c

index a7242ef2a2cd6581e72eac43fef38ba3e44a3848..350c98103d45ef3977190487d79a447682bcf3f0 100644 (file)
@@ -65,7 +65,8 @@
 #define ARM64_MTE                              57
 #define ARM64_WORKAROUND_1508412               58
 #define ARM64_HAS_LDAPR                                59
+#define ARM64_KVM_PROTECTED_MODE               60
 
-#define ARM64_NCAPS                            60
+#define ARM64_NCAPS                            61
 
 #endif /* __ASM_CPUCAPS_H */
index 820954ad247761535f3f17f13e07f30b7d151a3b..7119d38e3c5601327b48f648f9936b189231284b 100644 (file)
@@ -58,6 +58,7 @@ enum kvm_mode {
        KVM_MODE_DEFAULT,
        KVM_MODE_PROTECTED,
 };
+enum kvm_mode kvm_get_mode(void);
 
 DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 
index 6069be50baf9fba2d5a05c5e0893b08b2b6a03f8..eb81dcc220b65ecd0d8a90746bdc05c6dee66876 100644 (file)
@@ -97,6 +97,14 @@ static __always_inline bool has_vhe(void)
                return cpus_have_final_cap(ARM64_HAS_VIRT_HOST_EXTN);
 }
 
+static __always_inline bool is_protected_kvm_enabled(void)
+{
+       if (is_vhe_hyp_code())
+               return false;
+       else
+               return cpus_have_final_cap(ARM64_KVM_PROTECTED_MODE);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* ! __ASM__VIRT_H */
index cffcb0198bae829ee0a9afaf24edd21788bb1e2c..0c029adf72d33082e384c5caa0fe283849f928dd 100644 (file)
@@ -74,6 +74,7 @@
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
 #include <asm/fpsimd.h>
+#include <asm/kvm_host.h>
 #include <asm/mmu_context.h>
 #include <asm/mte.h>
 #include <asm/processor.h>
@@ -1703,6 +1704,21 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 }
 #endif /* CONFIG_ARM64_MTE */
 
+#ifdef CONFIG_KVM
+static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
+{
+       if (kvm_get_mode() != KVM_MODE_PROTECTED)
+               return false;
+
+       if (is_kernel_in_hyp_mode()) {
+               pr_warn("Protected KVM not available with VHE\n");
+               return false;
+       }
+
+       return true;
+}
+#endif /* CONFIG_KVM */
+
 /* Internal helper functions to match cpu capability type */
 static bool
 cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
@@ -1794,6 +1810,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .field_pos = ID_AA64PFR0_EL1_SHIFT,
                .min_field_value = ID_AA64PFR0_EL1_32BIT_64BIT,
        },
+       {
+               .desc = "Protected KVM",
+               .capability = ARM64_KVM_PROTECTED_MODE,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .matches = is_kvm_protected_mode,
+       },
 #endif
        {
                .desc = "Kernel page table isolation (KPTI)",
index 5db90680742c22655acb3ceed85a58b7b4378bee..745e1b4bcbe0534564be7854d98cd11ab4b650ae 100644 (file)
@@ -1771,7 +1771,9 @@ int kvm_arch_init(void *opaque)
        if (err)
                goto out_hyp;
 
-       if (in_hyp_mode)
+       if (is_protected_kvm_enabled())
+               kvm_info("Protected nVHE mode initialized successfully\n");
+       else if (in_hyp_mode)
                kvm_info("VHE mode initialized successfully\n");
        else
                kvm_info("Hyp mode initialized successfully\n");
@@ -1806,6 +1808,11 @@ static int __init early_kvm_mode_cfg(char *arg)
 }
 early_param("kvm-arm.mode", early_kvm_mode_cfg);
 
+enum kvm_mode kvm_get_mode(void)
+{
+       return kvm_mode;
+}
+
 static int arm_init(void)
 {
        int rc = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);