Re: [PATCH v2] mm/khugepaged: Don't install PMDs in uffd-minor-registered VMAs

From: James Houghton

Date: Fri Aug 28 2026 - 21:10:35 EST


On Fri, Aug 28, 2026 at 5:33 PM Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> On Fri, 28 Aug 2026 22:26:40 +0000 James Houghton <jthoughton@xxxxxxxxxx> wrote:
>
> > Userfaultfd minor faults provides userspace with the ability to manually
> > install PTEs with UFFDIO_CONTINUE. Right now, khugepaged collapse can
> > map holes in the VMA when a naturally-aligned THP is present without
> > explicit action from userspace.
> >
> > This is a problem, as it bypasses userfaultfd minor faults that
> > userspace is expecting to handle.
> >
> > If userspace implements post-copy live migration using userfaultfd minor
> > faults, this situation is currently possible:
> > 1. The VMA for guest memory is userfaultfd-minor-registered and nothing
> > is mapped in the page tables.
> > 2. A stale copy of a page is present in a naturally-aligned THP (from
> > pre-copy live migration).
> > 3. khugepaged collapses the mapping of the THP, installs a PMD.
> > 4. The VM now has access to the stale contents => VM is broken.
> > 5. After installing the correct contents, userspace attempts to map the
> > page with UFFDIO_CONTINUE; it gets EEXIST, indicating that something
> > unexpectedly mapped the page.
>
> Did I read somewhere that this it biting you in a real-life scenario?
> That would use useful info to spell out.
>
> Or is this a theoretical thing?

So far it is only theoretical (but please do keep reading). I caught
this while debugging a related, real problem.

The real problem was that userspace was doing MADV_COLLAPSE (*without*
userfaultfd registered) and assuming that page tables wouldn't be
created. This is of course incorrect, but for some reason we only
started hitting this after moving from a 6.6-based kernel to a
6.18-based kernel. I don't know what change caused this (most likely a
downstream change), but the real fix was for userspace to instead do
something like:
1. MADV_COLLAPSE (let's assume this must be done)
2. UFFD_REGISTER_MODE_MINOR
3. MADV_DONTNEED
and we're good to go, right? Wrong, in fact!

I noticed that there was indeed a circumstance where khugepaged could
create PMDs even when userfaultfd *was* registered, making the
userspace fix technically incomplete. That's what this patch fixes.

I haven't yet seen this in our production environment (as far as I am
aware, hence "theoretical"); we don't actually have that many VMs
running a userfaultfd-based live migration stack anymore though (maybe
tens of thousands).

I hope that extra context is helpful.

> > The naturally-aligned THP case is the only case where this is a problem.
> > khugepaged otherwise requires all PTEs to be present for
> > userfaultfd-registered VMAs (i.e., max none PTEs is 0), which is
> > correct. This check is essentially bypassed for naturally-aligned THPs.
> >
> > No changes are needed for file_backed_vma_is_retractable(), as zapping
> > PTEs is safe. Userspace must already handle cases where PTEs are zapped
> > without explicit action (e.g. due to reclaim).
> >
> > Fixes: 58ac9a8993a1 ("mm/khugepaged: attempt to map file/shmem-backed pte-mapped THPs by pmds")
> > Cc: <stable@xxxxxxxxxxxxxxx> # 6.1
>
> From the changelog it isn't clear why a -stable backport is proposed?
> I assume the userspace-visible runtime effect is a rare and bogus
> -EEXIST from UFFDIO_CONTINUE?

Although this bug is likely pretty inconsequential (I'm not sure how
many users of userfaultfd minor faults there are), but rarely getting
EEXIST back when UFFDIO_CONTINUE is a userspace-visible bug that
doesn't really have a great workaround.

Because this bug essentially breaks userfaultfd minor faults,
*technically* live migration implemented with it can sometimes corrupt
guest memory, and the hypervisor (like QEMU, but QEMU doesn't use
minor faults) only learns about it after the fact, after we get EEXIST
back. IMO this is enough to backport the patch to stable. But if
others disagree, I don't really mind.

>
> > Suggested-by: Lance Yang <lance.yang@xxxxxxxxx>
> > Tested-by: Lance Yang <lance.yang@xxxxxxxxx>
>
> Wondering what Lance tested. Was he able to reproduce the bug?

I assume he just re-ran my repro, but yeah I'm not sure, heh. Lance,
what did you test?

> Sashiko might have found another race in there:
>
> https://sashiko.dev/#/patchset/20260828222640.1638457-1-jthoughton@xxxxxxxxxx

Let me get back to you on this. Best case, I'll send another
(separate) patch. :)