diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-07 14:50:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-07 14:50:38 -0700 |
commit | 813895f8dcb31bc6b0e9f5fc35e8c687a467f3dd (patch) | |
tree | 576996d2cae905f4af87a8604cfa5c59bdef54f5 /arch/x86/kernel/cpu/common.c | |
parent | d4c54919ed86302094c0ca7d48a8cbd4ee753e92 (diff) | |
parent | 745c51673e289acf4d9ffc2835524de73ef923fd (diff) |
Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Peter Anvin:
"A significantly larger than I'd like set of patches for just below the
wire. All of these, however, fix real problems.
The one thing that is genuinely scary in here is the change of SMP
initialization, but that *does* fix a confirmed hang when booting
virtual machines.
There is also a patch to actually do the right thing about not
offlining a CPU when there are not enough interrupt vectors available
in the system; the accounting was done incorrectly. The worst case
for that patch is that we fail to offline CPUs when we should (the new
code is strictly more conservative than the old), so is not
particularly risky.
Most of the rest is minor stuff; the EFI patches are all about
exporting correct information to boot loaders and kexec"
* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/boot: EFI_MIXED should not prohibit loading above 4G
x86/smpboot: Initialize secondary CPU only if master CPU will wait for it
x86/smpboot: Log error on secondary CPU wakeup failure at ERR level
x86: Fix list/memory corruption on CPU hotplug
x86: irq: Get correct available vectors for cpu disable
x86/efi: Do not export efi runtime map in case old map
x86/efi: earlyprintk=efi,keep fix
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index a135239badb..a4bcbacdbe0 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1221,6 +1221,17 @@ static void dbg_restore_debug_regs(void) #define dbg_restore_debug_regs() #endif /* ! CONFIG_KGDB */ +static void wait_for_master_cpu(int cpu) +{ + /* + * wait for ACK from master CPU before continuing + * with AP initialization + */ + WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)); + while (!cpumask_test_cpu(cpu, cpu_callout_mask)) + cpu_relax(); +} + /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT @@ -1236,16 +1247,17 @@ void cpu_init(void) struct task_struct *me; struct tss_struct *t; unsigned long v; - int cpu; + int cpu = stack_smp_processor_id(); int i; + wait_for_master_cpu(cpu); + /* * Load microcode on this cpu if a valid microcode is available. * This is early microcode loading procedure. */ load_ucode_ap(); - cpu = stack_smp_processor_id(); t = &per_cpu(init_tss, cpu); oist = &per_cpu(orig_ist, cpu); @@ -1257,9 +1269,6 @@ void cpu_init(void) me = current; - if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) - panic("CPU#%d already initialized!\n", cpu); - pr_debug("Initializing CPU#%d\n", cpu); clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); @@ -1336,13 +1345,9 @@ void cpu_init(void) struct tss_struct *t = &per_cpu(init_tss, cpu); struct thread_struct *thread = &curr->thread; - show_ucode_info_early(); + wait_for_master_cpu(cpu); - if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) { - printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); - for (;;) - local_irq_enable(); - } + show_ucode_info_early(); printk(KERN_INFO "Initializing CPU#%d\n", cpu); |