mm-thp-fix-mte-tag-mismatch-when-replacing-zero-filled-subpages.patch removed from -mm tree
The quilt patch titled
Subject: mm/thp: fix MTE tag mismatch when replacing zero-filled subpages
has been removed from the -mm tree. Its filename was
mm-thp-fix-mte-tag-mismatch-when-replacing-zero-filled-subpages.patch
This patch was dropped because it was merged into the mm-hotfixes-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Lance Yang <[email protected]>
Subject: mm/thp: fix MTE tag mismatch when replacing zero-filled subpages
Date: Mon, 22 Sep 2025 10:14:58 +0800
From: Lance Yang <[email protected]>
When both THP and MTE are enabled, splitting a THP and replacing its zero-filled subpages with the shared zeropage can cause MTE tag mismatch faults in userspace.
Remapping zero-filled subpages to the shared zeropage is unsafe, as the zeropage has a fixed tag of zero, which may not match the tag expected by the userspace pointer.
KSM already avoids this problem by using memcmp_pages(), which on arm64 intentionally reports MTE-tagged pages as non-identical to prevent unsafe merging.
As suggested by David[1], this patch adopts the same pattern, replacing the memchr_inv() byte-level check with a call to pages_identical(). This leverages existing architecture-specific logic to determine if a page is truly identical to the shared zeropage.
Having both the THP shrinker and KSM rely on pages_identical() makes the design more future-proof, IMO. Instead of handling quirks in generic code, we just let the architecture decide what makes two pages identical.
[1] https://lore.kernel.org/all/[email protected]
---
mm/huge_memory.c | 15 +++------------ mm/migrate.c | 8 +------- 2 files changed, 4 insertions(+), 19 deletions(-)
mm/huge_memory.c renamed from mm/huge_memory.c~mm-thp-fix-mte-tag-mismatch-when-replacing-zero-filled-subpages +3 -12
@@ -4104,32 +4104,23 @@ static unsigned long deferred_split_counstatic bool thp_underused (struct folio *folio) {int num_zero_pages =0 , num_filled_pages =0 ; -void *kaddr;int i;if (khugepaged_max_ptes_none ==HPAGE_PMD_NR -1 )return false;for (i =0 ; i <folio_nr_pages (folio); i++) { - kaddr =kmap_local_folio (folio, i *PAGE_SIZE ); -if (!memchr_inv (kaddr,0 ,PAGE_SIZE )) { - num_zero_pages++; -if (num_zero_pages > khugepaged_max_ptes_none) { -kunmap_local (kaddr); +if (pages_identical (folio_page (folio, i),ZERO_PAGE (0 ))) { +if (++num_zero_pages > khugepaged_max_ptes_none)return true; - } }else {/* * Another path for early exit once the number * of non-zero filled pages exceeds threshold. */ - num_filled_pages++; -if (num_filled_pages >=HPAGE_PMD_NR - khugepaged_max_ptes_none) { -kunmap_local (kaddr); +if (++num_filled_pages >=HPAGE_PMD_NR - khugepaged_max_ptes_none)return false; - } } -kunmap_local (kaddr); }return false; }
mm/migrate.c renamed from mm/migrate.c~mm-thp-fix-mte-tag-mismatch-when-replacing-zero-filled-subpages +1 -7
@@ -300,9 +300,7 @@ static bool try_to_map_unused_to_zeropag unsigned long idx) {struct page *page =folio_page (folio, idx); -bool contains_data;pte_t newpte; -void *addr;if (PageCompound (page))return false;
@@ -319,11 +317,7 @@ static bool try_to_map_unused_to_zeropag* this subpage has been non present. If the subpage is only zero-filled * then map it to the shared zeropage. */ - addr =kmap_local_page (page); - contains_data =memchr_inv (addr,0 ,PAGE_SIZE ); -kunmap_local (addr); - -if (contains_data) +if (!pages_identical (page,ZERO_PAGE (0 )))return false; newpte = pte_mkspecial(pfn_pte(my_zero_pfn(pvmw->address),
_
Patches currently in -mm which might be from [email protected] are
hung_task-fix-warnings-caused-by-unaligned-lock-pointers.patch mm-khugepaged-abort-collapse-scan-on-non-swap-entries.patch