[PATCH 26/46] mm/mmu_gather: fix flushing ranges with 4 GiB or larger

Dev Jain dev.jain at arm.com
Tue Oct 27 00:35:27 PDT 2026



On 27/10/26 4:47 am, David Hildenbrand (Arm) wrote:
> From: Josef Bacik <josef at toxicpanda.com>
> 
> __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

Nit: this wasn't obvious to me. Better expressed as:
"a 64K kernel can have 16 GiB hugepage mapped contiguously at the PMD level"


> 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.

Nit: after reading this I thought you are passing some other parameter now.
But that is just a type change.


> 
> 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 at vger.kernel.org
> Signed-off-by: Josef Bacik <josef at toxicpanda.com>
> Acked-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>
> [ david: use two-tab indent, simplify description ]
> Signed-off-by: David Hildenbrand (Arm) <david at kernel.org>
> ---

Reviewed-by: Dev Jain <dev.jain at arm.com>


>  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);
> 




More information about the kexec mailing list