[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch 36/37] x86/smpboot/64: Implement arch_cpuhp_init_parallel_bringup() and enable it



Implement the validation function which tells the core code whether
parallel bringup is possible:

  1) Valid CPUID leaf for APIC ID retrieval. For non x2APIC systmms leaf
     0x1 is sufficient, otherwise leaf 0xb or 0x1f must be available.

  2) Prevent parallel bringup on encrypted guests as this requires a
     different handling of the CPUID leaf retrieval via a call into the
     trusted firmware module. This is what the #VC trap handler does later
     on, which is not available during the very early startup.

Originally-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
---
 arch/x86/Kconfig             |    3 +-
 arch/x86/kernel/cpu/common.c |    6 -----
 arch/x86/kernel/smpboot.c    |   49 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 50 insertions(+), 8 deletions(-)

--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -272,8 +272,9 @@ config X86
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_USER_RETURN_NOTIFIER
        select HAVE_GENERIC_VDSO
+       select HOTPLUG_PARALLEL                 if SMP && X86_64
        select HOTPLUG_SMT                      if SMP
-       select HOTPLUG_SPLIT_STARTUP            if SMP
+       select HOTPLUG_SPLIT_STARTUP            if SMP && X86_32
        select IRQ_FORCED_THREADING
        select NEED_PER_CPU_EMBED_FIRST_CHUNK
        select NEED_PER_CPU_PAGE_FIRST_CHUNK
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -2127,11 +2127,7 @@ static inline void setup_getcpu(int cpu)
 }
 
 #ifdef CONFIG_X86_64
-static inline void ucode_cpu_init(int cpu)
-{
-       if (cpu)
-               load_ucode_ap();
-}
+static inline void ucode_cpu_init(int cpu) { }
 
 static inline void tss_setup_ist(struct tss_struct *tss)
 {
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -58,6 +58,7 @@
 #include <linux/overflow.h>
 #include <linux/stackprotector.h>
 #include <linux/cpuhotplug.h>
+#include <linux/mc146818rtc.h>
 
 #include <asm/acpi.h>
 #include <asm/cacheinfo.h>
@@ -75,7 +76,7 @@
 #include <asm/fpu/api.h>
 #include <asm/setup.h>
 #include <asm/uv/uv.h>
-#include <linux/mc146818rtc.h>
+#include <asm/microcode.h>
 #include <asm/i8259.h>
 #include <asm/misc.h>
 #include <asm/qspinlock.h>
@@ -128,7 +129,6 @@ int arch_update_cpu_topology(void)
        return retval;
 }
 
-
 static unsigned int smpboot_warm_reset_vector_count;
 
 static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
@@ -247,6 +247,8 @@ static void notrace start_secondary(void
 #endif
        cpu_init_exception_handling();
 
+       load_ucode_ap();
+
        /*
         * Sync point with the hotplug core. Sets the sync state to ALIVE
         * and waits for the control CPU to release it.
@@ -1251,6 +1253,49 @@ void __init smp_prepare_cpus_common(void
        set_cpu_sibling_map(0);
 }
 
+#ifdef CONFIG_X86_64
+/* Establish whether parallel bringup can be supported. */
+bool __init arch_cpuhp_init_parallel_bringup(void)
+{
+       unsigned int ctrl;
+
+       if (boot_cpu_data.cpuid_level < 0x01) {
+               pr_info("Parallel CPU startup disabled due to lack of CPUID\n");
+               return false;
+       }
+
+       /* Encrypted guests require special CPUID handling. */
+       if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) {
+               pr_info("Parallel CPU startup disabled due to guest state 
encryption\n");
+               return false;
+       }
+
+       switch (topology_extended_leaf) {
+       case 0x0b:
+               ctrl = STARTUP_APICID_CPUID_0B;
+               break;
+       case 0x1f:
+               ctrl = STARTUP_APICID_CPUID_1F;
+               break;
+       case 0x00:
+               /* For !x2APIC mode 8 bits from leaf 0x01 are sufficient. */
+               if (!x2apic_mode) {
+                       ctrl = STARTUP_APICID_CPUID_01;
+                       break;
+               }
+               fallthrough;
+       default:
+               pr_info("Parallel CPU startup disabled. Unsupported topology 
leaf %u\n",
+                       topology_extended_leaf);
+               return false;
+       }
+
+       pr_debug("Parallel CPU startup enabled: 0x%08x\n", ctrl);
+       smpboot_control = ctrl;
+       return true;
+}
+#endif
+
 /*
  * Prepare for SMP bootup.
  * @max_cpus: configured maximum number of CPUs, It is a legacy parameter




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.