First, HVO must have ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU so that incompatible CPUs can be onlined if HVO is not in use. The late_cpu_enable() callback is used to check if HVO is truly in use. If the late CPU is incompatible with HVO and HVO is *not* in use, HVO becomes permanently disabled. If the late CPU is incompatible with HVO and HVO *is* in use, the CPU is not onlined. If the late CPU is compatible with HVO, there is no issue. Signed-off-by: James Houghton --- arch/arm64/kernel/cpufeature.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 7e2c134f3b55..65bb3c7c9595 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include @@ -2181,6 +2182,22 @@ static bool hvo_compatible(const struct arm64_cpu_capabilities *caps, int scope) return supports_hw_af(scope); } +static bool late_cpu_enable_hvo(const struct arm64_cpu_capabilities *__unused) +{ +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP + if (cpu_has_hw_af()) + return true; + + /* + * If the CPU does not support HW AF, we cannot online it if HVO is + * currently in use. + */ + return hugetlb_vmemmap_optimization_try_disable(); +#else + return true; +#endif +} + static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused) { /* @@ -3079,8 +3096,11 @@ static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "HugeTLB Vmemmap Optimization Support", .capability = ARM64_HVO_COMPATIBLE, - .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .type = ARM64_CPUCAP_SCOPE_SYSTEM | + ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU | + ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU, .matches = hvo_compatible, + .late_cpu_enable = late_cpu_enable_hvo, }, { .desc = "52-bit Virtual Addressing for KVM (LPA2)", -- 2.55.0.795.g602f6c329a-goog