FAILED: patch "[PATCH] mm: khugepaged: fix folio is used after pte_unmap_unlock()" failed to apply to 5.10-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x ba2f1f92ddfabd340c9248fd2380104f717ee8b1
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110424-quaintly-refined-4f82@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ba2f1f92ddfabd340c9248fd2380104f717ee8b1 Mon Sep 17 00:00:00 2001
From: Vernon Yang <[email protected]>
Date: Wed, 9 Sep 2026 10:58:02 +0800
Subject: [PATCH] mm: khugepaged: fix folio is used after pte_unmap_unlock()
After the page table lock has dropped, the folio can be freed concurrently. The trace_mm_khugepaged_scan_pmd() is left with a dangling folio pointer.
So using the folio_pfn() before dropping the page table lock, closing use-after-free window.
And other pre-existing bug, When the for (i = 0; i < HPAGE_PMD_NR; i++) iteration to terminate and the folio operation preceding is normal, but pfn will be incorrect. so we really only trace the PFN if it really was problematic.
include/trace/events/huge_memory.h +3 -3
@@ -55,10 +55,10 @@ SCAN_STATUS TRACE_EVENT(mm_khugepaged_scan_pmd, - TP_PROTO(struct mm_struct *mm, struct folio *folio, + TP_PROTO(struct mm_struct *mm, unsigned long pfn, int referenced, int none_or_zero, int status, int unmapped), - TP_ARGS(mm, folio, referenced, none_or_zero, status, unmapped), + TP_ARGS(mm, pfn, referenced, none_or_zero, status, unmapped), TP_STRUCT__entry( __field(struct mm_struct *, mm)
@@ -71,7 +71,7 @@ TRACE_EVENT(mm_khugepaged_scan_pmd,TP_fast_assign ( __entry->mm = mm; - __entry->pfn = folio ?folio_pfn (folio) :-1 ; + __entry->pfn = pfn; __entry->referenced = referenced; __entry->none_or_zero = none_or_zero; __entry->status = status;
mm/khugepaged.c +9 -1
@@ -1612,6 +1612,7 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm,enum scan_result result =SCAN_FAIL ;struct page *page =NULL ;struct folio *folio =NULL ; +unsigned long failed_pfn =-1 ;unsigned long addr;unsigned long enabled_orders;spinlock_t *ptl;
@@ -1706,11 +1707,13 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm,if (cc->is_khugepaged && !(vma->vm_flags &VM_DROPPABLE ) &&folio_test_lazyfree (folio) && !pte_dirty (pteval)) { result =SCAN_PAGE_LAZYFREE ; + failed_pfn =folio_pfn (folio); goto out_unmap; }if (!folio_test_anon (folio)) { result =SCAN_PAGE_ANON ; + failed_pfn =folio_pfn (folio); goto out_unmap; }
@@ -1721,6 +1724,7 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm,if (folio_maybe_mapped_shared (folio)) {if (++shared > max_ptes_shared) { result =SCAN_EXCEED_SHARED_PTE ; + failed_pfn =folio_pfn (folio);count_collapse_event (HPAGE_PMD_ORDER ,THP_SCAN_EXCEED_SHARED_PTE ,MTHP_STAT_COLLAPSE_EXCEED_SHARED ); goto out_unmap;
@@ -1738,15 +1742,18 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, node =folio_nid (folio);if (collapse_scan_abort (node, cc)) { result =SCAN_SCAN_ABORT ; + failed_pfn =folio_pfn (folio); goto out_unmap; } cc->node_load[node]++;if (!folio_test_lru (folio)) { result =SCAN_PAGE_LRU ; + failed_pfn =folio_pfn (folio); goto out_unmap; }if (folio_test_locked (folio)) { result =SCAN_PAGE_LOCK ; + failed_pfn =folio_pfn (folio); goto out_unmap; }
@@ -1759,6 +1766,7 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm,*/ if (folio_expected_ref_count (folio) !=folio_ref_count (folio)) { result =SCAN_PAGE_COUNT ; + failed_pfn =folio_pfn (folio); goto out_unmap; }
@@ -1784,7 +1792,7 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, *lock_dropped = true; } out: -trace_mm_khugepaged_scan_pmd (mm, folio, referenced, +trace_mm_khugepaged_scan_pmd (mm, failed_pfn, referenced, none_or_zero, result, unmapped);return result; }