diff options
Diffstat (limited to 'arch/i386/kernel/alternative.c')
-rw-r--r-- | arch/i386/kernel/alternative.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 206ea2ca63cc..c3750c2c4113 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <asm/alternative.h> | 8 | #include <asm/alternative.h> |
9 | #include <asm/sections.h> | 9 | #include <asm/sections.h> |
10 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
11 | #include <asm/mce.h> | ||
12 | #include <asm/nmi.h> | ||
11 | 13 | ||
12 | #ifdef CONFIG_HOTPLUG_CPU | 14 | #ifdef CONFIG_HOTPLUG_CPU |
13 | static int smp_alt_once; | 15 | static int smp_alt_once; |
@@ -373,6 +375,14 @@ void __init alternative_instructions(void) | |||
373 | { | 375 | { |
374 | unsigned long flags; | 376 | unsigned long flags; |
375 | 377 | ||
378 | /* The patching is not fully atomic, so try to avoid local interruptions | ||
379 | that might execute the to be patched code. | ||
380 | Other CPUs are not running. */ | ||
381 | stop_nmi(); | ||
382 | #ifdef CONFIG_MCE | ||
383 | stop_mce(); | ||
384 | #endif | ||
385 | |||
376 | local_irq_save(flags); | 386 | local_irq_save(flags); |
377 | apply_alternatives(__alt_instructions, __alt_instructions_end); | 387 | apply_alternatives(__alt_instructions, __alt_instructions_end); |
378 | 388 | ||
@@ -405,6 +415,11 @@ void __init alternative_instructions(void) | |||
405 | #endif | 415 | #endif |
406 | apply_paravirt(__parainstructions, __parainstructions_end); | 416 | apply_paravirt(__parainstructions, __parainstructions_end); |
407 | local_irq_restore(flags); | 417 | local_irq_restore(flags); |
418 | |||
419 | restart_nmi(); | ||
420 | #ifdef CONFIG_MCE | ||
421 | restart_mce(); | ||
422 | #endif | ||
408 | } | 423 | } |
409 | 424 | ||
410 | /* | 425 | /* |