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: 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
This commit is contained in:
parent
d8b369c4e3
commit
3eb681fba2
@ -65,7 +65,8 @@
|
|||||||
#define ARM64_MTE 57
|
#define ARM64_MTE 57
|
||||||
#define ARM64_WORKAROUND_1508412 58
|
#define ARM64_WORKAROUND_1508412 58
|
||||||
#define ARM64_HAS_LDAPR 59
|
#define ARM64_HAS_LDAPR 59
|
||||||
|
#define ARM64_KVM_PROTECTED_MODE 60
|
||||||
|
|
||||||
#define ARM64_NCAPS 60
|
#define ARM64_NCAPS 61
|
||||||
|
|
||||||
#endif /* __ASM_CPUCAPS_H */
|
#endif /* __ASM_CPUCAPS_H */
|
||||||
|
@ -58,6 +58,7 @@ enum kvm_mode {
|
|||||||
KVM_MODE_DEFAULT,
|
KVM_MODE_DEFAULT,
|
||||||
KVM_MODE_PROTECTED,
|
KVM_MODE_PROTECTED,
|
||||||
};
|
};
|
||||||
|
enum kvm_mode kvm_get_mode(void);
|
||||||
|
|
||||||
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
|
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
|
||||||
|
|
||||||
|
@ -97,6 +97,14 @@ static __always_inline bool has_vhe(void)
|
|||||||
return cpus_have_final_cap(ARM64_HAS_VIRT_HOST_EXTN);
|
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 /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* ! __ASM__VIRT_H */
|
#endif /* ! __ASM__VIRT_H */
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeature.h>
|
||||||
#include <asm/cpu_ops.h>
|
#include <asm/cpu_ops.h>
|
||||||
#include <asm/fpsimd.h>
|
#include <asm/fpsimd.h>
|
||||||
|
#include <asm/kvm_host.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/mte.h>
|
#include <asm/mte.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
@ -1703,6 +1704,21 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_ARM64_MTE */
|
#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 */
|
/* Internal helper functions to match cpu capability type */
|
||||||
static bool
|
static bool
|
||||||
cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
|
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,
|
.field_pos = ID_AA64PFR0_EL1_SHIFT,
|
||||||
.min_field_value = ID_AA64PFR0_EL1_32BIT_64BIT,
|
.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
|
#endif
|
||||||
{
|
{
|
||||||
.desc = "Kernel page table isolation (KPTI)",
|
.desc = "Kernel page table isolation (KPTI)",
|
||||||
|
@ -1771,7 +1771,9 @@ int kvm_arch_init(void *opaque)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_hyp;
|
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");
|
kvm_info("VHE mode initialized successfully\n");
|
||||||
else
|
else
|
||||||
kvm_info("Hyp mode initialized successfully\n");
|
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);
|
early_param("kvm-arm.mode", early_kvm_mode_cfg);
|
||||||
|
|
||||||
|
enum kvm_mode kvm_get_mode(void)
|
||||||
|
{
|
||||||
|
return kvm_mode;
|
||||||
|
}
|
||||||
|
|
||||||
static int arm_init(void)
|
static int arm_init(void)
|
||||||
{
|
{
|
||||||
int rc = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
int rc = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||||
|
Loading…
Reference in New Issue
Block a user