x86/cpu: Get rid of redundant switch_to_new_gdt() invocations
authorThomas Gleixner <tglx@linutronix.de>
Thu, 15 Sep 2022 11:10:42 +0000 (13:10 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 17 Oct 2022 14:40:56 +0000 (16:40 +0200)
The only place where switch_to_new_gdt() is required is early boot to
switch from the early GDT to the direct GDT. Any other invocation is
completely redundant because it does not change anything.

Secondary CPUs come out of the ASM code with GDT and GSBASE correctly set
up. The same is true for XEN_PV.

Remove all the voodoo invocations which are left overs from the ancient
past, rename the function to switch_gdt_and_percpu_base() and mark it init.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220915111143.198076128@infradead.org
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/smpboot.c
arch/x86/xen/enlighten_pv.c

index e21ec970d41abac303d6562a398da305e610a94e..c660700ecfc6100d56b9feda7212712590a55a8b 100644 (file)
@@ -667,7 +667,7 @@ extern int sysenter_setup(void);
 /* Defined in head.S */
 extern struct desc_ptr         early_gdt_descr;
 
-extern void switch_to_new_gdt(int);
+extern void switch_gdt_and_percpu_base(int);
 extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
 extern void cpu_init(void);
index c09abee6f4d5bbefe61573f797147edd1fbc2d5c..f51928dd275adfae689cd0b27c24034753ec73d9 100644 (file)
@@ -729,14 +729,15 @@ void load_fixmap_gdt(int cpu)
 EXPORT_SYMBOL_GPL(load_fixmap_gdt);
 
 /**
- * switch_to_new_gdt - Switch form early GDT to the direct one
+ * switch_gdt_and_percpu_base - Switch to direct GDT and runtime per CPU base
  * @cpu:       The CPU number for which this is invoked
  *
- * Invoked during early boot to switch from early GDT and early per CPU
- * (%fs on 32bit, GS_BASE on 64bit) to the direct GDT and the runtime per
- * CPU area.
+ * Invoked during early boot to switch from early GDT and early per CPU to
+ * the direct GDT and the runtime per CPU area. On 32-bit the percpu base
+ * switch is implicit by loading the direct GDT. On 64bit this requires
+ * to update GSBASE.
  */
-void switch_to_new_gdt(int cpu)
+void __init switch_gdt_and_percpu_base(int cpu)
 {
        load_direct_gdt(cpu);
 
@@ -2263,12 +2264,6 @@ void cpu_init(void)
            boot_cpu_has(X86_FEATURE_TSC) || boot_cpu_has(X86_FEATURE_DE))
                cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
 
-       /*
-        * Initialize the per-CPU GDT with the boot GDT,
-        * and set up the GDT descriptor:
-        */
-       switch_to_new_gdt(cpu);
-
        if (IS_ENABLED(CONFIG_X86_64)) {
                loadsegment(fs, 0);
                memset(cur->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
index 49325caa7307df8f5944b1ea2b32c8310d59c642..555089a5b446d4feb645a26401b25404b7fcd124 100644 (file)
@@ -211,7 +211,7 @@ void __init setup_per_cpu_areas(void)
                 * area.  Reload any changed state for the boot CPU.
                 */
                if (!cpu)
-                       switch_to_new_gdt(cpu);
+                       switch_gdt_and_percpu_base(cpu);
        }
 
        /* indicate the early static arrays will soon be gone */
index 3f3ea0287f694f6a5a674ef7d63c1b5f8839fbcb..ce8728d2e5efa4fe6043384d2e8c1b195edb60b2 100644 (file)
@@ -1453,7 +1453,11 @@ void arch_thaw_secondary_cpus_end(void)
 void __init native_smp_prepare_boot_cpu(void)
 {
        int me = smp_processor_id();
-       switch_to_new_gdt(me);
+
+       /* SMP handles this from setup_per_cpu_areas() */
+       if (!IS_ENABLED(CONFIG_SMP))
+               switch_gdt_and_percpu_base(me);
+
        /* already set me in cpu_online_mask in boot_cpu_init() */
        cpumask_set_cpu(me, cpu_callout_mask);
        cpu_set_state_online(me);
index f82857e488152a7377690f9d37a3a72e733c58d7..9b892079581ba9f02632dcf8badf8ea024d78037 100644 (file)
@@ -1209,7 +1209,7 @@ static void __init xen_setup_gdt(int cpu)
        pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry_boot;
        pv_ops.cpu.load_gdt = xen_load_gdt_boot;
 
-       switch_to_new_gdt(cpu);
+       switch_gdt_and_percpu_base(cpu);
 
        pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry;
        pv_ops.cpu.load_gdt = xen_load_gdt;