aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/alternative.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index cdc43242da92..318a4f9b7ece 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -273,6 +273,7 @@ struct smp_alt_module {
273}; 273};
274static LIST_HEAD(smp_alt_modules); 274static LIST_HEAD(smp_alt_modules);
275static DEFINE_SPINLOCK(smp_alt); 275static DEFINE_SPINLOCK(smp_alt);
276static int smp_mode = 1; /* protected by smp_alt */
276 277
277void alternatives_smp_module_add(struct module *mod, char *name, 278void alternatives_smp_module_add(struct module *mod, char *name,
278 void *locks, void *locks_end, 279 void *locks, void *locks_end,
@@ -354,7 +355,14 @@ void alternatives_smp_switch(int smp)
354 BUG_ON(!smp && (num_online_cpus() > 1)); 355 BUG_ON(!smp && (num_online_cpus() > 1));
355 356
356 spin_lock_irqsave(&smp_alt, flags); 357 spin_lock_irqsave(&smp_alt, flags);
357 if (smp) { 358
359 /*
360 * Avoid unnecessary switches because it forces JIT based VMs to
361 * throw away all cached translations, which can be quite costly.
362 */
363 if (smp == smp_mode) {
364 /* nothing */
365 } else if (smp) {
358 printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); 366 printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
359 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); 367 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
360 clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP); 368 clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
@@ -369,6 +377,7 @@ void alternatives_smp_switch(int smp)
369 alternatives_smp_unlock(mod->locks, mod->locks_end, 377 alternatives_smp_unlock(mod->locks, mod->locks_end,
370 mod->text, mod->text_end); 378 mod->text, mod->text_end);
371 } 379 }
380 smp_mode = smp;
372 spin_unlock_irqrestore(&smp_alt, flags); 381 spin_unlock_irqrestore(&smp_alt, flags);
373} 382}
374 383
@@ -441,7 +450,10 @@ void __init alternative_instructions(void)
441 alternatives_smp_module_add(NULL, "core kernel", 450 alternatives_smp_module_add(NULL, "core kernel",
442 __smp_locks, __smp_locks_end, 451 __smp_locks, __smp_locks_end,
443 _text, _etext); 452 _text, _etext);
444 alternatives_smp_switch(0); 453
454 /* Only switch to UP mode if we don't immediately boot others */
455 if (num_possible_cpus() == 1 || setup_max_cpus <= 1)
456 alternatives_smp_switch(0);
445 } 457 }
446#endif 458#endif
447 apply_paravirt(__parainstructions, __parainstructions_end); 459 apply_paravirt(__parainstructions, __parainstructions_end);