[PATCH 26/46] mm/mmu_gather: fix flushing ranges with 4 GiB or larger
From: David Hildenbrand (Arm)
Date: Mon Oct 26 2026 - 19:26:25 EST
From: Josef Bacik <josef@xxxxxxxxxxxxxx>
__tlb_adjust_range() takes the size of the range which has to be flushed
as an unsigned int. Its callers, tlb_flush_{pte,pmd,pud,p4d}_range(), get
and pass an unsigned long. Consequently, a range that is 4 GiB or larger
gets truncated, possibly to 0.
On arm64 with hugetlb, a 64k kernel can flush 16 GiB hugetlb PMDs, and a
16k kernel can flush 64 GiB PUDs through tlb_unshare_pmd_ptdesc(). So
at least these two scenarios are affected.
Fix it by flushing the proper range instead of the truncated one.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: b528e4b6405b ("mm/hugetlb: add tlb_remove_hugetlb_entry for handling hugetlb pages")
Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Acked-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
[ david: use two-tab indent, simplify description ]
Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
---
include/asm-generic/tlb.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index fbe1114e9a443..3f4a180b48f3c 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -350,8 +350,7 @@ struct mmu_gather {
void tlb_flush_mmu(struct mmu_gather *tlb);
static inline void __tlb_adjust_range(struct mmu_gather *tlb,
- unsigned long address,
- unsigned int range_size)
+ unsigned long address, unsigned long range_size)
{
tlb->start = min(tlb->start, address);
tlb->end = max(tlb->end, address + range_size);
--
2.43.0