Skip to content

Commit 4ba55e6

Browse files
amlutoIngo Molnar
authored andcommitted
x86/mm/32: Load a sane CR3 before cpu_init() on secondary CPUs
For unknown historical reasons (i.e. Borislav doesn't recall), 32-bit kernels invoke cpu_init() on secondary CPUs with initial_page_table loaded into CR3. Then they set current->active_mm to &init_mm and call enter_lazy_tlb() before fixing CR3. This means that the x86 TLB code gets invoked while CR3 is inconsistent, and, with the improved PCID sanity checks I added, we warn. Fix it by loading swapper_pg_dir (i.e. init_mm.pgd) earlier. Reported-by: Paul Menzel <[email protected]> Reported-by: Pavel Machek <[email protected]> Signed-off-by: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Fixes: 72c0098 ("x86/mm: Reinitialize TLB state on hotplug and resume") Link: http://lkml.kernel.org/r/30cdfea504682ba3b9012e77717800a91c22097f.1505663533.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent b8b7aba commit 4ba55e6

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

arch/x86/kernel/smpboot.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,19 +232,20 @@ static void notrace start_secondary(void *unused)
232232
*/
233233
if (boot_cpu_has(X86_FEATURE_PCID))
234234
__write_cr4(__read_cr4() | X86_CR4_PCIDE);
235-
cpu_init();
236-
x86_cpuinit.early_percpu_clock_init();
237-
preempt_disable();
238-
smp_callin();
239-
240-
enable_start_cpu0 = 0;
241235

242236
#ifdef CONFIG_X86_32
243237
/* switch away from the initial page table */
244238
load_cr3(swapper_pg_dir);
245239
__flush_tlb_all();
246240
#endif
247241

242+
cpu_init();
243+
x86_cpuinit.early_percpu_clock_init();
244+
preempt_disable();
245+
smp_callin();
246+
247+
enable_start_cpu0 = 0;
248+
248249
/* otherwise gcc will move up smp_processor_id before the cpu_init */
249250
barrier();
250251
/*

0 commit comments

Comments
 (0)