Track HVO compatibility as its own system feature. If every boot CPU supports it, later onlining a CPU that doesn't support it won't be allowed. HVO requires BBM Level 2 no abort for the block -> table transitions when optimizing the vmemmap, and it requires hardware AF management to avoid taking page faults on the !AF translation that is installed as part of the RW table -> RO + new OA table transitions. Another possibility would be to disable HVO if an incompatible CPU were onlined; I haven't done this. Signed-off-by: James Houghton --- arch/arm64/include/asm/cpucaps.h | 2 ++ arch/arm64/include/asm/cpufeature.h | 5 +++++ arch/arm64/kernel/cpufeature.c | 16 ++++++++++++++++ arch/arm64/tools/cpucaps | 1 + 4 files changed, 24 insertions(+) diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 25c61cda901c..6db3ef827f86 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -75,6 +75,8 @@ cpucap_is_possible(const unsigned int cap) return IS_ENABLED(CONFIG_HW_PERF_EVENTS); case ARM64_HAS_LSUI: return IS_ENABLED(CONFIG_ARM64_LSUI); + case ARM64_HVO_COMPATIBLE: + return IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP); } return true; diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index e818ad1b56e2..a62c284962cf 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -885,6 +885,11 @@ static inline bool system_supports_bbml2_noabort(void) return alternative_has_cap_unlikely(ARM64_HAS_BBML2_NOABORT); } +static inline bool system_supports_hvo(void) +{ + return alternative_has_cap_unlikely(ARM64_HVO_COMPATIBLE); +} + int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt); bool try_emulate_mrs(struct pt_regs *regs, u32 isn); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9a22df0c5120..3b9224b99a5f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2172,6 +2172,16 @@ static bool has_bbml2_noabort(const struct arm64_cpu_capabilities *caps, int sco return cpu_supports_bbml2_noabort(); } +static bool hvo_compatible(const struct arm64_cpu_capabilities *caps, int scope) +{ + /* + * We need BBML2 to support Block -> Table transitions without taking + * faults, and we need HW AF support to support changing the OA without + * taking faults. + */ + return cpu_supports_bbml2_noabort() && supports_hw_af(scope); +} + static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) { /* @@ -3067,6 +3077,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .type = ARM64_CPUCAP_EARLY_LOCAL_CPU_FEATURE, .matches = has_bbml2_noabort, }, + { + .desc = "HugeTLB Vmemmap Optimization Support", + .capability = ARM64_HVO_COMPATIBLE, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = hvo_compatible, + }, { .desc = "52-bit Virtual Addressing for KVM (LPA2)", .capability = ARM64_HAS_LPA2, diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 9b85a84f6fd4..630953d59c52 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -70,6 +70,7 @@ HAS_VIRT_HOST_EXTN HAS_WFXT HAS_XNX HAFT +HVO_COMPATIBLE HW_DBM KVM_HVHE KVM_PROTECTED_MODE -- 2.55.0.795.g602f6c329a-goog