From: "David Hildenbrand (Arm)" <david@kernel.org>
To: Konstantin Khorenko <khorenko@virtuozzo.com>,
Andrew Morton <akpm@linux-foundation.org>,
Zi Yan <ziy@nvidia.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
"Liam R. Howlett" <liam@infradead.org>,
Nico Pache <nico.pache@linux.dev>,
Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
Barry Song <baohua@kernel.org>, Lance Yang <lance.yang@linux.dev>,
Usama Arif <usama.arif@linux.dev>,
Kiryl Shutsemau <kas@kernel.org>, Peter Xu <peterx@redhat.com>
Cc: "Alex Williamson" <alex@shazbot.org>,
kvm@vger.kernel.org,
"Loïc Molinari" <loic.molinari@collabora.com>,
dri-devel@lists.freedesktop.org,
"Madhavan Srinivasan" <maddy@linux.ibm.com>,
"Ritesh Harjani (IBM)" <ritesh.list@gmail.com>,
linuxppc-dev@lists.ozlabs.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, "Jason Gunthorpe" <jgg@ziepe.ca>,
stable@vger.kernel.org
Subject: Re: [PATCH v3 1/2] mm/huge_memory: recheck a special PMD under the lock in copy_huge_pmd()
Date: Thu, 15 Oct 2026 16:14:07 +0200 [thread overview]
Message-ID: <5800bc6e-7671-41eb-bb09-7fbc8f2d085c@kernel.org> (raw)
In-Reply-To: <20261014-b4-prep-vstor-149847-copy_huge_pmd-recheck-special-pmd-v3-1-85eaec8417f6@virtuozzo.com>
On 10/14/26 17:46, Konstantin Khorenko wrote:
> copy_huge_pmd() reads a special PMD without the page table lock and
> copies that value to the child. The mmap write lock held by fork does
> not stop unmap_mapping_range(): it zaps under i_mmap_rwsem and the PMD
> lock.
For a special PMD (that is not the huge zero folio), we need to go through
vmf_insert_pfn_pmd()->insert_pmd().
I would have thought that unmap_mapping_pages() is only called in corner cases
when we would have concurrent fork().
Like vfio_pci_zap_bars().
But yeah, likely there is a theoretical race.
>
> The zap visits the parent VMA before the child's, as dup_mmap() links
> the child right after the parent in i_mmap. If it clears the parent PMD
> after fork has read it, and passes the child before fork copies it, the
> child keeps a mapping the driver has revoked:
>
> - vfio-pci: the child reaches the BAR after the device memory was
> disabled or the device was reset, instead of getting SIGBUS;
> - panthor: the child maps the pages of an evicted buffer object after
> they are freed.
>
> Read the PMD again under the source PMD lock, which the zap takes to
> clear it. Either the zap got there first, and the PMD is none, or the
> copy is in place before the zap reaches the child. Faults are locked
> out, so only a zap can change the PMD, and pmd_none() is the test.
>
> Fixes: bc02afbd4d73 ("mm/fork: accept huge pfnmap entries")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
> ---
> mm/huge_memory.c | 23 ++++++++++++++++-------
> 1 file changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 1e5d68acf62a5..bf788bb231691 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -1965,13 +1965,22 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
> src_ptl = pmd_lockptr(src_mm, src_pmd);
> spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
> /*
> - * No need to recheck the pmd, it can't change with write
> - * mmap lock held here.
> - *
> - * Meanwhile, making sure it's not a CoW VMA with writable
> - * mapping, otherwise it means either the anon page wrongly
> - * applied special bit, or we made the PRIVATE mapping be
> - * able to wrongly write to the backend MMIO.
> + * The mmap and VMA write locks of the source keep faults
> + * out, but unmap_mapping_range() does not take the mmap
> + * lock and may have cleared the pmd since the lockless
> + * read. Let copy_pmd_range() skip it then.
> + */
TBH, I think we can drop this comment entirely. That's just simply the right
thing to do? :)
> + pmd = pmdp_get(src_pmd);
> + if (unlikely(pmd_none(pmd))) {
> + spin_unlock(src_ptl);
> + spin_unlock(dst_ptl);
> + return -EAGAIN;
> + }
> + /*
> + * Make sure it's not a CoW VMA with writable mapping,
> + * otherwise it means either the anon page wrongly applied
> + * special bit, or we made the PRIVATE mapping be able to
> + * wrongly write to the backend MMIO.
> */
> VM_WARN_ON_ONCE(vma_is_cow_mapping(src_vma) && pmd_write(pmd));
> goto set_pmd;
>
But why do we do this early copy dance *at all*? I think I complained about this
vma_is_anonymous handling in the past. vma_needs_copy() is the one deciding
whether something should get copied or not.
So, can't we just get rid of the vma_is_anonymous() handling and perform the
weird special-pte check (that I hate entirely) when already holding the PTL?
--
Cheers,
David
next prev parent reply other threads:[~2026-10-15 14:14 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 15:46 [PATCH v3 0/2] mm/huge_memory: fix the copy of special PMDs at fork Konstantin Khorenko
2026-10-14 15:46 ` [PATCH v3 1/2] mm/huge_memory: recheck a special PMD under the lock in copy_huge_pmd() Konstantin Khorenko
2026-10-15 14:14 ` David Hildenbrand (Arm) [this message]
2026-10-14 15:46 ` [PATCH v3 2/2] mm/huge_memory: deposit a page table for a special PMD copied by fork Konstantin Khorenko
2026-10-15 14:15 ` David Hildenbrand (Arm)
2026-10-14 15:57 ` [PATCH v3 0/2] mm/huge_memory: fix the copy of special PMDs at fork Zi Yan
2026-10-14 16:04 ` Lance Yang
2026-10-15 11:49 ` Konstantin Khorenko
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=5800bc6e-7671-41eb-bb09-7fbc8f2d085c@kernel.org \
--to=david@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alex@shazbot.org \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=dev.jain@arm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jgg@ziepe.ca \
--cc=kas@kernel.org \
--cc=khorenko@virtuozzo.com \
--cc=kvm@vger.kernel.org \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=loic.molinari@collabora.com \
--cc=maddy@linux.ibm.com \
--cc=nico.pache@linux.dev \
--cc=peterx@redhat.com \
--cc=ritesh.list@gmail.com \
--cc=ryan.roberts@arm.com \
--cc=stable@vger.kernel.org \
--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.