x86: prevent PGE flush from interruption/preemption

CR4 manipulation is not protected against interrupts and preemption,
but KVM uses smp_function_call to manipulate the X86_CR4_VMXE bit
either from the CPU hotplug code or from the kvm_init call.

We need to protect the CR4 manipulation from both interrupts and
preemption.

Original bug report: http://lkml.org/lkml/2008/5/7/48
Bugzilla entry: http://bugzilla.kernel.org/show_bug.cgi?id=10642

This is not a regression from 2.6.25, it's a long standing and hard to
trigger bug.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by Ingo Molnar and committed by Thomas Gleixner b1979a5f a1289643

+12 -1
+12 -1
include/asm-x86/tlbflush.h
··· 22 22 23 23 static inline void __native_flush_tlb_global(void) 24 24 { 25 - unsigned long cr4 = read_cr4(); 25 + unsigned long flags; 26 + unsigned long cr4; 26 27 28 + /* 29 + * Read-modify-write to CR4 - protect it from preemption and 30 + * from interrupts. (Use the raw variant because this code can 31 + * be called from deep inside debugging code.) 32 + */ 33 + raw_local_irq_save(flags); 34 + 35 + cr4 = read_cr4(); 27 36 /* clear PGE */ 28 37 write_cr4(cr4 & ~X86_CR4_PGE); 29 38 /* write old PGE again and flush TLBs */ 30 39 write_cr4(cr4); 40 + 41 + raw_local_irq_restore(flags); 31 42 } 32 43 33 44 static inline void __native_flush_tlb_single(unsigned long addr)