]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-x86/tlbflush.h
Merge branch 'x86/prototypes' into x86-v28-for-linus-phase1
[linux-2.6-omap-h63xx.git] / include / asm-x86 / tlbflush.h
index 0c0674d9425559408fba244df6240760bf5cbcf9..ef68b76dc3c5c32f0ee2f24a1ecfec5725bba003 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TLBFLUSH_H
-#define _ASM_X86_TLBFLUSH_H
+#ifndef ASM_X86__TLBFLUSH_H
+#define ASM_X86__TLBFLUSH_H
 
 #include <linux/mm.h>
 #include <linux/sched.h>
@@ -22,12 +22,23 @@ static inline void __native_flush_tlb(void)
 
 static inline void __native_flush_tlb_global(void)
 {
-       unsigned long cr4 = read_cr4();
+       unsigned long flags;
+       unsigned long cr4;
 
+       /*
+        * Read-modify-write to CR4 - protect it from preemption and
+        * from interrupts. (Use the raw variant because this code can
+        * be called from deep inside debugging code.)
+        */
+       raw_local_irq_save(flags);
+
+       cr4 = read_cr4();
        /* clear PGE */
        write_cr4(cr4 & ~X86_CR4_PGE);
        /* write old PGE again and flush TLBs */
        write_cr4(cr4);
+
+       raw_local_irq_restore(flags);
 }
 
 static inline void __native_flush_tlb_single(unsigned long addr)
@@ -154,4 +165,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
        flush_tlb_all();
 }
 
-#endif /* _ASM_X86_TLBFLUSH_H */
+#endif /* ASM_X86__TLBFLUSH_H */