|
@@ -985,8 +985,16 @@ void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
|
|
|
*/
|
|
|
void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
|
|
|
{
|
|
|
- for (; caps->matches; caps++)
|
|
|
- if (caps->enable && cpus_have_cap(caps->capability))
|
|
|
+ for (; caps->matches; caps++) {
|
|
|
+ unsigned int num = caps->capability;
|
|
|
+
|
|
|
+ if (!cpus_have_cap(num))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* Ensure cpus_have_const_cap(num) works */
|
|
|
+ static_branch_enable(&cpu_hwcap_keys[num]);
|
|
|
+
|
|
|
+ if (caps->enable) {
|
|
|
/*
|
|
|
* Use stop_machine() as it schedules the work allowing
|
|
|
* us to modify PSTATE, instead of on_each_cpu() which
|
|
@@ -994,6 +1002,8 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
|
|
|
* we return.
|
|
|
*/
|
|
|
stop_machine(caps->enable, NULL, cpu_online_mask);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1096,6 +1106,14 @@ static void __init setup_feature_capabilities(void)
|
|
|
enable_cpu_capabilities(arm64_features);
|
|
|
}
|
|
|
|
|
|
+DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready);
|
|
|
+EXPORT_SYMBOL(arm64_const_caps_ready);
|
|
|
+
|
|
|
+static void __init mark_const_caps_ready(void)
|
|
|
+{
|
|
|
+ static_branch_enable(&arm64_const_caps_ready);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Check if the current CPU has a given feature capability.
|
|
|
* Should be called from non-preemptible context.
|
|
@@ -1131,6 +1149,7 @@ void __init setup_cpu_features(void)
|
|
|
/* Set the CPU feature capabilies */
|
|
|
setup_feature_capabilities();
|
|
|
enable_errata_workarounds();
|
|
|
+ mark_const_caps_ready();
|
|
|
setup_elf_hwcaps(arm64_elf_hwcaps);
|
|
|
|
|
|
if (system_supports_32bit_el0())
|