Commit 3eb681fb authored by David Brazdil's avatar David Brazdil Committed by Marc Zyngier
Browse files

KVM: arm64: Add ARM64_KVM_PROTECTED_MODE CPU capability



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: default avatarDavid Brazdil <dbrazdil@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20201202184122.26046-3-dbrazdil@google.com
parent d8b369c4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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);

+8 −0
Original line number Diff line number Diff line
@@ -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 */
+22 −0
Original line number Diff line number Diff line
@@ -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)",
+8 −1
Original line number Diff line number Diff line
@@ -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);