Re: [PATCH] mm: prepare anon_vma before swapin rmap

David Hildenbrand (Arm)
2026-04-17T10:53:43Z

On 4/17/26 03:16, ZhengYuan Huang wrote:
> [BUG]
> madvise(MADV_HWPOISON) can fault a swap entry back in through
> get_user_pages_fast() and hit:
>
> kernel BUG at mm/rmap.c:1364!
> Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
> RIP: 0010:__folio_set_anon mm/rmap.c:1364 [inline]
> RIP: 0010:folio_add_new_anon_rmap+0x41d/0xc10 mm/rmap.c:1553
> Call Trace:
> do_swap_page+0x14c5/0x5c30 mm/memory.c:4963
> handle_pte_fault mm/memory.c:6198 [inline]
> __handle_mm_fault+0x1512/0x22f0 mm/memory.c:6336
> handle_mm_fault+0x42f/0x820 mm/memory.c:6505
> faultin_page mm/gup.c:1126 [inline]
> __get_user_pages+0x4b3/0x3400 mm/gup.c:1428
> __get_user_pages_locked mm/gup.c:1692 [inline]
> __gup_longterm_locked+0x945/0x14b0 mm/gup.c:2476
> gup_fast_fallback+0x8a3/0x2440 mm/gup.c:3220
> get_user_pages_fast+0x64/0xb0 mm/gup.c:3298
> madvise_inject_error mm/madvise.c:1456 [inline]
> madvise_do_behavior+0x503/0x860 mm/madvise.c:1875
> do_madvise+0x17e/0x210 mm/madvise.c:1978
> __do_sys_madvise mm/madvise.c:1987 [inline]
> __se_sys_madvise mm/madvise.c:1985 [inline]
> __x64_sys_madvise+0xae/0x120 mm/madvise.c:1985
> ...
>
> [CAUSE]
> Commit a373baed5a9d ("mm: delay the check for a NULL anon_vma") moved
> anon_vma preparation out of the generic fault path and into the fault
> handlers that actually need to install anonymous rmap state.
>
> do_swap_page() was left behind. It can still restore anonymous mappings
> via folio_add_new_anon_rmap() or folio_add_anon_rmap_ptes(), but it does
> not call vmf_anon_prepare() first. On a VMA-lock fault this can leave
> vma->anon_vma NULL all the way down to __folio_set_anon(), which BUG_ONs
> on that violated invariant.
>
> [FIX]
> Prepare the faulting VMA's anon_vma once do_swap_page() has confirmed it
> is handling a real swap entry, before any swapin path can install
> anonymous rmap state.
>
> vmf_anon_prepare() already handles the retry rules for VMA-lock faults,
> and when anon_vma is already present this stays a single likely branch in
> the swap fault hot path.
>
> Fixes: a373baed5a9d ("mm: delay the check for a NULL anon_vma")
> Signed-off-by: ZhengYuan Huang <gality369@gmail.com>
> ---
> I can reproduce this issue deterministically on v6.18, but I have not
> been able to reproduce it with the same setup on next-20260415.
>
> However, I have not identified a change that clearly explains the
> difference. From code inspection, do_swap_page() still appears able to
> reach folio_add_new_anon_rmap()/folio_add_anon_rmap_ptes() without a
> prior vmf_anon_prepare()

If there is an anon page swapped out, certainly at the allocation time
of that anon folio, there would have to be a anon_rmap allocated.

During fork, the anon_rmap would have to be created as well.

Something is off here.

--
Cheers,

David