aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/pgtable-3level.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86/pgtable-3level.h')
-rw-r--r--include/asm-x86/pgtable-3level.h26
1 files changed, 11 insertions, 15 deletions
diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
index a195c3e757b9..1d763eec740f 100644
--- a/include/asm-x86/pgtable-3level.h
+++ b/include/asm-x86/pgtable-3level.h
@@ -93,26 +93,22 @@ static inline void native_pmd_clear(pmd_t *pmd)
93 93
94static inline void pud_clear(pud_t *pudp) 94static inline void pud_clear(pud_t *pudp)
95{ 95{
96 unsigned long pgd;
97
96 set_pud(pudp, __pud(0)); 98 set_pud(pudp, __pud(0));
97 99
98 /* 100 /*
99 * In principle we need to do a cr3 reload here to make sure 101 * According to Intel App note "TLBs, Paging-Structure Caches,
100 * the processor recognizes the changed pgd. In practice, all 102 * and Their Invalidation", April 2007, document 317080-001,
101 * the places where pud_clear() gets called are followed by 103 * section 8.1: in PAE mode we explicitly have to flush the
102 * full tlb flushes anyway, so we can defer the cost here. 104 * TLB via cr3 if the top-level pgd is changed...
103 *
104 * Specifically:
105 *
106 * mm/memory.c:free_pmd_range() - immediately after the
107 * pud_clear() it does a pmd_free_tlb(). We change the
108 * mmu_gather structure to do a full tlb flush (which has the
109 * effect of reloading cr3) when the pagetable free is
110 * complete.
111 * 105 *
112 * arch/x86/mm/hugetlbpage.c:huge_pmd_unshare() - the call to 106 * Make sure the pud entry we're updating is within the
113 * this is followed by a flush_tlb_range, which on x86 does a 107 * current pgd to avoid unnecessary TLB flushes.
114 * full tlb flush.
115 */ 108 */
109 pgd = read_cr3();
110 if (__pa(pudp) >= pgd && __pa(pudp) < (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
111 write_cr3(pgd);
116} 112}
117 113
118#define pud_page(pud) \ 114#define pud_page(pud) \