From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Tal Zussman <tz2294@columbia.edu>
Cc: "Andrew Morton" <akpm@linux-foundation.org>,
"Mike Rapoport" <rppt@kernel.org>, "Peter Xu" <peterx@redhat.com>,
"James Houghton" <jthoughton@google.com>,
"Andrea Arcangeli" <aarcange@redhat.com>,
"Suren Baghdasaryan" <surenb@google.com>,
"Balbir Singh" <balbirs@nvidia.com>,
"Liam R. Howlett" <liam@infradead.org>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Jann Horn" <jannh@google.com>,
"Pedro Falcato" <pfalcato@suse.de>,
"Michał Mirosław" <mirq-linux@rere.qmqm.pl>,
"Andrei Vagin" <avagin@gmail.com>,
"Stephen Rothwell" <sfr@canb.auug.org.au>,
"Arnd Bergmann" <arnd@arndb.de>,
"Muhammad Usama Anjum" <usama.anjum@arm.com>,
"David Hildenbrand" <david@kernel.org>, "Zi Yan" <ziy@nvidia.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Joshua Hahn" <joshua.hahnjy@gmail.com>,
"Byungchul Park" <byungchul@sk.com>,
"Gregory Price" <gourry@gourry.net>,
"Ying Huang" <ying.huang@linux.alibaba.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Baolin Wang" <baolin.wang@linux.alibaba.com>,
"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>,
"Chris Down" <chris@chrisdown.name>,
"Muchun Song" <muchun.song@linux.dev>,
"Oscar Salvador" <osalvador@suse.de>,
"Mikołaj Lenczewski" <miko.lenczewski@arm.com>,
"Michal Hocko" <mhocko@suse.com>,
"Mike Kravetz" <mike.kravetz@oracle.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH 01/12] userfaultfd: use anonymous memory for UFFDIO_ZEROPAGE on private file mappings
Date: Thu, 12 Nov 2026 18:05:20 +0000 [thread overview]
Message-ID: <avX_qlthMqypxHm0@gremlin> (raw)
In-Reply-To: <20261111-uffd-state-fixes-v1-1-00713d368976@columbia.edu>
On Wed, Nov 11, 2026 at 12:55:09PM -0500, Tal Zussman wrote:
> If the mm cannot map the shared zero page, UFFDIO_ZEROPAGE falls back to
> mfill_atomic_pte_zeroed_folio(), which allocates a zeroed folio and
> installs it through vma_uffd_ops(), no matter what kind of mapping it
> is. An s390 KVM guest with storage keys or protected virtualization is
> such an mm.
>
> For a MAP_PRIVATE shmem mapping, that adds the zeroed folio to the page
> cache of the file. That is wrong: a private mapping must never modify
> the file it maps, and the file might even be mapped from a read-only fd.
>
> The ioctl can also fail where it should succeed. A missing fault is only
> delivered for a hole in the file, but UFFDIO_ZEROPAGE can be called on
> an address that did not fault, or can race with a write to the file. If
> the file has a page at that offset by then, inserting the zeroed folio
> fails and the ioctl returns -EEXIST although nothing is mapped at the
> destination address.
>
> What we want is what UFFDIO_ZEROPAGE does on a private mapping when the
> shared zero page can be used, and what UFFDIO_COPY does: only check that
> nothing is mapped at the destination address, map zeroed memory there,
> and leave the page cache alone. The zeroed folio path did that before it
> was moved to vm_uffd_ops.
>
> To fix it, pick the ops in the common folio path, as
> mfill_atomic_pte_copy() did for UFFDIO_COPY: anon_uffd_ops for a private
> mapping, the ops of the VMA otherwise. That makes
> mfill_atomic_pte_copy() and mfill_atomic_pte_zeroed_folio() redundant,
> so remove them and rename __mfill_atomic_pte() to
> mfill_atomic_pte_folio().
>
> UFFDIO_ZEROPAGE no longer modifies the file, and only fails with -EEXIST
> if something is already mapped at the destination address.
>
> Fixes: f74991b4e383 ("shmem, userfaultfd: implement shmem uffd operations using vm_uffd_ops")
> Cc: stable@vger.kernel.org
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Looks sensible (also another cleanup in disguise which I like ;):
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> mm/userfaultfd.c | 46 ++++++++++++++++------------------------------
> 1 file changed, 16 insertions(+), 30 deletions(-)
>
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index d65184d9a480..61a712e1f9f5 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -531,15 +531,27 @@ static int mfill_copy_folio_retry(struct mfill_state *mfill_state,
> return 0;
> }
>
> -static int __mfill_atomic_pte(struct mfill_state *state,
> - const struct vm_uffd_ops *ops)
> +static int mfill_atomic_pte_folio(struct mfill_state *state)
> {
> + const struct vm_uffd_ops *ops = vma_uffd_ops(state->vma);
> unsigned long dst_addr = state->dst_addr;
> unsigned long src_addr = state->src_addr;
> uffd_flags_t flags = state->flags;
> struct folio *folio;
> int ret;
>
> + /*
> + * The normal page fault path for a MAP_PRIVATE mapping in a
> + * file-backed VMA will invoke the fault, fill the hole in the file and
> + * COW it right away. The result generates plain anonymous memory.
> + * So when we are asked to fill a hole in a MAP_PRIVATE mapping, we'll
> + * generate anonymous memory directly without actually filling the
> + * hole. For the MAP_PRIVATE case the robustness check only happens in
> + * the pagetable (to verify it's still none) and not in the page cache.
> + */
> + if (!(state->vma->vm_flags & VM_SHARED))
> + ops = &anon_uffd_ops;
> +
> if (!ops) {
> VM_WARN_ONCE(1, "UFFDIO_COPY for unsupported VMA");
> return -EOPNOTSUPP;
> @@ -597,32 +609,6 @@ static int __mfill_atomic_pte(struct mfill_state *state,
> return ret;
> }
>
> -static int mfill_atomic_pte_copy(struct mfill_state *state)
> -{
> - const struct vm_uffd_ops *ops = vma_uffd_ops(state->vma);
> -
> - /*
> - * The normal page fault path for a MAP_PRIVATE mapping in a
> - * file-backed VMA will invoke the fault, fill the hole in the file and
> - * COW it right away. The result generates plain anonymous memory.
> - * So when we are asked to fill a hole in a MAP_PRIVATE mapping, we'll
> - * generate anonymous memory directly without actually filling the
> - * hole. For the MAP_PRIVATE case the robustness check only happens in
> - * the pagetable (to verify it's still none) and not in the page cache.
> - */
> - if (!(state->vma->vm_flags & VM_SHARED))
> - ops = &anon_uffd_ops;
> -
> - return __mfill_atomic_pte(state, ops);
> -}
> -
> -static int mfill_atomic_pte_zeroed_folio(struct mfill_state *state)
> -{
> - const struct vm_uffd_ops *ops = vma_uffd_ops(state->vma);
> -
> - return __mfill_atomic_pte(state, ops);
> -}
> -
> static int mfill_atomic_pte_zeropage(struct mfill_state *state)
> {
> struct vm_area_struct *dst_vma = state->vma;
> @@ -634,7 +620,7 @@ static int mfill_atomic_pte_zeropage(struct mfill_state *state)
>
> if (mm_forbids_zeropage(dst_vma->vm_mm) ||
> (dst_vma->vm_flags & VM_SHARED))
> - return mfill_atomic_pte_zeroed_folio(state);
> + return mfill_atomic_pte_folio(state);
>
> _dst_pte = pte_mkspecial(pfn_pte(zero_pfn(dst_addr),
> dst_vma->vm_page_prot));
> @@ -927,7 +913,7 @@ static __always_inline ssize_t mfill_atomic_pte(struct mfill_state *state)
> if (uffd_flags_mode_is(flags, MFILL_ATOMIC_POISON))
> return mfill_atomic_pte_poison(state);
> if (uffd_flags_mode_is(flags, MFILL_ATOMIC_COPY))
> - return mfill_atomic_pte_copy(state);
> + return mfill_atomic_pte_folio(state);
> if (uffd_flags_mode_is(flags, MFILL_ATOMIC_ZEROPAGE))
> return mfill_atomic_pte_zeropage(state);
>
>
> --
> 2.39.5
>
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-11-12 18:05 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 17:55 [PATCH 00/12] userfaultfd: assorted fixes (part 1) Tal Zussman
2026-11-11 17:55 ` [PATCH 01/12] userfaultfd: use anonymous memory for UFFDIO_ZEROPAGE on private file mappings Tal Zussman
2026-11-12 18:05 ` Lorenzo Stoakes (ARM) [this message]
2026-11-11 17:55 ` [PATCH 02/12] userfaultfd: refuse UFFDIO_MOVE into a non-present huge destination PMD Tal Zussman
2026-11-12 17:56 ` sashiko-bot
2026-11-12 18:07 ` Lorenzo Stoakes (ARM)
2026-11-11 17:55 ` [PATCH 03/12] fs/proc/task_mmu: downgrade writable migration entries in PAGEMAP_SCAN write-protect Tal Zussman
2026-11-12 18:34 ` Lorenzo Stoakes (ARM)
2026-11-11 17:55 ` [PATCH 04/12] mm/migrate: keep the uffd bit when restoring a writable migration entry Tal Zussman
2026-11-12 18:44 ` Lorenzo Stoakes (ARM)
2026-11-11 17:55 ` [PATCH 05/12] fs/proc/task_mmu: write-protect device-private THPs in PAGEMAP_SCAN Tal Zussman
2026-11-12 19:34 ` Lorenzo Stoakes (ARM)
2026-11-11 17:55 ` [PATCH 06/12] mm/huge_memory: build the moved huge zero PMD from the destination VMA Tal Zussman
2026-11-11 19:12 ` Kiryl Shutsemau
2026-11-12 17:57 ` sashiko-bot
2026-11-11 17:55 ` [PATCH 07/12] mm/mremap: resolve uffd state when the context is dropped, not during the move Tal Zussman
2026-11-11 19:20 ` Kiryl Shutsemau
2026-11-11 22:39 ` Tal Zussman
2026-11-12 11:44 ` Lorenzo Stoakes (ARM)
2026-11-12 16:00 ` Tal Zussman
2026-11-12 17:57 ` sashiko-bot
2026-11-11 17:55 ` [PATCH 08/12] mm/migrate_device: do not migrate a uffd-protected zero page Tal Zussman
2026-11-11 17:55 ` [PATCH 09/12] mm/madvise: let a guard marker carry the uffd-wp bit Tal Zussman
2026-11-12 11:21 ` Lorenzo Stoakes (ARM)
2026-11-12 16:06 ` Tal Zussman
2026-11-11 17:55 ` [PATCH 10/12] mm: set the uffd-wp bit on a guard marker when write-protecting Tal Zussman
2026-11-12 11:43 ` Lorenzo Stoakes (ARM)
2026-11-11 17:55 ` [PATCH 11/12] mm/madvise: send UFFD_EVENT_REMOVE when installing guard regions Tal Zussman
2026-11-11 19:25 ` Kiryl Shutsemau
2026-11-11 23:21 ` Tal Zussman
2026-11-12 9:40 ` Jose A. Perez de Azpillaga
2026-11-12 11:57 ` Kiryl Shutsemau
2026-11-12 11:03 ` Lorenzo Stoakes (ARM)
2026-11-12 11:06 ` Lorenzo Stoakes (ARM)
2026-11-12 15:56 ` Tal Zussman
2026-11-12 17:57 ` sashiko-bot
2026-11-11 17:55 ` [PATCH 12/12] mm/userfaultfd: check hugetlb end alignment in UFFDIO_UNREGISTER pre-scan Tal Zussman
2026-11-12 19:52 ` Lorenzo Stoakes (ARM)
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=avX_qlthMqypxHm0@gremlin \
--to=ljs@kernel.org \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=arnd@arndb.de \
--cc=avagin@gmail.com \
--cc=balbirs@nvidia.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=byungchul@sk.com \
--cc=chris@chrisdown.name \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=gourry@gourry.net \
--cc=jannh@google.com \
--cc=joshua.hahnjy@gmail.com \
--cc=jthoughton@google.com \
--cc=kas@kernel.org \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matthew.brost@intel.com \
--cc=mhocko@suse.com \
--cc=mike.kravetz@oracle.com \
--cc=miko.lenczewski@arm.com \
--cc=mirq-linux@rere.qmqm.pl \
--cc=muchun.song@linux.dev \
--cc=nico.pache@linux.dev \
--cc=osalvador@suse.de \
--cc=peterx@redhat.com \
--cc=pfalcato@suse.de \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=sfr@canb.auug.org.au \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=tz2294@columbia.edu \
--cc=usama.anjum@arm.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=ying.huang@linux.alibaba.com \
--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.