6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjiang Tu tujinjiang@huawei.com
[ Upstream commit 45d19b4b6c2d422771c29b83462d84afcbb33f01 ]
smaps_hugetlb_range() handles the pte without holdling ptl, and may be concurrenct with migration, leaing to BUG_ON in pfn_swap_entry_to_page(). The race is as follows.
smaps_hugetlb_range migrate_pages huge_ptep_get remove_migration_ptes folio_unlock pfn_swap_entry_folio BUG_ON
To fix it, hold ptl lock in smaps_hugetlb_range().
Link: https://lkml.kernel.org/r/20250724090958.455887-1-tujinjiang@huawei.com Link: https://lkml.kernel.org/r/20250724090958.455887-2-tujinjiang@huawei.com Fixes: 25ee01a2fca0 ("mm: hugetlb: proc: add hugetlb-related fields to /proc/PID/smaps") Signed-off-by: Jinjiang Tu tujinjiang@huawei.com Acked-by: David Hildenbrand david@redhat.com Cc: Andrei Vagin avagin@gmail.com Cc: Andrii Nakryiko andrii@kernel.org Cc: Baolin Wang baolin.wang@linux.alibaba.com Cc: Brahmajit Das brahmajit.xyz@gmail.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: David Rientjes rientjes@google.com Cc: Dev Jain dev.jain@arm.com Cc: Hugh Dickins hughd@google.com Cc: Joern Engel joern@logfs.org Cc: Kefeng Wang wangkefeng.wang@huawei.com Cc: Lorenzo Stoakes lorenzo.stoakes@oracle.com Cc: Michal Hocko mhocko@suse.com Cc: Ryan Roberts ryan.roberts@arm.com Cc: Thiago Jung Bauermann thiago.bauermann@linaro.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 72a58681f031..2257bf52fb2a 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1007,10 +1007,13 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask, { struct mem_size_stats *mss = walk->private; struct vm_area_struct *vma = walk->vma; - pte_t ptent = huge_ptep_get(walk->mm, addr, pte); struct folio *folio = NULL; bool present = false; + spinlock_t *ptl; + pte_t ptent;
+ ptl = huge_pte_lock(hstate_vma(vma), walk->mm, pte); + ptent = huge_ptep_get(walk->mm, addr, pte); if (pte_present(ptent)) { folio = page_folio(pte_page(ptent)); present = true; @@ -1029,6 +1032,7 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask, else mss->private_hugetlb += huge_page_size(hstate_vma(vma)); } + spin_unlock(ptl); return 0; } #else