return ret;
}
+static void microcode_late_eval_cpuid(void *arg)
+{
+ init_scattered_cpuid_features(&cpu_data(smp_processor_id()),
+ GET_CPU_CAP_FULL);
+}
+
+static void microcode_late_eval_cpuid_all(void)
+{
+ int cpu;
+ /*
+ * Evaluate CPU features after microcode loading.
+ * This needs to be done on each CPU.
+ */
+ for_each_online_cpu(cpu) {
+ if (cpu == 0)
+ continue;
+ smp_call_function_single(cpu, microcode_late_eval_cpuid, NULL, 1);
+ }
+ smp_call_function_single(0, microcode_late_eval_cpuid, NULL, 1);
+}
+
struct apply_microcode_ctx {
int err;
};
if (ret > 0) {
perf_check_microcode();
-
- /* check spec_ctrl capabilities */
- init_scattered_cpuid_features(&cpu_data(0), GET_CPU_CAP_FULL);
+ microcode_late_eval_cpuid_all();
}
mutex_unlock(µcode_mutex);
}
if (!ret) {
perf_check_microcode();
-
- init_scattered_cpuid_features(&cpu_data(0), GET_CPU_CAP_FULL);
+ microcode_late_eval_cpuid_all();
}
mutex_unlock(µcode_mutex);
error = subsys_interface_register(&mc_cpu_interface);
if (!error) {
perf_check_microcode();
-
- init_scattered_cpuid_features(&cpu_data(0), GET_CPU_CAP_FULL);
+ microcode_late_eval_cpuid_all();
}
mutex_unlock(µcode_mutex);