Commit-ID:  b2e2ba578e016a091eb31565849990fe68c7c599
Gitweb:     https://git.kernel.org/tip/b2e2ba578e016a091eb31565849990fe68c7c599
Author:     Chang S. Bae <chang.seok....@intel.com>
AuthorDate: Tue, 18 Sep 2018 16:08:59 -0700
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Mon, 8 Oct 2018 10:41:10 +0200

x86/vdso: Initialize the CPU/node NR segment descriptor earlier

Currently the CPU/node NR segment descriptor (GDT_ENTRY_CPU_NUMBER) is
initialized relatively late during CPU init, from the vCPU code, which
has a number of disadvantages, such as hotplug CPU notifiers and SMP
cross-calls.

Instead just initialize it much earlier, directly in cpu_init().

This reduces complexity and increases robustness.

[ mingo: Wrote new changelog. ]

Suggested-by: H. Peter Anvin <h...@zytor.com>
Suggested-by: Andy Lutomirski <l...@kernel.org>
Signed-off-by: Chang S. Bae <chang.seok....@intel.com>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Markus T Metzger <markus.t.metz...@intel.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Ravi Shankar <ravi.v.shan...@intel.com>
Cc: Rik van Riel <r...@surriel.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Link: 
http://lkml.kernel.org/r/1537312139-5580-9-git-send-email-chang.seok....@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 arch/x86/entry/vdso/vma.c    | 33 +--------------------------------
 arch/x86/kernel/cpu/common.c | 24 ++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 39b5584c5808..3f9d43f26f63 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -332,35 +332,6 @@ static __init int vdso_setup(char *s)
        return 0;
 }
 __setup("vdso=", vdso_setup);
-#endif
-
-#ifdef CONFIG_X86_64
-static void vgetcpu_cpu_init(void *arg)
-{
-       int cpu = smp_processor_id();
-       struct desc_struct d = { };
-       unsigned long cpudata = vdso_encode_cpu_node(cpu, cpu_to_node(cpu));
-
-       if (static_cpu_has(X86_FEATURE_RDTSCP))
-               write_rdtscp_aux(cpudata);
-
-       /* Store CPU and node number in limit */
-       d.limit0 = cpudata;
-       d.limit1 = cpudata >> 16;
-
-       d.type = 5;             /* RO data, expand down, accessed */
-       d.dpl = 3;              /* Visible to user code */
-       d.s = 1;                /* Not a system segment */
-       d.p = 1;                /* Present */
-       d.d = 1;                /* 32-bit */
-
-       write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_CPU_NUMBER, &d, 
DESCTYPE_S);
-}
-
-static int vgetcpu_online(unsigned int cpu)
-{
-       return smp_call_function_single(cpu, vgetcpu_cpu_init, NULL, 1);
-}
 
 static int __init init_vdso(void)
 {
@@ -370,9 +341,7 @@ static int __init init_vdso(void)
        init_vdso_image(&vdso_image_x32);
 #endif
 
-       /* notifier priority > KVM */
-       return cpuhp_setup_state(CPUHP_AP_X86_VDSO_VMA_ONLINE,
-                                "x86/vdso/vma:online", vgetcpu_online, NULL);
+       return 0;
 }
 subsys_initcall(init_vdso);
 #endif /* CONFIG_X86_64 */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 44c4ef3d989b..a148d18a1ef0 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1669,6 +1669,29 @@ static void wait_for_master_cpu(int cpu)
 #endif
 }
 
+#ifdef CONFIG_X86_64
+static void setup_getcpu(int cpu)
+{
+       unsigned long cpudata = vdso_encode_cpu_node(cpu, 
early_cpu_to_node(cpu));
+       struct desc_struct d = { };
+
+       if (static_cpu_has(X86_FEATURE_RDTSCP))
+               write_rdtscp_aux(cpudata);
+
+       /* Store CPU and node number in limit. */
+       d.limit0 = cpudata;
+       d.limit1 = cpudata >> 16;
+
+       d.type = 5;             /* RO data, expand down, accessed */
+       d.dpl = 3;              /* Visible to user code */
+       d.s = 1;                /* Not a system segment */
+       d.p = 1;                /* Present */
+       d.d = 1;                /* 32-bit */
+
+       write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_CPU_NUMBER, &d, 
DESCTYPE_S);
+}
+#endif
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1706,6 +1729,7 @@ void cpu_init(void)
            early_cpu_to_node(cpu) != NUMA_NO_NODE)
                set_numa_node(early_cpu_to_node(cpu));
 #endif
+       setup_getcpu(cpu);
 
        me = current;
 

Reply via email to