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
next prev parent 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