Commit 0bf87165 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov (AMD)

x86/microcode: Replace the all-in-one rendevous handler

with a new handler which just separates the control flow of primary and
secondary CPUs.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20231002115903.433704135@linutronix.de
parent 6067788f
......@@ -268,7 +268,7 @@ struct microcode_ctrl {
};
static DEFINE_PER_CPU(struct microcode_ctrl, ucode_ctrl);
static atomic_t late_cpus_in, late_cpus_out;
static atomic_t late_cpus_in;
static bool wait_for_cpus(atomic_t *cnt)
{
......@@ -304,7 +304,7 @@ static bool wait_for_ctrl(void)
return false;
}
static __maybe_unused void load_secondary(unsigned int cpu)
static void load_secondary(unsigned int cpu)
{
unsigned int ctrl_cpu = this_cpu_read(ucode_ctrl.ctrl_cpu);
enum ucode_state ret;
......@@ -339,7 +339,7 @@ static __maybe_unused void load_secondary(unsigned int cpu)
this_cpu_write(ucode_ctrl.ctrl, SCTRL_DONE);
}
static __maybe_unused void load_primary(unsigned int cpu)
static void load_primary(unsigned int cpu)
{
struct cpumask *secondaries = topology_sibling_cpumask(cpu);
enum sibling_ctrl ctrl;
......@@ -376,46 +376,14 @@ static __maybe_unused void load_primary(unsigned int cpu)
static int load_cpus_stopped(void *unused)
{
int cpu = smp_processor_id();
enum ucode_state ret;
/*
* Wait for all CPUs to arrive. A load will not be attempted unless all
* CPUs show up.
* */
if (!wait_for_cpus(&late_cpus_in)) {
this_cpu_write(ucode_ctrl.result, UCODE_TIMEOUT);
return 0;
}
/*
* On an SMT system, it suffices to load the microcode on one sibling of
* the core because the microcode engine is shared between the threads.
* Synchronization still needs to take place so that no concurrent
* loading attempts happen on multiple threads of an SMT core. See
* below.
*/
if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
goto wait_for_siblings;
unsigned int cpu = smp_processor_id();
ret = microcode_ops->apply_microcode(cpu);
this_cpu_write(ucode_ctrl.result, ret);
wait_for_siblings:
if (!wait_for_cpus(&late_cpus_out))
panic("Timeout during microcode update!\n");
/*
* At least one thread has completed update on each core.
* For others, simply call the update to make sure the
* per-cpu cpuinfo can be updated with right microcode
* revision.
*/
if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
return 0;
if (this_cpu_read(ucode_ctrl.ctrl_cpu) == cpu)
load_primary(cpu);
else
load_secondary(cpu);
ret = microcode_ops->apply_microcode(cpu);
this_cpu_write(ucode_ctrl.result, ret);
/* No point to wait here. The CPUs will all wait in stop_machine(). */
return 0;
}
......@@ -429,7 +397,6 @@ static int load_late_stop_cpus(void)
pr_err("You should switch to early loading, if possible.\n");
atomic_set(&late_cpus_in, num_online_cpus());
atomic_set(&late_cpus_out, num_online_cpus());
/*
* Take a snapshot before the microcode update in order to compare and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment