linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Jianhui Zhou <jianhuizzzzz@gmail.com>
Cc: Muchun Song <muchun.song@linux.dev>,
	Oscar Salvador <osalvador@suse.de>,
	Andrew Morton <akpm@linux-foundation.org>,
	Mike Rapoport <rppt@kernel.org>,
	David Hildenbrand <david@kernel.org>,
	Andrea Arcangeli <aarcange@redhat.com>,
	Mike Kravetz <mike.kravetz@oracle.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Jonas Zhou <jonaszhou@zhaoxin.com>,
	syzbot+f525fd79634858f478e7@syzkaller.appspotmail.com,
	stable@vger.kernel.org
Subject: Re: [PATCH] mm/userfaultfd: fix hugetlb fault mutex hash calculation
Date: Fri, 6 Mar 2026 11:53:36 -0500	[thread overview]
Message-ID: <aasGkA4r56pLqNC3@x1.local> (raw)
In-Reply-To: <20260306140332.171078-1-jianhuizzzzz@gmail.com>

On Fri, Mar 06, 2026 at 10:03:32PM +0800, Jianhui Zhou wrote:
> In mfill_atomic_hugetlb(), linear_page_index() is used to calculate the
> page index for hugetlb_fault_mutex_hash(). However, linear_page_index()
> returns the index in PAGE_SIZE units, while hugetlb_fault_mutex_hash()
> expects the index in huge page units (as calculated by
> vma_hugecache_offset()). This mismatch means that different addresses
> within the same huge page can produce different hash values, leading to
> the use of different mutexes for the same huge page. This can cause
> races between faulting threads, which can corrupt the reservation map
> and trigger the BUG_ON in resv_map_release().
> 
> Fix this by replacing linear_page_index() with vma_hugecache_offset()
> and applying huge_page_mask() to align the address properly. To make
> vma_hugecache_offset() available outside of mm/hugetlb.c, move it to
> include/linux/hugetlb.h as a static inline function.
> 
> Fixes: 60d4d2d2b40e ("userfaultfd: hugetlbfs: add __mcopy_atomic_hugetlb for huge page UFFDIO_COPY")
> Reported-by: syzbot+f525fd79634858f478e7@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=f525fd79634858f478e7
> Cc: stable@vger.kernel.org
> Signed-off-by: Jianhui Zhou <jianhuizzzzz@gmail.com>

Good catch.. only one trivial comment below.

> ---
>  include/linux/hugetlb.h | 17 +++++++++++++++++
>  mm/hugetlb.c            | 11 -----------
>  mm/userfaultfd.c        |  5 ++++-
>  3 files changed, 21 insertions(+), 12 deletions(-)
> 
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index 65910437be1c..3f994f3e839c 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -796,6 +796,17 @@ static inline unsigned huge_page_shift(struct hstate *h)
>  	return h->order + PAGE_SHIFT;
>  }
>  
> +/*
> + * Convert the address within this vma to the page offset within
> + * the mapping, huge page units here.
> + */
> +static inline pgoff_t vma_hugecache_offset(struct hstate *h,
> +		struct vm_area_struct *vma, unsigned long address)
> +{
> +	return ((address - vma->vm_start) >> huge_page_shift(h)) +
> +		(vma->vm_pgoff >> huge_page_order(h));
> +}
> +
>  static inline bool order_is_gigantic(unsigned int order)
>  {
>  	return order > MAX_PAGE_ORDER;
> @@ -1197,6 +1208,12 @@ static inline unsigned int huge_page_shift(struct hstate *h)
>  	return PAGE_SHIFT;
>  }
>  
> +static inline pgoff_t vma_hugecache_offset(struct hstate *h,
> +		struct vm_area_struct *vma, unsigned long address)
> +{
> +	return linear_page_index(vma, address);
> +}

IIUC we don't need this; the userfaultfd.c reference should only happen
when CONFIG_HUGETLB_PAGE.  Please double check.

Thanks,

> +
>  static inline bool hstate_is_gigantic(struct hstate *h)
>  {
>  	return false;
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 0beb6e22bc26..b87ed652c748 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1006,17 +1006,6 @@ static long region_count(struct resv_map *resv, long f, long t)
>  	return chg;
>  }
>  
> -/*
> - * Convert the address within this vma to the page offset within
> - * the mapping, huge page units here.
> - */
> -static pgoff_t vma_hugecache_offset(struct hstate *h,
> -			struct vm_area_struct *vma, unsigned long address)
> -{
> -	return ((address - vma->vm_start) >> huge_page_shift(h)) +
> -			(vma->vm_pgoff >> huge_page_order(h));
> -}
> -
>  /**
>   * vma_kernel_pagesize - Page size granularity for this VMA.
>   * @vma: The user mapping.
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index 927086bb4a3c..8efebc47a410 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -507,6 +507,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
>  	pgoff_t idx;
>  	u32 hash;
>  	struct address_space *mapping;
> +	struct hstate *h;
>  
>  	/*
>  	 * There is no default zero huge page for all huge page sizes as
> @@ -564,6 +565,8 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
>  			goto out_unlock;
>  	}
>  
> +	h = hstate_vma(dst_vma);
> +
>  	while (src_addr < src_start + len) {
>  		VM_WARN_ON_ONCE(dst_addr >= dst_start + len);
>  
> @@ -573,7 +576,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
>  		 * in the case of shared pmds.  fault mutex prevents
>  		 * races with other faulting threads.
>  		 */
> -		idx = linear_page_index(dst_vma, dst_addr);
> +		idx = vma_hugecache_offset(h, dst_vma, dst_addr & huge_page_mask(h));
>  		mapping = dst_vma->vm_file->f_mapping;
>  		hash = hugetlb_fault_mutex_hash(mapping, idx);
>  		mutex_lock(&hugetlb_fault_mutex_table[hash]);
> -- 
> 2.43.0
> 

-- 
Peter Xu



  reply	other threads:[~2026-03-06 16:53 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-06 14:03 Jianhui Zhou
2026-03-06 16:53 ` Peter Xu [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-03-06 13:59 Jianhui Zhou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aasGkA4r56pLqNC3@x1.local \
    --to=peterx@redhat.com \
    --cc=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=jianhuizzzzz@gmail.com \
    --cc=jonaszhou@zhaoxin.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mike.kravetz@oracle.com \
    --cc=muchun.song@linux.dev \
    --cc=osalvador@suse.de \
    --cc=rppt@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=syzbot+f525fd79634858f478e7@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox