Skip to content

Commit 83a8441

Browse files
author
Matthew Wilcox (Oracle)
committed
mm/huge_memory: Avoid calling pmd_page() on a non-leaf PMD
Calling try_to_unmap() with TTU_SPLIT_HUGE_PMD and a folio that's not mapped by a PMD causes oopses on arm64 because we now call page_folio() on an invalid page. pmd_page() returns a valid page for non-leaf PMDs on some architectures, so this bug escaped testing before now. Fix this bug by delaying the call to pmd_page() until after we know the PMD is a leaf. Link: https://bugzilla.kernel.org/show_bug.cgi?id=215804 Fixes: af28a98 ("mm/huge_memory: Convert __split_huge_pmd() to take a folio") Reported-by: Zorro Lang <zlang@redhat.com> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Tested-by: Zorro Lang <zlang@redhat.com>
1 parent 3e732eb commit 83a8441

1 file changed

Lines changed: 5 additions & 6 deletions

File tree

mm/huge_memory.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,15 +2145,14 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
21452145
* pmd against. Otherwise we can end up replacing wrong folio.
21462146
*/
21472147
VM_BUG_ON(freeze && !folio);
2148-
if (folio) {
2149-
VM_WARN_ON_ONCE(!folio_test_locked(folio));
2150-
if (folio != page_folio(pmd_page(*pmd)))
2151-
goto out;
2152-
}
2148+
VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));
21532149

21542150
if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
2155-
is_pmd_migration_entry(*pmd))
2151+
is_pmd_migration_entry(*pmd)) {
2152+
if (folio && folio != page_folio(pmd_page(*pmd)))
2153+
goto out;
21562154
__split_huge_pmd_locked(vma, pmd, range.start, freeze);
2155+
}
21572156

21582157
out:
21592158
spin_unlock(ptl);

0 commit comments

Comments
 (0)