diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index 206ea2ca63cc5beb221c238ff81172244de262b9..c3750c2c41137a694be9570443f59b379cc4cc4d 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -8,6 +8,8 @@
 #include <asm/alternative.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
+#include <asm/mce.h>
+#include <asm/nmi.h>
 
 #ifdef CONFIG_HOTPLUG_CPU
 static int smp_alt_once;
@@ -373,6 +375,14 @@ void __init alternative_instructions(void)
 {
 	unsigned long flags;
 
+	/* The patching is not fully atomic, so try to avoid local interruptions
+	   that might execute the to be patched code.
+	   Other CPUs are not running. */
+	stop_nmi();
+#ifdef CONFIG_MCE
+	stop_mce();
+#endif
+
 	local_irq_save(flags);
 	apply_alternatives(__alt_instructions, __alt_instructions_end);
 
@@ -405,6 +415,11 @@ void __init alternative_instructions(void)
 #endif
  	apply_paravirt(__parainstructions, __parainstructions_end);
 	local_irq_restore(flags);
+
+	restart_nmi();
+#ifdef CONFIG_MCE
+	restart_mce();
+#endif
 }
 
 /*
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index 56cd485b127ce59b2da500e9f176b83bb755b7b7..34c781eddee4cdc6fce3419366b63329965655a5 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -60,6 +60,20 @@ void mcheck_init(struct cpuinfo_x86 *c)
 	}
 }
 
+static unsigned long old_cr4 __initdata;
+
+void __init stop_mce(void)
+{
+	old_cr4 = read_cr4();
+	clear_in_cr4(X86_CR4_MCE);
+}
+
+void __init restart_mce(void)
+{
+	if (old_cr4 & X86_CR4_MCE)
+		set_in_cr4(X86_CR4_MCE);
+}
+
 static int __init mcheck_disable(char *str)
 {
 	mce_disabled = 1;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 438949da3b634d63e40503da9baba34fe00e130b..cfffe3dd9e838315089c9461a49b0fa2b6aef12b 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -775,6 +775,8 @@ static __kprobes void default_do_nmi(struct pt_regs * regs)
 	reassert_nmi();
 }
 
+static int ignore_nmis;
+
 fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 {
 	int cpu;
@@ -785,11 +787,24 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 
 	++nmi_count(cpu);
 
-	default_do_nmi(regs);
+	if (!ignore_nmis)
+		default_do_nmi(regs);
 
 	nmi_exit();
 }
 
+void stop_nmi(void)
+{
+	acpi_nmi_disable();
+	ignore_nmis++;
+}
+
+void restart_nmi(void)
+{
+	ignore_nmis--;
+	acpi_nmi_enable();
+}
+
 #ifdef CONFIG_KPROBES
 fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
 {
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 4d8450ee3635e8ee587f5f639f7862b5a5155a74..a66d607f5b924e09d864120d1d656c3e1a1c2da0 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -667,6 +667,20 @@ static struct miscdevice mce_log_device = {
 	&mce_chrdev_ops,
 };
 
+static unsigned long old_cr4 __initdata;
+
+void __init stop_mce(void)
+{
+	old_cr4 = read_cr4();
+	clear_in_cr4(X86_CR4_MCE);
+}
+
+void __init restart_mce(void)
+{
+	if (old_cr4 & X86_CR4_MCE)
+		set_in_cr4(X86_CR4_MCE);
+}
+
 /* 
  * Old style boot options parsing. Only for compatibility. 
  */
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index edbbc59b752334d570cb939c70ece3f43ca8ae42..cb8ee9d02f8682d4e52374aae1847a4daf03292a 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -384,11 +384,14 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
 	return rc;
 }
 
+static unsigned ignore_nmis;
+
 asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 {
 	nmi_enter();
 	add_pda(__nmi_count,1);
-	default_do_nmi(regs);
+	if (!ignore_nmis)
+		default_do_nmi(regs);
 	nmi_exit();
 }
 
@@ -401,6 +404,18 @@ int do_nmi_callback(struct pt_regs * regs, int cpu)
 	return 0;
 }
 
+void stop_nmi(void)
+{
+	acpi_nmi_disable();
+	ignore_nmis++;
+}
+
+void restart_nmi(void)
+{
+	ignore_nmis--;
+	acpi_nmi_enable();
+}
+
 #ifdef CONFIG_SYSCTL
 
 static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
diff --git a/include/asm-i386/mce.h b/include/asm-i386/mce.h
index b0a02ee34ffd74720747c295077720e86604933c..d56d89742e8fdcd0bfd96ccd1ff83292eea0bc99 100644
--- a/include/asm-i386/mce.h
+++ b/include/asm-i386/mce.h
@@ -5,3 +5,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
 #endif
 
 extern int mce_disabled;
+
+extern void stop_mce(void);
+extern void restart_mce(void);
+
diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h
index fb1e133efd9fecdc182d827ddd8c75841b8c6660..ff30c98f87b023290c8d1355f3873540e7d6c2ae 100644
--- a/include/asm-i386/nmi.h
+++ b/include/asm-i386/nmi.h
@@ -57,5 +57,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz);
 int lapic_watchdog_ok(void);
 void disable_lapic_nmi_watchdog(void);
 void enable_lapic_nmi_watchdog(void);
+void stop_nmi(void);
+void restart_nmi(void);
 
 #endif /* ASM_NMI_H */
diff --git a/include/asm-x86_64/mce.h b/include/asm-x86_64/mce.h
index 556be5563e308f2d80e7e67f65b4ab19b67b3b49..7bc030a1996de9c2ad53763eac202643e459a54b 100644
--- a/include/asm-x86_64/mce.h
+++ b/include/asm-x86_64/mce.h
@@ -107,6 +107,9 @@ extern void do_machine_check(struct pt_regs *, long);
 
 extern int mce_notify_user(void);
 
+extern void stop_mce(void);
+extern void restart_mce(void);
+
 #endif
 
 #endif
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
index d0a7f53b1497cf65442c2162716608378589c467..5fb3c0de5cccba5a421a3820bb551619d489fad9 100644
--- a/include/asm-x86_64/nmi.h
+++ b/include/asm-x86_64/nmi.h
@@ -88,5 +88,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz);
 int lapic_watchdog_ok(void);
 void disable_lapic_nmi_watchdog(void);
 void enable_lapic_nmi_watchdog(void);
+void stop_nmi(void);
+void restart_nmi(void);
 
 #endif /* ASM_NMI_H */