arm64: Add KVM_HVHE capability and has_hvhe() predicate
authorMarc Zyngier <maz@kernel.org>
Fri, 9 Jun 2023 16:21:47 +0000 (17:21 +0100)
committerOliver Upton <oliver.upton@linux.dev>
Mon, 12 Jun 2023 23:17:23 +0000 (23:17 +0000)
Expose a capability keying the hVHE feature as well as a new
predicate testing it. Nothing is so far using it, and nothing
is enabling it yet.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20230609162200.2024064-5-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/virt.h
arch/arm64/kernel/cpufeature.c
arch/arm64/tools/cpucaps

index bc10098..3d4b547 100644 (file)
@@ -16,6 +16,7 @@
 #define cpu_feature(x)         KERNEL_HWCAP_ ## x
 
 #define ARM64_SW_FEATURE_OVERRIDE_NOKASLR      0
+#define ARM64_SW_FEATURE_OVERRIDE_HVHE         4
 
 #ifndef __ASSEMBLY__
 
index 21e9406..5227db7 100644 (file)
@@ -142,6 +142,14 @@ static __always_inline bool is_protected_kvm_enabled(void)
                return cpus_have_final_cap(ARM64_KVM_PROTECTED_MODE);
 }
 
+static __always_inline bool has_hvhe(void)
+{
+       if (is_vhe_hyp_code())
+               return false;
+
+       return cpus_have_final_cap(ARM64_KVM_HVHE);
+}
+
 static inline bool is_hyp_nvhe(void)
 {
        return is_hyp_mode_available() && !is_kernel_in_hyp_mode();
index 2d2b7bb..c743b1a 100644 (file)
@@ -1998,6 +1998,19 @@ static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap,
        return true;
 }
 
+static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
+                         int __unused)
+{
+       u64 val;
+
+       val = read_sysreg(id_aa64mmfr1_el1);
+       if (!cpuid_feature_extract_unsigned_field(val, ID_AA64MMFR1_EL1_VH_SHIFT))
+               return false;
+
+       val = arm64_sw_feature_override.val & arm64_sw_feature_override.mask;
+       return cpuid_feature_extract_unsigned_field(val, ARM64_SW_FEATURE_OVERRIDE_HVHE);
+}
+
 #ifdef CONFIG_ARM64_PAN
 static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
 {
@@ -2643,6 +2656,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .cpu_enable = cpu_enable_dit,
                ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, DIT, IMP)
        },
+       {
+               .desc = "VHE for hypervisor only",
+               .capability = ARM64_KVM_HVHE,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .matches = hvhe_possible,
+       },
        {},
 };
 
index 40ba954..3c23a55 100644 (file)
@@ -47,6 +47,7 @@ HAS_TLB_RANGE
 HAS_VIRT_HOST_EXTN
 HAS_WFXT
 HW_DBM
+KVM_HVHE
 KVM_PROTECTED_MODE
 MISMATCHED_CACHE_TYPE
 MTE