]> err.no Git - linux-2.6/blobdiff - include/asm-x86/pgtable-3level.h
Merge git://git.infradead.org/mtd-2.6
[linux-2.6] / include / asm-x86 / pgtable-3level.h
index ed4c6f0e57ec28464b018f6a61e4fed80a6257dc..1d763eec740ff882c329889db1a9ae7006ac8817 100644 (file)
@@ -93,17 +93,22 @@ static inline void native_pmd_clear(pmd_t *pmd)
 
 static inline void pud_clear(pud_t *pudp)
 {
+       unsigned long pgd;
+
        set_pud(pudp, __pud(0));
 
        /*
-        * Pentium-II erratum A13: in PAE mode we explicitly have to flush
-        * the TLB via cr3 if the top-level pgd is changed...
+        * According to Intel App note "TLBs, Paging-Structure Caches,
+        * and Their Invalidation", April 2007, document 317080-001,
+        * section 8.1: in PAE mode we explicitly have to flush the
+        * TLB via cr3 if the top-level pgd is changed...
         *
-        * XXX I don't think we need to worry about this here, since
-        * when clearing the pud, the calling code needs to flush the
-        * tlb anyway.  But do it now for safety's sake. - jsgf
+        * Make sure the pud entry we're updating is within the
+        * current pgd to avoid unnecessary TLB flushes.
         */
-       write_cr3(read_cr3());
+       pgd = read_cr3();
+       if (__pa(pudp) >= pgd && __pa(pudp) < (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
+               write_cr3(pgd);
 }
 
 #define pud_page(pud) \