Skip to content

Commit c283610

Browse files
kiryltorvalds
authored andcommitted
x86, mm: do not leak page->ptl for pmd page tables
There are two code paths how page with pmd page table can be freed: pmd_free() and pmd_free_tlb(). I've missed the second one and didn't add page table destructor call there. It leads to leak of page->ptl for pmd page tables, if dynamically allocated page->ptl is in use. The patch adds the missed destructor and modifies documentation accordingly. Signed-off-by: Kirill A. Shutemov <[email protected]> Reported-by: Andrey Vagin <[email protected]> Tested-by: Andrey Vagin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 3a72660 commit c283610

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

Documentation/vm/split_page_table_lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ levels.
6363
PMD split lock enabling requires pgtable_pmd_page_ctor() call on PMD table
6464
allocation and pgtable_pmd_page_dtor() on freeing.
6565

66-
Allocation usually happens in pmd_alloc_one(), freeing in pmd_free(), but
67-
make sure you cover all PMD table allocation / freeing paths: i.e X86_PAE
68-
preallocate few PMDs on pgd_alloc().
66+
Allocation usually happens in pmd_alloc_one(), freeing in pmd_free() and
67+
pmd_free_tlb(), but make sure you cover all PMD table allocation / freeing
68+
paths: i.e X86_PAE preallocate few PMDs on pgd_alloc().
6969

7070
With everything in place you can set CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK.
7171

arch/x86/mm/pgtable.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
6161
#if PAGETABLE_LEVELS > 2
6262
void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
6363
{
64+
struct page *page = virt_to_page(pmd);
6465
paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT);
6566
/*
6667
* NOTE! For PAE, any changes to the top page-directory-pointer-table
@@ -69,7 +70,8 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
6970
#ifdef CONFIG_X86_PAE
7071
tlb->need_flush_all = 1;
7172
#endif
72-
tlb_remove_page(tlb, virt_to_page(pmd));
73+
pgtable_pmd_page_dtor(page);
74+
tlb_remove_page(tlb, page);
7375
}
7476

7577
#if PAGETABLE_LEVELS > 3

0 commit comments

Comments
 (0)