]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - arch/x86/kernel/smpboot.c
Merge tag 'x86_microcode_for_v6.7_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[thirdparty/linux.git] / arch / x86 / kernel / smpboot.c
index 75163c80f0559c02005da60b551238b73a84842f..2cc2aa120b4b390550178e1df5b916a2bdfacf2f 100644 (file)
@@ -87,6 +87,7 @@
 #include <asm/hw_irq.h>
 #include <asm/stackprotector.h>
 #include <asm/sev.h>
+#include <asm/spec-ctrl.h>
 
 /* representing HT siblings of each logical CPU */
 DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
@@ -124,7 +125,20 @@ struct mwait_cpu_dead {
  */
 static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead);
 
-/* Logical package management. We might want to allocate that dynamically */
+/* Logical package management. */
+struct logical_maps {
+       u32     phys_pkg_id;
+       u32     phys_die_id;
+       u32     logical_pkg_id;
+       u32     logical_die_id;
+};
+
+/* Temporary workaround until the full topology mechanics is in place */
+static DEFINE_PER_CPU_READ_MOSTLY(struct logical_maps, logical_maps) = {
+       .phys_pkg_id    = U32_MAX,
+       .phys_die_id    = U32_MAX,
+};
+
 unsigned int __max_logical_packages __read_mostly;
 EXPORT_SYMBOL(__max_logical_packages);
 static unsigned int logical_packages __read_mostly;
@@ -284,7 +298,7 @@ static void notrace start_secondary(void *unused)
 
        cpu_init();
        fpu__init_cpu();
-       rcu_cpu_starting(raw_smp_processor_id());
+       rcutree_report_cpu_starting(raw_smp_processor_id());
        x86_cpuinit.early_percpu_clock_init();
 
        ap_starting();
@@ -333,10 +347,8 @@ int topology_phys_to_logical_pkg(unsigned int phys_pkg)
        int cpu;
 
        for_each_possible_cpu(cpu) {
-               struct cpuinfo_x86 *c = &cpu_data(cpu);
-
-               if (c->initialized && c->phys_proc_id == phys_pkg)
-                       return c->logical_proc_id;
+               if (per_cpu(logical_maps.phys_pkg_id, cpu) == phys_pkg)
+                       return per_cpu(logical_maps.logical_pkg_id, cpu);
        }
        return -1;
 }
@@ -351,14 +363,12 @@ EXPORT_SYMBOL(topology_phys_to_logical_pkg);
  */
 static int topology_phys_to_logical_die(unsigned int die_id, unsigned int cur_cpu)
 {
-       int cpu, proc_id = cpu_data(cur_cpu).phys_proc_id;
+       int cpu, proc_id = cpu_data(cur_cpu).topo.pkg_id;
 
        for_each_possible_cpu(cpu) {
-               struct cpuinfo_x86 *c = &cpu_data(cpu);
-
-               if (c->initialized && c->cpu_die_id == die_id &&
-                   c->phys_proc_id == proc_id)
-                       return c->logical_die_id;
+               if (per_cpu(logical_maps.phys_pkg_id, cpu) == proc_id &&
+                   per_cpu(logical_maps.phys_die_id, cpu) == die_id)
+                       return per_cpu(logical_maps.logical_die_id, cpu);
        }
        return -1;
 }
@@ -383,7 +393,9 @@ int topology_update_package_map(unsigned int pkg, unsigned int cpu)
                        cpu, pkg, new);
        }
 found:
-       cpu_data(cpu).logical_proc_id = new;
+       per_cpu(logical_maps.phys_pkg_id, cpu) = pkg;
+       per_cpu(logical_maps.logical_pkg_id, cpu) = new;
+       cpu_data(cpu).topo.logical_pkg_id = new;
        return 0;
 }
 /**
@@ -406,7 +418,9 @@ int topology_update_die_map(unsigned int die, unsigned int cpu)
                        cpu, die, new);
        }
 found:
-       cpu_data(cpu).logical_die_id = new;
+       per_cpu(logical_maps.phys_die_id, cpu) = die;
+       per_cpu(logical_maps.logical_die_id, cpu) = new;
+       cpu_data(cpu).topo.logical_die_id = new;
        return 0;
 }
 
@@ -417,8 +431,8 @@ static void __init smp_store_boot_cpu_info(void)
 
        *c = boot_cpu_data;
        c->cpu_index = id;
-       topology_update_package_map(c->phys_proc_id, id);
-       topology_update_die_map(c->cpu_die_id, id);
+       topology_update_package_map(c->topo.pkg_id, id);
+       topology_update_die_map(c->topo.die_id, id);
        c->initialized = true;
 }
 
@@ -472,21 +486,21 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
        if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
                int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
-               if (c->phys_proc_id == o->phys_proc_id &&
-                   c->cpu_die_id == o->cpu_die_id &&
-                   per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) {
-                       if (c->cpu_core_id == o->cpu_core_id)
+               if (c->topo.pkg_id == o->topo.pkg_id &&
+                   c->topo.die_id == o->topo.die_id &&
+                   per_cpu_llc_id(cpu1) == per_cpu_llc_id(cpu2)) {
+                       if (c->topo.core_id == o->topo.core_id)
                                return topology_sane(c, o, "smt");
 
-                       if ((c->cu_id != 0xff) &&
-                           (o->cu_id != 0xff) &&
-                           (c->cu_id == o->cu_id))
+                       if ((c->topo.cu_id != 0xff) &&
+                           (o->topo.cu_id != 0xff) &&
+                           (c->topo.cu_id == o->topo.cu_id))
                                return topology_sane(c, o, "smt");
                }
 
-       } else if (c->phys_proc_id == o->phys_proc_id &&
-                  c->cpu_die_id == o->cpu_die_id &&
-                  c->cpu_core_id == o->cpu_core_id) {
+       } else if (c->topo.pkg_id == o->topo.pkg_id &&
+                  c->topo.die_id == o->topo.die_id &&
+                  c->topo.core_id == o->topo.core_id) {
                return topology_sane(c, o, "smt");
        }
 
@@ -495,8 +509,8 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 
 static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
-       if (c->phys_proc_id == o->phys_proc_id &&
-           c->cpu_die_id == o->cpu_die_id)
+       if (c->topo.pkg_id == o->topo.pkg_id &&
+           c->topo.die_id == o->topo.die_id)
                return true;
        return false;
 }
@@ -506,11 +520,11 @@ static bool match_l2c(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
        int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
        /* If the arch didn't set up l2c_id, fall back to SMT */
-       if (per_cpu(cpu_l2c_id, cpu1) == BAD_APICID)
+       if (per_cpu_l2c_id(cpu1) == BAD_APICID)
                return match_smt(c, o);
 
        /* Do not match if L2 cache id does not match: */
-       if (per_cpu(cpu_l2c_id, cpu1) != per_cpu(cpu_l2c_id, cpu2))
+       if (per_cpu_l2c_id(cpu1) != per_cpu_l2c_id(cpu2))
                return false;
 
        return topology_sane(c, o, "l2c");
@@ -523,7 +537,7 @@ static bool match_l2c(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
  */
 static bool match_pkg(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
-       if (c->phys_proc_id == o->phys_proc_id)
+       if (c->topo.pkg_id == o->topo.pkg_id)
                return true;
        return false;
 }
@@ -556,11 +570,11 @@ static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
        bool intel_snc = id && id->driver_data;
 
        /* Do not match if we do not have a valid APICID for cpu: */
-       if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID)
+       if (per_cpu_llc_id(cpu1) == BAD_APICID)
                return false;
 
        /* Do not match if LLC id does not match: */
-       if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2))
+       if (per_cpu_llc_id(cpu1) != per_cpu_llc_id(cpu2))
                return false;
 
        /*
@@ -636,13 +650,13 @@ static void __init build_sched_topology(void)
        };
 #endif
        /*
-        * When there is NUMA topology inside the package skip the DIE domain
+        * When there is NUMA topology inside the package skip the PKG domain
         * since the NUMA domains will auto-magically create the right spanning
         * domains based on the SLIT.
         */
        if (!x86_has_numa_in_package) {
                x86_topology[i++] = (struct sched_domain_topology_level){
-                       cpu_cpu_mask, x86_die_flags, SD_INIT_NAME(DIE)
+                       cpu_cpu_mask, x86_die_flags, SD_INIT_NAME(PKG)
                };
        }
 
@@ -805,7 +819,7 @@ static void __init smp_quirk_init_udelay(void)
 /*
  * Wake up AP by INIT, INIT, STARTUP sequence.
  */
-static void send_init_sequence(int phys_apicid)
+static void send_init_sequence(u32 phys_apicid)
 {
        int maxlvt = lapic_get_maxlvt();
 
@@ -831,7 +845,7 @@ static void send_init_sequence(int phys_apicid)
 /*
  * Wake up AP by INIT, INIT, STARTUP sequence.
  */
-static int wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
+static int wakeup_secondary_cpu_via_init(u32 phys_apicid, unsigned long start_eip)
 {
        unsigned long send_status = 0, accept_status = 0;
        int num_starts, j, maxlvt;
@@ -978,7 +992,7 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
  * Returns zero if startup was successfully sent, else error code from
  * ->wakeup_secondary_cpu.
  */
-static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
+static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
 {
        unsigned long start_ip = real_mode_header->trampoline_start;
        int ret;
@@ -1046,7 +1060,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 
 int native_kick_ap(unsigned int cpu, struct task_struct *tidle)
 {
-       int apicid = apic->cpu_present_to_apicid(cpu);
+       u32 apicid = apic->cpu_present_to_apicid(cpu);
        int err;
 
        lockdep_assert_irqs_enabled();
@@ -1401,7 +1415,7 @@ static void remove_siblinginfo(int cpu)
        cpumask_clear(topology_sibling_cpumask(cpu));
        cpumask_clear(topology_core_cpumask(cpu));
        cpumask_clear(topology_die_cpumask(cpu));
-       c->cpu_core_id = 0;
+       c->topo.core_id = 0;
        c->booted_cores = 0;
        cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
        recompute_smt_state();
@@ -1592,8 +1606,15 @@ void __noreturn hlt_play_dead(void)
                native_halt();
 }
 
+/*
+ * native_play_dead() is essentially a __noreturn function, but it can't
+ * be marked as such as the compiler may complain about it.
+ */
 void native_play_dead(void)
 {
+       if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))
+               __update_spec_ctrl(0);
+
        play_dead_common();
        tboot_shutdown(TB_SHUTDOWN_WFS);