Re: [PATCH] mm: thp: Deny THP for guest_memfd and secretmem in file_thp_enabled()

From: Deepanshu Kartikey

Date: Tue Feb 10 2026 - 21:00:00 EST


On Wed, Feb 11, 2026 at 4:30 AM Ackerley Tng <ackerleytng@xxxxxxxxxx> wrote:
>
> "David Hildenbrand (Arm)" <david@xxxxxxxxxx> writes:
>
> >>> BUT, something just occurred to me.
> >>>
> >>> We added the mc-handling in
> >>>
> >>> commit 98c76c9f1ef7599b39bfd4bd99b8a760d4a8cd3b
> >>> Author: Jiaqi Yan <jiaqiyan@xxxxxxxxxx>
> >>> Date: Wed Mar 29 08:11:19 2023 -0700
> >>>
> >>> mm/khugepaged: recover from poisoned anonymous memory
> >>>
> >>> ..
> >>>
> >>> So I assume kernels before that would crash when collapsing?
> >>>
> >>> Looking at 5.15.199, it does not contain 98c76c9f1e [1].
> >>>
> >>> So I suspect we need a fix+stable backport.
> >>>
> >>> Who volunteers to try a secretmem reproducer on a stable kernel? :)
> >>>
> >>
> >> I could give this a shot. 5.15.199 doesn't have AS_INACCESSIBLE. Should
> >> we backport AS_INACCESSIBLE there or could the fix for 5.15.199 just be
> >> special-casing secretmem like you suggested below?
> >
> > Yes. If there is no guest_memfd we wouldn't need it.
> >
>
> Seems like on 5.15.199 there's a hugepage_vma_check(), which will return
> false since secretmem has vma->vm_ops defined [1], so secretmem VMAs are
> skipped.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/mm/khugepaged.c?h=v5.15.199#n469
>
> >>
> >>>
> >>> The following is a bit nasty as well but should do the trick until we rip
> >>> out the CONFIG_READ_ONLY_THP_FOR_FS stuff.
> >>>
> >>>
> >>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> >>> index 03886d4ccecc..4ac1cb36b861 100644
> >>> --- a/mm/huge_memory.c
> >>> +++ b/mm/huge_memory.c
> >>> @@ -40,6 +40,7 @@
> >>> #include <linux/pgalloc.h>
> >>> #include <linux/pgalloc_tag.h>
> >>> #include <linux/pagewalk.h>
> >>> +#include <linux/secretmem.h>
> >>>
> >>> #include <asm/tlb.h>
> >>> #include "internal.h"
> >>> @@ -94,6 +95,10 @@ static inline bool file_thp_enabled(struct vm_area_struct *vma)
> >>>
> >>> inode = file_inode(vma->vm_file);
> >>>
> >>> + if (mapping_inaccessible(inode->i_mapping) ||
> >>> + secretmem_mapping(inode->i_mapping))
> >>> + return false;
> >>> +
>
> Regarding checking mapping, is there any chance of racing with inode
> release? (Might the mapping be freed?)
>
> >>

I don't think so. file_thp_enabled() is called from
__thp_vma_allowable_orders(), which is reached via khugepaged,
MADV_COLLAPSE, or page faults. All these paths hold mmap_lock and
operate on a valid VMA. The VMA holds a reference to the file
(vma->vm_file), which holds a reference on the inode, so the inode
and its mapping cannot be freed while we are checking it..