From: Lance Yang <lance.yang@linux.dev>
To: akpm@linux-foundation.org
Cc: lance.yang@linux.dev, david@kernel.org, ziy@nvidia.com,
baolin.wang@linux.alibaba.com, liam@infradead.org,
nico.pache@linux.dev, ryan.roberts@arm.com, dev.jain@arm.com,
baohua@kernel.org, usama.arif@linux.dev, kas@kernel.org,
ljs@kernel.org, surenb@google.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH 1/1] mm/huge_memory: fix pgtable withdrawal for huge zero PMDs
Date: Sun, 13 Sep 2026 15:23:12 +0800 [thread overview]
Message-ID: <20260913072312.52111-1-lance.yang@linux.dev> (raw)
In-Reply-To: <20260912234635.db50397364858aa15f58f4d7@linux-foundation.org>
On Sat, Sep 12, 2026 at 11:46:35PM -0700, Andrew Morton wrote:
>On Sun, 13 Sep 2026 13:19:42 +0800 Lance Yang <lance.yang@linux.dev> wrote:
>
>> From: Lance Yang <lance.yang@linux.dev>
>>
>> has_deposited_pgtable() uses !vma_is_dax() to decide whether a huge zero
>> PMD has a deposited PTE page table. That also accepts raw PFN mappings
>> of huge_zero_pfn, although vmf_insert_pfn_pmd() does not deposit a page
>> table on x86.
>>
>> Zapping such a mapping would call pgtable_trans_huge_withdraw() without
>> a corresponding deposit. With pmd_huge_pte(mm, pmd) == NULL, that causes
>> a NULL pointer dereference.
>
>That's the sort of thing we'd prefer to avoid.
>
>> Use vma_is_anonymous() for the huge zero PMD check. This matches how PTE
>> page tables are allocated, deposited and moved.
>>
>> - For anonymous page faults that install a huge zero PMD,
>> do_huge_pmd_anonymous_page() allocates a PTE page table and
>> set_huge_zero_folio() deposits it before installing the PMD.
>>
>> - On fork, copy_huge_pmd() allocates and deposits a PTE page table when
>> copying a huge zero PMD into an anonymous VMA.
>>
>> - Raw PFN mappings use vmf_insert_pfn_pmd(), and DAX file holes use
>> vmf_insert_folio_pmd() to map the huge zero folio. Both use insert_pmd(),
>> which deposits a PTE page table only when arch_needs_pgtable_deposit()
>> requires it.
>>
>> - Moving an anonymous huge PMD preserves its deposited PTE page table.
>> move_huge_pmd() transfers the deposit when necessary. For UFFD MOVE,
>> both VMAs must be anonymous, and move_pages_huge_pmd() transfers the
>> deposit as well.
>>
>> Keep arch_needs_pgtable_deposit() first so architectures that require a
>> deposited PTE page table still return true regardless of the VMA type.
>>
>> Commit d80a9cb1a64a ("mm/huge_memory: add and use
>> normal_or_softleaf_folio_pmd()") removed the vma_is_special_huge() check
>> in zap_huge_pmd(). That check skipped the huge zero PMD deposit test for
>> non-DAX VM_PFNMAP and VM_MIXEDMAP mappings. Removing it exposed these
>> mappings to the incorrect !vma_is_dax() test.
>>
>> Fixes: d80a9cb1a64a ("mm/huge_memory: add and use normal_or_softleaf_folio_pmd()")
>> Cc: stable@vger.kernel.org
>
>How real is this? Is there a reported-by:? Do you have a reproducer?
Yes, I reproduced it on x86 with a small test module. It sets
VM_MIXEDMAP | VM_HUGEPAGE and calls vmf_insert_pfn_pmd() with
huge_zero_pfn, without touching the page tables directly. A full-PMD
munmap() crashes before the split series[1] as well.
>Is it a theoretical, LLM-found-this thing which can't really happen?
I found this while reviewing the split series with LLM assistance.
mshv_vtl_low derives the PFN from the mmap offset, and its checks do not
exclude huge_zero_pfn. I haven't tested this on a Hyper-V, though.
[1] https://lore.kernel.org/linux-mm/cover.1787941780.git.yintirui@gmail.com/
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -2529,11 +2529,11 @@ static bool has_deposited_pgtable(struct vm_area_struct *vma, pmd_t pmdval,
>> return true;
>>
>> /*
>> - * Huge zero always deposited except for DAX which handles itself, see
>> - * set_huge_zero_folio().
>> + * Huge zero PMDs have a deposited page table only for anonymous VMAs,
>> + * see set_huge_zero_folio().
>> */
>> if (is_huge_zero_pmd(pmdval))
>> - return !vma_is_dax(vma);
>> + return vma_is_anonymous(vma);
>>
>> /*
>> * Otherwise, only anonymous folios are deposited, see
>
>Thanks, I'll add it for test-n-review.
Thanks!
prev parent reply other threads:[~2026-09-13 7:23 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-13 5:19 [PATCH 1/1] mm/huge_memory: fix pgtable withdrawal for huge zero PMDs Lance Yang
2026-09-13 6:46 ` Andrew Morton
2026-09-13 7:23 ` Lance Yang [this message]
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=20260913072312.52111-1-lance.yang@linux.dev \
--to=lance.yang@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=kas@kernel.org \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=nico.pache@linux.dev \
--cc=ryan.roberts@arm.com \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=ziy@nvidia.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.