<feed xmlns='http://www.w3.org/2005/Atom'>
<title>wireguard-linux/mm, branch stable</title>
<subtitle>WireGuard for the Linux kernel</subtitle>
<id>https://git.zx2c4.com/wireguard-linux/atom/mm?h=stable</id>
<link rel='self' href='https://git.zx2c4.com/wireguard-linux/atom/mm?h=stable'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/'/>
<updated>2026-09-29T03:11:31Z</updated>
<entry>
<title>Merge tag 'mm-hotfixes-stable-2026-09-27-19-12' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm</title>
<updated>2026-09-29T03:11:31Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-09-29T03:11:31Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=6f8319e3e9a44dd537d17f41565a8453c560a581'/>
<id>urn:sha1:6f8319e3e9a44dd537d17f41565a8453c560a581</id>
<content type='text'>
Pull MM fixes from Andrew Morton:

 - Fix module loading incorrectly returning success after alloc_tag
   codetag setup failed

 - Restore MADV_COLLAPSE semantics for shmem so forced collapse ignores
   the shmem THP/mTHP sysfs settings

 - Make alloc_tag UAPI structure padding explicit

 - Fix DAMON schemes unexpectedly stopping after quotas are disabled
   through the online parameter update interface

 - Fix a false SW_TAGS KASAN invalid-access report when freeing vmapped
   task stacks

 - Split the MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION MAINTAINERS
   entry into separate MIGRATION and NUMA PLACEMENT entries

 - Move memory tiering maintenance under NUMA PLACEMENT

 - Add Gregory Price as a NUMA PLACEMENT co-maintainer

 - Add Heming Zhao as an ocfs2 reviewer

 - Fix mmap_prepare() state being copied onto a merged VMA rather than
   only onto a newly allocated VMA

* tag 'mm-hotfixes-stable-2026-09-27-19-12' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  mm/vma: predicate setting mmap_prepare VMA fields on new vma alloc
  MAINTAINERS: add Heming Zhao as ocfs2 reviewer
  MAINTAINERS: make Gregory a co-maintainer of MEMORY MANAGEMENT - NUMA PLACEMENT
  MAINTAINERS: move memory tiering under MEMORY MANAGEMENT - NUMA PLACEMENT
  MAINTAINERS: split up MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION
  kasan: unpoison task stack below watermark only in generic mode
  mm/damon/core: don't skip damos_adjust_quota() while esz is not zero
  alloc_tag: avoid implicit padding in uapi
  mm: shmem: ignore sysfs configs for shmem forced collapse
  module: fix lost error code from codetag_load_module()
</content>
</entry>
<entry>
<title>mm/vma: predicate setting mmap_prepare VMA fields on new vma alloc</title>
<updated>2026-09-26T20:55:11Z</updated>
<author>
<name>Lorenzo Stoakes (ARM)</name>
<email>ljs@kernel.org</email>
</author>
<published>2026-09-23T17:45:41Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=976d5e0ddac885b0219252f004f6c561c344df9d'/>
<id>urn:sha1:976d5e0ddac885b0219252f004f6c561c344df9d</id>
<content type='text'>
It only makes sense to manipulate VMA fields if a new VMA was allocated,
rather than merged.

VMA merging does not compare vm_ops or vm_private_data, so a merged VMA
keeps its own, which is also what the legacy f_op-&gt;mmap path does since it
never touches an existing VMA.

Currently, these fields will get overwritten by whatever state is
established in the mmap_prepare hook, and if the VMA was merged,
vm_ops-&gt;mapped will not have been called, so this could destructively
clear existing state without replacing it with anything valid.

There is an implicit requirement that vm_private_data and vm_ops are
fungible across VMAs which means that losing the 'new' state is fine.

However in this case the 'old' state is being overwritten by potentially
invalid 'new' state, so this must be rectified.

Additionally constify have_mmap_prepare while here.

All existing in-tree users either derive state from the file or are
unmergeable due to VMA flags, so this has no direct impact.

Link: https://lore.kernel.org/20260923-fix-mmap-prepare-overwrite-v1-1-3b3f1bfcdf5e@kernel.org
Fixes: c84bf6dd2b83 ("mm: introduce new .mmap_prepare() file callback")
Signed-off-by: Lorenzo Stoakes (ARM) &lt;ljs@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Reviewed-by: Suren Baghdasaryan &lt;surenb@google.com&gt;
Reviewed-by: Gregory Price (Meta) &lt;gourry@gourry.net&gt;
Acked-by: Zi Yan &lt;ziy@nvidia.com&gt;
Acked-by: Vlastimil Babka (SUSE) &lt;vbabka@kernel.org&gt;
Cc: Liam R. Howlett &lt;liam@infradead.org&gt;
Cc: Jann Horn &lt;jannh@google.com&gt;
Cc: Pedro Falcato &lt;pfalcato@suse.de&gt;
Cc: &lt;stable@vger.kernel.org&gt;
</content>
</entry>
<entry>
<title>kasan: unpoison task stack below watermark only in generic mode</title>
<updated>2026-09-26T20:55:10Z</updated>
<author>
<name>Andrey Ryabinin</name>
<email>ryabinin.a.a@gmail.com</email>
</author>
<published>2026-09-16T17:51:13Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=22ab0647764c38924669673634ae333578d77768'/>
<id>urn:sha1:22ab0647764c38924669673634ae333578d77768</id>
<content type='text'>
CPU resume and BPF exception handling can discard stack frames without
running their compiler-generated epilogues.  Generic KASAN needs
kasan_unpoison_task_stack_below() to clear the redzones left behind by
those frames before the stack is reused.

CONFIG_KASAN_STACK also enables this helper for SW_TAGS.  The helper
derives the stack base from an untagged stack pointer, so kasan_unpoison()
writes KASAN_TAG_KERNEL (0xff) into the shadow for [base, watermark).  For
a vmapped task stack, vm_area-&gt;addr still carries the original random
allocation tag.  This creates a tag mismatch at the stack base even if
that memory has never held an instrumented stack object.

When the task exits and its stack is not cached, thread_stack_free_rcu()
passes vm_area-&gt;addr to vfree().  In RCU callback context this reaches
vfree_atomic(), whose llist_add() writes to the allocation base through
the tagged pointer and triggers a false KASAN invalid-access report:

  BUG: KASAN: invalid-access in vfree_atomic+0x90/0x150
  Write of size 8 at addr c2ffffc0a8f70000 by task rcuop/7/75
  Pointer tag: [c2], memory tag: [ff]
  Call trace:
   __hwasan_store8_noabort+0xe8/0xf8
   vfree_atomic+0x90/0x150
   vfree+0x220/0x298
   thread_stack_free_rcu+0x3c/0x4c
   rcu_do_batch+0x308/0xaf0
   rcu_nocb_cb_kthread+0x33c/0x708

The deferred-free path started using the tagged vm_area-&gt;addr in commit
449e0b4ed5a1 ("fork: clean-up naming of vm_stack/vm_struct variables in
vmap stacks code").  Previously it freed the untagged pointer derived from
tsk-&gt;stack, so the write was never tag-checked.

SW_TAGS does not need the blanket shadow reset to make subsequent stack
accesses valid: untagged kernel pointers have the match-all 0xff tag, and
the compiler initializes the shadow tags of instrumented stack objects
before use.

Return early unless CONFIG_KASAN_GENERIC is enabled.  Keep the mode check
in the common helper so it covers both resume and bpf_throw().

Link: https://lore.kernel.org/20260916175113.1327454-1-ryabinin.a.a@gmail.com
Fixes: 449e0b4ed5a1 ("fork: clean-up naming of vm_stack/vm_struct variables in vmap stacks code")
Signed-off-by: Andrey Ryabinin &lt;ryabinin.a.a@gmail.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Reported-by: Shaobo Huang &lt;huangshaobo3@xiaomi.com&gt;
Closes: https://lore.kernel.org/all/20260806123020.90869-1-huangshaobo3@xiaomi.com/
Assisted-by: LLM
Cc: Alexander Potapenko &lt;glider@google.com&gt;
Cc: Andrey Konovalov &lt;andreyknvl@gmail.com&gt;
Cc: David Hildenbrand &lt;david@kernel.org&gt;
Cc: Dmitry Vyukov &lt;dvyukov@google.com&gt;
Cc: Lorenzo Stoakes &lt;ljs@kernel.org&gt;
Cc: Vincenzo Frascino &lt;vincenzo.frascino@arm.com&gt;
Cc: &lt;stable@vger.kernel.org&gt;
</content>
</entry>
<entry>
<title>mm/damon/core: don't skip damos_adjust_quota() while esz is not zero</title>
<updated>2026-09-26T20:55:10Z</updated>
<author>
<name>SJ Park</name>
<email>sj@kernel.org</email>
</author>
<published>2026-09-16T13:50:19Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=52ae167ce16609c7e6fffef588b3c2c26de2db19'/>
<id>urn:sha1:52ae167ce16609c7e6fffef588b3c2c26de2db19</id>
<content type='text'>
DAMOS could unexpectedly stop working when a user disables quota using the
online parameters commit feature.  Fix it by correcting a wrong quota
unset check in damos_adjust_quota().

DAMON users could disable all quotas by unsetting time and size quotas,
and removing all quota goals.  The intention of disabling quotas would be
making DAMOS run at full speed.  When such quota disabled setup is
detected, damos_adjust_quota() skips all its work.  The skipped works
include effective size quota (damos_quota-&gt;esz) updates and charged quota
amount (damos_quota-&gt;charged_sz) resets.  The intention is to avoid doing
unnecessary work when quotas are disabled.

However, users could do the setup while effective size quota is non-zero,
by doing the disabling with the online DAMON parameters commit feature. 
In this case, because the effective size quota exists, DAMOS will keep
working with the quota until it is fully charged.  After the effective
quota is fully charged, the charged quota amount (damos_quota-&gt;charged_sz)
cannot be reset because damos_adjust_quota() skips it.  Then, DAMOS stops
working until the quota is newly set or DAMON is entirely restarted.

The problem happens because damos_adjust_quota() assumes the user setup
for disabling quota immediately disabled it.  In reality, the quota is
still working until the effective size quota is also updated to zero. 
Other logic for catching that uses damos_quota_is_set(), which understands
the fact and therefore checks the effective size quota in addition to the
user setup.  Fix the issue by using damos_quota_is_set() in
damos_adjust_quota() to determine if its works should be skipped.

The user impact is a non-deterministic and unexpected DAMOS stop behavior.
That is, users would disable quotas using the online parameters commit
feature, expecting DAMOS will run at full speed.  However, depending on
the timing, the setup can be updated while the effective size quota is
non-zero.  Due to the above mentioned internal mechanism, DAMOS stops
working instead of running at full speed.  It is unexpected behavior.  It
is also non-deterministic because sometimes the setup is done when the
effective size quota is zero, depending on the timing.  It doesn't cause
critical issues like crashes or leaks.  Users can simply set a reasonable
quota again, or restart DAMON.  But definitely it is an unexpected and
non-deterministic behavior that makes it difficult to reliably use.  Also
investigating the root cause of the behavior would be quite difficult.

Link: https://lore.kernel.org/20260916135020.86483-1-sj@kernel.org
Fixes: da87878010e5 ("mm/damon/sysfs: support online inputs update")
Signed-off-by: SJ Park &lt;sj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Reviewed-by: Kunwu Chan &lt;kunwu.chan@gmail.com&gt;
Cc: &lt;stable@vger.kernel.org&gt; # 5.19.x
</content>
</entry>
<entry>
<title>mm: shmem: ignore sysfs configs for shmem forced collapse</title>
<updated>2026-09-26T20:55:09Z</updated>
<author>
<name>Baolin Wang</name>
<email>baolin.wang@linux.alibaba.com</email>
</author>
<published>2026-09-14T02:12:41Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=72c3d682c165b836b54a3d07a01f72e39c47022c'/>
<id>urn:sha1:72c3d682c165b836b54a3d07a01f72e39c47022c</id>
<content type='text'>
According to Documentation/mm/transhuge.rst, MADV_COLLAPSE is expected to
ignore any THP or mTHP interface settings.

However, after commit 26c7d8413aaf ("mm: thp: support "THPeligible"
semantics for mTHP with anonymous shmem"), performing MADV_COLLAPSE on
shmem will depend on /sys/.../hugepages-2048kB/shmem_enabled being set to
"inherit" (although that is the default), which can cause MADV_COLLAPSE to
fail unexpectedly.

This could cause a userspace-visible performance regression.

Fix this by returning the result of shmem_huge_global_enabled() directly
when MADV_COLLAPSE is requested, allowing PMD-order collapse while
ignoring shmem THP/mTHP settings.

Link: https://lore.kernel.org/063f655b4d6c4234f3aa27ed6ecab10283ecb880.1789351825.git.baolin.wang@linux.alibaba.com
Fixes: 26c7d8413aaf ("mm: thp: support "THPeligible" semantics for mTHP with anonymous shmem")
Signed-off-by: Baolin Wang &lt;baolin.wang@linux.alibaba.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Reported-by: Kiryl Shutsemau (Meta) &lt;kas@kernel.org&gt;
Closes: https://lore.kernel.org/all/20260908125105.1510704-7-kirill@shutemov.name/
Reviewed-by: Kiryl Shutsemau (Meta) &lt;kas@kernel.org&gt;
Acked-by: Zi Yan &lt;ziy@nvidia.com&gt;
Reviewed-by: Lance Yang &lt;lance.yang@linux.dev&gt;
Reviewed-by: Barry Song &lt;baohua@kernel.org&gt;
Acked-by: Qi Zheng &lt;qi.zheng@linux.dev&gt;
Acked-by: David Hildenbrand (Arm) &lt;david@kernel.org&gt;
Reviewed-by: Lorenzo Stoakes (ARM) &lt;ljs@kernel.org&gt;
Cc: Dev Jain &lt;dev.jain@arm.com&gt;
Cc: Hugh Dickins &lt;hughd@google.com&gt;
Cc: Liam R. Howlett &lt;liam@infradead.org&gt;
Cc: Ryan Roberts &lt;ryan.roberts@arm.com&gt;
Cc: &lt;stable@vger.kernel.org&gt;
</content>
</entry>
<entry>
<title>Merge tag 'fixes-2026-09-24' of git://git.kernel.org/pub/scm/linux/kernel/git/mm/memblock</title>
<updated>2026-09-24T13:16:19Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-09-24T13:16:19Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=e2936d228b96346d474f368f1bb0172582035577'/>
<id>urn:sha1:e2936d228b96346d474f368f1bb0172582035577</id>
<content type='text'>
Pull memblock fix from Mike Rapoport:
 "The rework of HugeTLB bootmem allocation forgot to add the name for a
  new RSV_HUGETLB flag for proper display in debugfs.

  Add the flag name now"

* tag 'fixes-2026-09-24' of git://git.kernel.org/pub/scm/linux/kernel/git/mm/memblock:
  mm: memblock: add missing HugeTLB flag name
</content>
</entry>
<entry>
<title>Merge tag 'mm-hotfixes-stable-2026-09-21-17-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm</title>
<updated>2026-09-22T17:03:33Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2026-09-22T17:03:33Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=a52a93358ac2bef65f15e0069cd410a2b59ae03b'/>
<id>urn:sha1:a52a93358ac2bef65f15e0069cd410a2b59ae03b</id>
<content type='text'>
Pull MM fixes from Andrew Morton:
 "14 hotfixes.  10 are cc:stable.  11 are for MM.

  Five DAMON fixes: one fixes an arm64 contpte bug where DAMON can write
  past the end of a page-table page, resulting in memory corruption and
  possible crashes.

  Two hugetlb fixes: one fixes an mremap() address calculation bug which
  can panic x86-64.

  There's also a missing anon_vma publication barrier which can result
  in hung tasks, and a writeback fix to keep long cgroup writeback
  drains from delaying Tasks-RCU grace periods.

  The remainder are smaller fixes and maintenance changes"

* tag 'mm-hotfixes-stable-2026-09-21-17-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  MAINTAINERS: update Xu Xin's email
  writeback: report a Tasks-RCU quiescent state per cgwb drain pass
  mm/damon/core: reset invalid quota-&gt;charge_target_from
  MAINTAINERS: add Baoquan and Baolin as MGLRU reviewers
  mm/rmap: fix missing barrier between anon_vma init and vma-&gt;anon_vma publish
  mm/hugetlb: preserve mremap address delta when skipping page tables
  mm/damon/core: fix unconditionally skip last region
  mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold()
  mm/damon/core: allow esz to be set to zero
  mm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()
  ocfs2: make ocfs2_calc_xattr_init() return void
  mailmap: update Haowen Bai's email address
  selftests/cgroup: account for zswap shrinker writeback
  mm/hugetlb: do not dissolve gigantic pages without runtime support
</content>
</entry>
<entry>
<title>writeback: report a Tasks-RCU quiescent state per cgwb drain pass</title>
<updated>2026-09-18T15:20:15Z</updated>
<author>
<name>Josef Bacik</name>
<email>josef@toxicpanda.com</email>
</author>
<published>2026-09-09T18:01:07Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=407a5d205179a4ab186571b0e16ec42725dc77bc'/>
<id>urn:sha1:407a5d205179a4ab186571b0e16ec42725dc77bc</id>
<content type='text'>
cleanup_offline_cgwbs_workfn() drains a dying cgwb by calling
cleanup_offline_cgwb() until it returns false, with a cond_resched()
between passes.  On a CONFIG_PREEMPTION kernel that cond_resched() does
nothing: _cond_resched() is a plain "return 0", and under PREEMPT_DYNAMIC
the full and lazy modes disable it.  Since commit 7dadeaa6e851 ("sched:
Further restrict the preemption modes") those are the only two models on
the architectures with PREEMPT_LAZY support, arm64 and x86 among them, so
the drain loop never reports a Tasks-RCU quiescent state.

A worker draining a cgwb with millions of attached inodes runs for
minutes.  On a 6.18 arm64 host in lazy mode the cgwb worker drained one
dying cgroup's writeback domain for over 11 minutes.  A BPF program unlink
(bpf_trampoline_unlink_prog -&gt; bpf_trampoline_update -&gt;
unregister_ftrace_direct -&gt; ftrace_shutdown -&gt; synchronize_rcu_tasks())
waited on that grace period while holding the trampoline mutex, 42 tasks
queued behind it in D state, and the hung task detector fired at 614 s and
panicked the host.  Any BPF or ftrace detach during a long drain inherits
the drain's length.

Fix this by calling cond_resched_tasks_rcu_qs() so we do not stall out
anybody who calls sycnrhonize_rcu_tasks().  We put this in a do { } while
loop because if we have many small cgroups cleanup_offline_cgwb() will
return false and we will never call cond_resched_tasks_rcu_qs(), creating
the same problem.

Link: https://lore.kernel.org/20260909-cgwb-tasks-rcu-qs-v1-1-967a7754771f@toxicpanda.com
Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
Signed-off-by: Josef Bacik &lt;josef@toxicpanda.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Link: https://lore.kernel.org/bpf/9d444098-7c03-4163-af12-bd0a79a51443@paulmck-laptop/
Assisted-by: LLM
Acked-by: Tejun Heo &lt;tj@kernel.org&gt;
Reviewed-by: Roman Gushchin &lt;roman.gushchin@linux.dev&gt;
Reviewed-by: Jan Kara &lt;jack@suse.cz&gt;
Acked-by: Lorenzo Stoakes (ARM) &lt;ljs@kernel.org&gt;
Cc: David Hildenbrand &lt;david@kernel.org&gt;
Cc: Dennis Zhou &lt;dennis@kernel.org&gt;
Cc: Liam R. Howlett &lt;liam@infradead.org&gt;
Cc: Matthew Wilcox (Oracle) &lt;willy@infradead.org&gt;
Cc: Michal Hocko &lt;mhocko@suse.com&gt;
Cc: Mike Rapoport &lt;rppt@kernel.org&gt;
Cc: "Paul E . McKenney" &lt;paulmck@kernel.org&gt;
Cc: Suren Baghdasaryan &lt;surenb@google.com&gt;
Cc: Vlastimil Babka &lt;vbabka@kernel.org&gt;
Cc: &lt;stable@vger.kernel.org&gt;
</content>
</entry>
<entry>
<title>mm/damon/core: reset invalid quota-&gt;charge_target_from</title>
<updated>2026-09-18T15:20:14Z</updated>
<author>
<name>SJ Park</name>
<email>sj@kernel.org</email>
</author>
<published>2026-09-10T14:28:45Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=eb64948249781bda35de04feab5a0acc36aa9051'/>
<id>urn:sha1:eb64948249781bda35de04feab5a0acc36aa9051</id>
<content type='text'>
DAMOS can suddenly stop working if a target process that the quota is just
fully charged on is terminated.  Fix by catching and processing the corner
case.

When DAMOS quota is fully charged, the target and the region to continue
applying the action in the next round is saved in
damos_quota-&gt;charge_{target,addr}_from.  In the next round, DAMOS iterates
targets and regions from the beginning.  It skips applying the action to
the regions until it visits and skips the saved target/region.

Virtual address space targets become invalid if the process is terminated.
Trying to apply the scheme to invalid target is just a waste of time. 
Hence commit 6e4930e33329 ("mm/damon/core: fix wasteful CPU calls by
skipping non-existent targets") made the logic to skip invalid targets. 
However, it does skip before the charged target/region skipping/updating.

Let's suppose the user runs DAMOS for multiple virtual address spaces with
a quota.  The quota exceeded in the middle of a virtual address space. 
And the process of the address space is terminated.  Then the
charge_target_from points to the invalid target.  The pointer update logic
is skipped for the invalid target, so the charge_target_from is never
updated.  DAMOS action to every target/region is skipped.  From the user's
perspective, it would look like suddenly DAMOS has stopped working.

No critical leak or crash can happen.  The user could reinstall the
scheme.  But this makes use of DAMOS under certain setups quite
unreliable.

When the invalid target is found, further check the corner case and reset
the pointer.

This issue was discovered [1] by Sashiko.

Link: https://lore.kernel.org/20260910142846.172957-1-sj@kernel.org
Link: https://lore.kernel.org/20260830064708.40CA61F000E9@smtp.kernel.org [1]
Fixes: 6e4930e33329 ("mm/damon/core: fix wasteful CPU calls by skipping non-existent targets")
Signed-off-by: SJ Park &lt;sj@kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Cc: Enze Li &lt;lienze@kylinos.cn&gt;
Cc: &lt;stable@vger.kernel.org&gt; # 7.0.x
</content>
</entry>
<entry>
<title>mm/rmap: fix missing barrier between anon_vma init and vma-&gt;anon_vma publish</title>
<updated>2026-09-18T15:20:14Z</updated>
<author>
<name>Jinjiang Tu</name>
<email>tujinjiang@huawei.com</email>
</author>
<published>2026-09-08T12:29:24Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-linux/commit/?id=b6ac0b3f6013c168f22cad97e79967accacb08e1'/>
<id>urn:sha1:b6ac0b3f6013c168f22cad97e79967accacb08e1</id>
<content type='text'>
On arm64 server, we find that a task trying to grab the anon_vma lock
triggers hungtask.

INFO: task main:2354726 blocked for more than 120 seconds.
      Tainted: G            E     5.10.0-0021.aarch64 #1
"echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:main            state:D stack:    0 pid:2354726 ppid:2350673 flags:0x00000a01
Call trace:
 __switch_to+0x7c/0xbc
 __schedule+0x3b4/0x8a0
 schedule+0x50/0xe0
 rwsem_down_write_slowpath+0x3cc/0x6cc
 down_write+0x60/0x260
 __anon_vma_prepare+0x6c/0x210
 do_anonymous_page+0x258/0x660
 handle_pte_fault+0x188/0x214
 __handle_mm_fault+0x1b0/0x380
 handle_mm_fault+0xf4/0x284
 do_page_fault+0x19c/0x494
 do_translation_fault+0xcc/0xf8
 do_mem_abort+0x48/0xac
 el0_da+0x44/0x80
 el0_sync_handler+0x88/0xb4
 el0_sync+0x160/0x180

After analyzing the vmcore, we found the anon_vma-&gt;root-&gt;rwsem.count is
-1.  There is another anon_vma whose anon_vma-&gt;root-&gt;rwsem.count is 1, the
anon_vma-&gt;root-&gt;rwsem.owner shows the lock is held, but the stack of the
task shows the task doesn't hold the anon_vma lock.

After adding more debugging info, we found __anon_vma_prepare() reuses
anon_vma and triggers the UAF of anon_vma-&gt;root due to missing memory
barrier, leading to locking and unlocking two different anon_vma-&gt;root,
thus leading to an anon_vma will never be unlocked, and another anon_vma
couldn't be locked anymore.

This race requires two adjacent VMAs that are not merged but are
anon_vma-compatible (e.g., they differ in VMA_ACCESS_FLAGS that can be
changed by mprotect()).  Two threads fault on each VMA concurrently, both
calling __anon_vma_prepare() with only mmap_lock held for reading.

    THREAD A                             THREAD B
__anon_vma_prepare                __anon_vma_prepare
 find_mergeable_anon_vma() -&gt; NULL
 anon_vma = anon_vma_alloc();
   anon_vma-&gt;root = anon_vma;
 // the two stores may be reordered
 vma-&gt;anon_vma = anon_vma;
                                   // finds A's anon_vma
                                   anon_vma = find_mergeable_anon_vma(vma);
                                   anon_vma_lock_write(anon_vma);
                                     // may still see the old root
                                     down_write(&amp;anon_vma-&gt;root-&gt;rwsem);
                                   anon_vma_unlock_write(anon_vma);
                                     // see the new root, never unlock old
                                     up_write(&amp;anon_vma-&gt;root-&gt;rwsem);

thread A triggers page fault and calls __anon_vma_prepare() to prepare
anon_vma for the faulting vma.  __anon_vma_prepare() allocates and
initializes a new anon_vma, and then publishes it to the vma with a plain
store.  anon_vma_prepare() only requires the mmap_lock to be held for
reading, so two threads can fault on adjacent VMAs at the same time. 
While thread A publishes a new anon_vma, thread B could find the anon_vma
via find_mergeable_anon_vma() and then locks anon_vma-&gt;root-&gt;rwsem.

The store to anon_vma-&gt;root in anon_vma_alloc() and the store to
vma-&gt;anon_vma can be reordered.  The anon_vma_lock_write() and spin_lock()
only provide acquire semantics, which do not prevent prior stores from
being reordered after them.  The release semantics of the corresponding
spin_unlock() and anon_vma_unlock_write() come too late, the store to
vma-&gt;anon_vma is already published before they take effect.  As a result,
thread B can observe the following order:

    vma-&gt;anon_vma = anon_vma;
    anon_vma-&gt;root = anon_vma;

The anon_vma slab is SLAB_TYPESAFE_BY_RCU, so a newly allocated anon_vma
may reuse memory from a previously freed one.  The constructor
(anon_vma_ctor) does not reset anon_vma-&gt;root, and __put_anon_vma()
doesn't clear it either, so the old root value persists until
anon_vma_alloc() overwrites it.  If that store isn't visible, thread B
reads a root that points to the old anon_vma and locks it.

As a result, thread B can call anon_vma_lock_write() with the old root,
and call anon_vma_unlock_write() with the new root, leading to an anon_vma
will never be unlocked, and another anon_vma couldn't be locked anymore
(its count is dropped from 0 to -1 due to wrong unlock).

To fix it, change the plain store `vma-&gt;anon_vma = anon_vma` to store
release, so that the fields of anon_vma are visible before anon_vma is
published to vma-&gt;anon_vma.

At read side, the load of anon_vma and anon_vma-&gt;root have address
dependency.  According to Documentation/memory-barriers.txt and some
investigations, only Alpha needs address-dependency barriers and it has
been handled by READ_ONCE() in reusable_anon_vma().

We reproduced this issue in v5.10 with KSM enabled.  The kernel doesn't
merge commit cf7e7a3503df ("mm: prevent KSM from breaking VMA merging for
new VMAs"), so there are many adjacent VMAs that aren't merged but are
compatible for anon_vma.

Without this fix, our production environment could reproduce this issue
about 2-5 times each month.  After adding a smp_mb() before
anon_vma_lock_write(anon_vma) in __anon_vma_prepare(), which is different
to this patch, this issue hasn't been reproduced for one month.

Link: https://lore.kernel.org/20260908122924.554373-1-tujinjiang@huawei.com
Fixes: 5c341ee1dfc8 ("mm: track the root (oldest) anon_vma")
Signed-off-by: Jinjiang Tu &lt;tujinjiang@huawei.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Reviewed-by: Lance Yang &lt;lance.yang@linux.dev&gt;
Reviewed-by: Lorenzo Stoakes (ARM) &lt;ljs@kernel.org&gt;
Acked-by: David Hildenbrand (Arm) &lt;david@kernel.org&gt;
Acked-by: Vlastimil Babka (SUSE) &lt;vbabka@kernel.org&gt;
Cc: Minchan Kim &lt;minchan@kernel.org&gt;
Cc: Harry Yoo &lt;harry@kernel.org&gt;
Cc: Hiroyouki Kamezawa &lt;kamezawa.hiroyu@jp.fujitsu.com&gt;
Cc: Jann Horn &lt;jannh@google.com&gt;
Cc: Jinjiang Tu &lt;tujinjiang@huawei.com&gt;
Cc: Kefeng Wang &lt;wangkefeng.wang@huawei.com&gt;
Cc: Larry Woodman &lt;lwoodman@redhat.com&gt;
Cc: Liam R. Howlett &lt;liam@infradead.org&gt;
Cc: Nanyong Sun &lt;sunnanyong@huawei.com&gt;
Cc: Rik van Riel &lt;riel@surriel.com&gt;
Cc: &lt;stable@vger.kernel.org&gt;
</content>
</entry>
</feed>
