x86/cpu: Ensure that CPU info updates are propagated on UP
The boot sequence evaluates CPUID information twice:
1) During early boot
2) When finalizing the early setup right before
mitigations are selected and alternatives are patched.
In both cases the evaluation is stored in boot_cpu_data, but on UP the
copying of boot_cpu_data to the per CPU info of the boot CPU happens
between #1 and #2. So any update which happens in #2 is never propagated to
the per CPU info instance.
Consolidate the whole logic and copy boot_cpu_data right before applying
alternatives as that's the point where boot_cpu_data is in it's final
state and not supposed to change anymore.
This also removes the voodoo mb() from smp_prepare_cpus_common() which
had absolutely no purpose.
Fixes: 71eb4893cf
("x86/percpu: Cure per CPU madness on UP")
Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20240322185305.127642785@linutronix.de
This commit is contained in:
parent
4e51653d5d
commit
c90399fbd7
@ -2307,6 +2307,8 @@ void arch_smt_update(void)
|
|||||||
|
|
||||||
void __init arch_cpu_finalize_init(void)
|
void __init arch_cpu_finalize_init(void)
|
||||||
{
|
{
|
||||||
|
struct cpuinfo_x86 *c = this_cpu_ptr(&cpu_info);
|
||||||
|
|
||||||
identify_boot_cpu();
|
identify_boot_cpu();
|
||||||
|
|
||||||
select_idle_routine();
|
select_idle_routine();
|
||||||
@ -2345,6 +2347,13 @@ void __init arch_cpu_finalize_init(void)
|
|||||||
fpu__init_system();
|
fpu__init_system();
|
||||||
fpu__init_cpu();
|
fpu__init_cpu();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that access to the per CPU representation has the initial
|
||||||
|
* boot CPU configuration.
|
||||||
|
*/
|
||||||
|
*c = boot_cpu_data;
|
||||||
|
c->initialized = true;
|
||||||
|
|
||||||
alternative_instructions();
|
alternative_instructions();
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_X86_64)) {
|
if (IS_ENABLED(CONFIG_X86_64)) {
|
||||||
|
@ -1206,16 +1206,6 @@ void __init i386_reserve_resources(void)
|
|||||||
|
|
||||||
#endif /* CONFIG_X86_32 */
|
#endif /* CONFIG_X86_32 */
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
|
||||||
void __init smp_prepare_boot_cpu(void)
|
|
||||||
{
|
|
||||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
|
||||||
|
|
||||||
*c = boot_cpu_data;
|
|
||||||
c->initialized = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct notifier_block kernel_offset_notifier = {
|
static struct notifier_block kernel_offset_notifier = {
|
||||||
.notifier_call = dump_kernel_offset
|
.notifier_call = dump_kernel_offset
|
||||||
};
|
};
|
||||||
|
@ -313,14 +313,6 @@ static void notrace start_secondary(void *unused)
|
|||||||
cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
|
cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init smp_store_boot_cpu_info(void)
|
|
||||||
{
|
|
||||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
|
||||||
|
|
||||||
*c = boot_cpu_data;
|
|
||||||
c->initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The bootstrap kernel entry code has set these up. Save them for
|
* The bootstrap kernel entry code has set these up. Save them for
|
||||||
* a given CPU
|
* a given CPU
|
||||||
@ -1039,29 +1031,15 @@ static __init void disable_smp(void)
|
|||||||
cpumask_set_cpu(0, topology_die_cpumask(0));
|
cpumask_set_cpu(0, topology_die_cpumask(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init smp_cpu_index_default(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct cpuinfo_x86 *c;
|
|
||||||
|
|
||||||
for_each_possible_cpu(i) {
|
|
||||||
c = &cpu_data(i);
|
|
||||||
/* mark all to hotplug */
|
|
||||||
c->cpu_index = nr_cpu_ids;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init smp_prepare_cpus_common(void)
|
void __init smp_prepare_cpus_common(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
smp_cpu_index_default();
|
/* Mark all except the boot CPU as hotpluggable */
|
||||||
|
for_each_possible_cpu(i) {
|
||||||
/*
|
if (i)
|
||||||
* Setup boot CPU information
|
per_cpu(cpu_info.cpu_index, i) = nr_cpu_ids;
|
||||||
*/
|
}
|
||||||
smp_store_boot_cpu_info(); /* Final full version of the data */
|
|
||||||
mb();
|
|
||||||
|
|
||||||
for_each_possible_cpu(i) {
|
for_each_possible_cpu(i) {
|
||||||
zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
|
zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
|
||||||
|
Loading…
Reference in New Issue
Block a user