Merge tag 'mm-core-7.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/mm/core
Pull core memory management fixes from David Hildenbrand:
"Here's a bigger set of MM fixes that we didn't manage to have ready
for -rc1. All fixes are stable-worthy; the majority fixes nasty
long-standing bugs instead of being purely hotfixes.
We have some more of these kinds of stable-worthy fixes in the
pipeline, but we'll focus on the really urgent fixes as we get closer
to the release.
(Leaving urgent MM fixes lurking for various weeks is not good, but
having too many changes close to the release is also not good, it's
tricky ...)
Most issues were reported by Anthropic. Others were found while
reworking proposed fixes, and of course some of the fixes were just
reported and fixed on the mailing list.
[53 lines not shown]
Merge tag 'mm-nonmm-hotfixes-stable-2026-11-04-20-26' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull non-MM fixes from Andrew Morton:
"22 patches. 17 are cc:stable.
Most are OCFS2 fixes. These address extended-attribute corruption,
missing attributes and kernel BUGs, along with crashes during cluster
configuration, lock migration, recovery and unmount. Extent movement
is also fixed to validate its range against a stable file size.
Three FAT changes prevent a failed-write/FIBMAP race from spuriously
making the filesystem read-only, correct directory link counts after
rename, and speed up file expansion. The reported QEMU benchmarks show
particularly large improvements on synchronous mounts.
A taint-string fix prevents an out-of-bounds read which can expose
slab contents in the kernel log. There are also build fixes for
OpenRISC modules on CPUs without hardware multiply and for Clang 24"
[22 lines not shown]
Merge tag 'mm-hotfixes-stable-2026-11-04-20-02' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull MM fixes from Andrew Morton:
- "mm: avoid losing atomic VMA flags" (Lorenzo Stoakes):
Preserve guard-page and soft-dirty state across VMA changes. Prevent
fork and THP collapse from losing guard markers, and keep changes
visible to applications which track modified memory.
- "MAINTAINERS: MM updates" (David Hildenbrand):
Start routing more MM components through mm/core.git and add Zi Yan
as a THP co-maintainer. Update component coverage and integration
branches as part of the transition to separate MM component trees.
- "mm/hugetlb: fix mremap bugs" (Li Zhe):
Fix hugetlb mremap deadlocks and truncated move lengths. Prevent
[80 lines not shown]
mm/huge_memory: set the mmu_gather page size in zap_huge_pud()
Unmapping a device-dax mapping with 1G alignment on powerpc radix kernel
built with CONFIG_DEBUG_VM triggers this warning on every munmap:
WARNING: mm/mmu_gather.c:176 at __tlb_remove_folio_pages_size+0x38/0x230
NIP [c00000000063d508] __tlb_remove_folio_pages_size+0x38/0x230
LR [c0000000006fb688] zap_huge_pud+0x1b8/0x2d0
Call Trace:
zap_huge_pud+0x170/0x2d0 (unreliable)
__zap_vma_range+0x1604/0x1e20
unmap_vmas+0xa0/0x1f0
unmap_region+0xb0/0x130
vms_complete_munmap_vmas+0x120/0x310
do_vmi_align_munmap+0x1ec/0x240
__vm_munmap+0x148/0x220
sys_munmap+0x28/0x40
To trigger this - it is enough to mmap() /dev/dax0.0, touch the first
[25 lines not shown]
mm/vma: call ->may_split() before a partial merge
A driver can use the ->may_split() hook to forbid a VMA boundary at
certain addresses.
A device-dax device is a character device that gives raw access to a
range of memory through mmap(). device-dax refuses any address that is not
a multiple of the device's alignment through vm_ops->may_split.
vma_merge_existing_range() can move boundaries, but does not call
vm_ops->may_split.
If a range at the edge of a VMA gets the attributes of the adjacent VMA,
the function moves only that range over to the neighbour: one VMA shrinks
and the other grows. This is a partial merge, and vma_modify() tries it
before any split.
Take a device-dax VMA that lies next to another VMA of the same file.
The user calls mprotect() on the one page of the first VMA that touches
[42 lines not shown]
mm: fix deadlock of mremap() against UFFDIO_MOVE
With per-VMA locks, UFFDIO_MOVE can run concurrently with mremap()
on different VMAs in the same mm. Those VMAs can share page tables, so
both operations can acquire the same pair of page-table locks.
UFFDIO_MOVE orders the locks by address, while mremap() takes the source
lock first. These conflicting orders can deadlock; mremap() holding
mmap_lock for writing no longer helps.
Move double_pt_lock() and double_pt_unlock() to mm/internal.h and use
them for all page-table moves in mremap(). Preserve the source entry
checks after acquiring both locks. Remove the comments claiming that
exclusive mmap_lock makes lock ordering irrelevant.
In move_ptes(), make sure to just recheck source and destination PMD
after taking the locks and drop the overly-long comment.
Fix generated by an LLM and sent by Chris Mason in private.
[13 lines not shown]
mm/madvise: fix data loss from MADV_FREE on a KSM page
MADV_FREE can clear the dirty flag of a singly mapped KSM folio. The
folio remains in the stable tree and can gain new mappings without being
dirtied again. Once marked lazyfree, reclaim can discard data that those
mappings still need.
KSM always marks a folio dirty when converting it to a KSM folio in
try_to_merge_one_page(). Marking a folio lazyfree clears PG_swapbacked
but leaves PG_dirty unchanged. Preserving PG_dirty makes reclaim restore
PG_swapbacked instead of discarding the folio. This also protects folios
that were already lazyfree when KSM converted them.
Skip KSM folios before clearing their dirty flag, checking under the
folio lock to serialize with KSM conversion.
Fixes: 854e9ed09ded ("mm: support madvise(MADV_FREE)")
Cc: stable at vger.kernel.org
Reported-by: Josef Bacik <josef at toxicpanda.com>
[5 lines not shown]
mm/memory: reject remote COW faults on PFN mappings
When handling a COW fault without a normal source page (PFN mappings),
__wp_page_copy_user() copies from the faulting user address. For remote
faults, this accesses the wrong address space, resulting in wrong data
getting copied.
For example, user_events updates an enable bit in the registering
process's memory. If that memory needs to be faulted in,
user_event_enabler_fault_fixup() calls fixup_user_fault() from a work
item. Placing the enable bit in a private PFN mapping can trigger this
remote COW path.
Reject these faults with VM_FAULT_SIGBUS when the target mm differs from
current->mm: remote faults. Ordinary (non-PFN) mappings are not affected.
The user-address copy dates back to commit 6aab341e0a28 ("mm: re-architect
the VM_UNPAGED logic"); likely, actual ways to get remote faults in
there on COW PFN mappings appeared afterwards. But the fix is simple and
[13 lines not shown]
mm/vma: don't leak the charge for stack growth
acct_stack_growth() charges stack expansion even without VM_ACCOUNT.
This can happen for read-only or MAP_NORESERVE mappings created with
MAP_GROWSDOWN. Unmapping these VMAs does not release the charge, leaking
Committed_AS.
Only check and charge growth for VM_ACCOUNT VMAs, matching mremap().
Unaccounted growth skips the overcommit check while remaining subject
to the other stack-growth limits.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable at vger.kernel.org
Reported-by: Josef Bacik <josef at toxicpanda.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>
Reviewed-by: Pedro Falcato <pfalcato at suse.de>
Reviewed-by: Harry Yoo (Meta) <harry at kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum at arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-44-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david at kernel.org>
mm: fix unkillable fault loop on MAP_DROPPABLE memory
handle_mm_fault() suppresses VM_FAULT_OOM for VM_DROPPABLE mappings.
For user-mode faults, pending signals are processed before retrying the
access. Kernel-mode faults on user buffers instead return directly to
the faulting instruction.
With persistent allocation failures (esp. memcg limits), a syscall,
such as write(), can therefore loop while not dropping locks.
Only suppress VM_FAULT_OOM when FAULT_FLAG_USER is set, allowing
kernel-mode faults and GUP to fail and signal allocation errors.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 9651fcedf7b9 ("mm: add MAP_DROPPABLE for designating always lazily freeable mappings")
Cc: stable at vger.kernel.org
Signed-off-by: Chris Mason <mason at kernel.org>
[5 lines not shown]
mm/huge_memory: split huge PUDs when adjusting VMA boundaries
PFN mappings such as VFIO PCI BAR mappings can use PUD leaves while
allowing VMA splits at page granularity. However, vma_adjust_trans_huge()
only handles PMDs.
After faulting a writable PUD-sized VFIO BAR mapping, changing its first
page to read-only with mprotect() makes the PMD walk treat the PUD leaf
as a PMD table. Applying MADV_DONTFORK to the first PMD-sized chunk leaves
the PUD spanning two VMAs: the PMD-aligned boundary skips splitting.
Walk the page tables once at each adjusted boundary and split a huge
PUD or PMD leaf as needed. Handle PUD leaves even when the boundary is
PMD-aligned.
Fixes: f9e54c3a2f5b7 ("vfio/pci: implement huge_fault support")
Cc: stable at vger.kernel.org
Tested-by: Muhammad Usama Anjum <usama.anjum at arm.com>
Reviewed-by: Kiryl Shutsemau (Meta) <kas at kernel.org>
[2 lines not shown]
mm/memory-tiers: unregister empty tiers outside memory_tier_lock
When offlining a node's last memory empties its tier,
clear_node_memory_tier() calls device_unregister() while holding
memory_tier_lock. A concurrent sysfs read can hold a kernfs active
reference and block in nodelist_show() on that mutex. device_unregister()
then waits in kernfs_drain() for the read to finish and release its active
reference, while the reader waits for the offlining task to release the
mutex.
Return the node's former tier from clear_node_memory_tier(), making the
helper more similar to set_node_memory_tier(), which also returns a
memory_tier pointer. Let the caller unlink an empty tier under
memory_tier_lock before rebuilding demotion targets, then unregister its
device after dropping the lock.
Fixes: 9832fb87834e ("mm/demotion: expose memory tier details via sysfs")
Cc: stable at vger.kernel.org
Reported-by: Josef Bacik <josef at toxicpanda.com>
[4 lines not shown]
mm/mremap: fix moving PUD leaves
pud_none_or_clear_bad() only really works on page tables. PUD leaves
confuse the check and make us clear the page table entry and print a
warning.
Since commit aed877c2b4257 ("device/dax: properly refcount device dax pages
when mapping"), this also leaks device-DAX folio references, mapcounts
and RSS accounting, resulting in "Bad rss-counter state" warnings on exit.
Allow PUD leaves in get_old_pud(). If a PUD leaf cannot be moved as a
whole or the move fails, split it. This unmaps it with proper accounting
instead of treating the leaf entry as a PMD table.
Keep using pud_trans_huge() for now, in the future this code should be
cleaned up to just check for PUD leaves.
Fix generated by an LLM and sent by Josef Bacik in private.
[10 lines not shown]
mm/gup: check folio->mapping under folio lock in memfd_pin_folios()
memfd_pin_folios() pins folios from the page cache without taking the
folio lock. khugepaged or MADV_COLLAPSE can therefore replace a folio
after checking its refcount while memfd_pin_folios() still pins the old
folio. The caller then receives a folio which is no longer part of the
memfd.
For udmabuf and iommufd, this can cause data corruption: DMA accesses
the detached folio rather than the live memfd contents. DMA reads can
return stale data, while DMA writes update the detached copy and are
lost from the live memfd. The detached folio remains pinned, so these
accesses do not constitute a use-after-free or target another
application's memory. For memfd live update, the stale contents can
reappear in the memfd after handover.
Lock the folio and recheck folio->mapping before pinning it, like other
page cache users do. If the folio was removed, retry the folio lookup
from the index that was removed.
[9 lines not shown]
mm/cma: don't release CMA pages still in use
When a driver calls dma_free_contiguous() before quiescing DMA, the
page might still have a reference from the device.
put_page_testzero() there returns false, WARN fires, but the code proceeds
to free_contig_frozen_range() putting a live page onto buddy and clearing
the bitmap. A subsequent allocation can hand the same PFN to a new
owner while the original holder still references it.
A concurrent put_page() that drops the last reference between the
testzero loop and free_contig_frozen_range() can double-queue the page
via page->lru, corrupting buddy lists.
Avoid the corruption by not freeing a CMA region if any of the
pages inside are still in use.
Make it explicit in the warning that the driver allowed a leak.
While at it, use page_ref_freeze() to make the semantics clearer and
[12 lines not shown]
mm/ksm: reset the unstable trees of all nodes
Each full scan resets ksm_nr_node_ids unstable tree roots. Enabling
merge_across_nodes resets this count to 1, even if per-node roots were
previously allocated.
So when toggling "merge_across_nodes" 0 -> 1 -> 0, a scan that starts
while the setting is 1 and continues after switching back to 0 can
encounter stale unstable tree roots, resulting in UAF.
Only root is allowed to change "merge_across_nodes", and the documented
sequence is: "merge_across_nodes setting can be changed only when there
are no ksm shared pages in the system: set run 2 to unmerge pages first,
then to 1 after changing merge_across_nodes, to remerge according to the
new setting."
Let's fix it by tracking in ksm_nr_node_ids the actual number of
allocated tree roots.
[12 lines not shown]
khugepaged: fix readahead lock inversion in collapse_file()
collapse_file() can call page_cache_sync_readahead() while still holding
source folios locked. If truncate holds mapping->invalidate_lock
exclusively and waits for one of those folios, readahead waits for
invalidate_lock and neither side can make progress.
We need to release those folio locks before starting readahead. On a page
cache miss, roll back first, populate the collapse range, and retry once.
Doing readahead after rollback avoids an extra pass when all folios are
already present. If another miss occurs on retry, give up rather than keep
retrying while truncate or reclaim removes folios.
Keep page_cache_sync_readahead() and wait for read I/O with
filemap_lock_folio(), releasing each folio before moving to the next. The
existing uptodate check during collapse still handles read errors.
Shmem uses shmem_get_folio() for swapin and fallocated folios without
taking mapping->invalidate_lock, so it is unaffected.
[12 lines not shown]
mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit
Commit 9eab0421fa94 ("mm: fix unmap_mapping_range high bits shift bug")
made holebegin and holelen unsigned before they are shifted, by casting
them to pgoff_t. That is an unsigned long: on a 32-bit kernel the cast
cuts off the upper half of the two loff_t values, so a hole which begins
at 4 GiB or beyond is taken for one in the first 4 GiB of the file.
truncate_pagecache() passes the new size of the file and asks for private
COWed pages to be unmapped as well. If a file of 6 GiB is truncated to
5 GiB, everything from 1 GiB on is unmapped, and what a process has
written to a private mapping of the range between 1 GiB and 5 GiB is
lost: it reads the contents of the file again.
Where the range has an end, the wrong range is unmapped instead of the
right one. The page cache copes with that, as it unmaps every folio that
it removes. The callers which only have unmap_mapping_range() to get
rid of user mappings do not, for example drm_vma_node_unmap(), whose fake
offsets reach beyond 4 GiB on 32-bit, and revoke_iomem() with physical
[14 lines not shown]
mm/ksm: fix use of a freed anon_vma at swap-in
A folio read from a swap slot previously shared by KSM can remain in the
swap cache after the process that first mapped it exits. Its anon_vma
can then be freed, so ksm_might_need_to_copy() must not dereference it
to compare roots.
Doing so can result in some false-positives, resulting in the reverse
mapping missing the new folio mapping, preventing migration and reclaim.
SLAB_TYPESAFE_BY_RCU allows individual anon_vma objects to be reused
immediately after freeing. A stale pointer can then refer to another
anon_vma whose root matches, even though the target VMA is not linked
to that anon_vma.
Move the anonymous rmap compatibility checks into
folio_anon_rmap_compatible(). Keep the page-index check and compare the
folio's anon_vma pointer against the VMA's own anon_vma and root first.
[62 lines not shown]
mm/ksm: check large swap-cache folios before mapping them
KSM folios are always small, but their shared swap slots can be read
back as part of a large folio in the swap cache. ksm_might_need_to_copy()
skips large folios, so another process can map a page with an incompatible
anon_vma or page index. Reverse mapping then cannot find the new
mapping, preventing migration or reclaim.
Apply the same compatibility checks to large folios as to small ones.
Pass the page corresponding to the swap entry and copy only that page
when necessary. In do_swap_page()'s copy path, decrement only that slot's
swap count, because the source swap-cache folio can now be large.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: f1879e8a0c60 ("mm, swap: never bypass the swap cache even for SWP_SYNCHRONOUS_IO")
Cc: stable at vger.kernel.org
Signed-off-by: Chris Mason <mason at kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>
[4 lines not shown]
mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs
try_collapse_pte_mapped_thp() clears PTEs without transferring their dirty
bits to the folio. A shmem read fault can map a clean folio writable, so
a later store only dirties the PTE. Losing that dirty bit allows reclaim
to discard modified data.
The assumption that regular files are read-only is also obsolete since
commit 1b6444331bebb ("mm/khugepaged: enable clean pagecache folio collapse
for writable files"). In any case, transferring PTE dirty bits to the folio
when removing mappings (and while the folio is still mapped) is the right
thing to do.
Use get_and_clear_ptes() to collect the dirty bits and mark the folio
dirty before unmapping it. Update the comment.
This was reproduced with shmem using MADV_COLLAPSE followed by
MADV_PAGEOUT.
[15 lines not shown]
mm/gup: recheck the PUD under PTL in follow_pud_mask()
follow_pud_mask() reads the PUD without a lock. If it is a leaf, it takes
the lock and calls follow_huge_pud(), which reads the entry again, but
only tests whether it is present.
A leaf can be zapped concurrently and a page fault can fill the empty
entry with a page table.
This currently only applies when device-dax makes use of PUD entries,
and the fault after e.g., MADV_DONTNEED would find THPs to be disabled.
That requires a sequence like
1) Fault in the PUD
2) Disable THP
3) Have GUP race against concurrent MADV_DONTNEED + refault
Which is rather unlikely to happen in practice, which is why we never
[24 lines not shown]
mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp()
try_collapse_pte_mapped_thp() drops the PTE lock after it has cleared the
page table, and takes the PMD lock and the PTE lock to remove it.
In between, MADV_DONTNEED with CONFIG_PT_RECLAIM can reclaim the
page table. The pmd_same() check is supposed to handle this, but it is
only done with CONFIG_SPLIT_PTE_PTLOCKS.
Fix it by performing the check unconditionally.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 6375e95f381e ("mm: pgtable: reclaim empty PTE page in madvise(MADV_DONTNEED)")
Cc: stable at vger.kernel.org
Signed-off-by: Josef Bacik <josef at toxicpanda.com>
[ david: adjust description ]
Reviewed-by: Gregory Price (Meta) <gourry at gourry.net>
Tested-by: Gregory Price (Meta) <gourry at gourry.net>
[5 lines not shown]
mm/userfaultfd: wake waiters when registration modes are removed
UFFDIO_REGISTER can replace MISSING or MINOR tracking without waking
faults that are already queued. For example, switching an anonymous
range from MISSING to WP leaves a missing-fault waiter asleep until
userspace explicitly wakes it.
When a registration change removes a UFFD mode, wake waiters in the
affected interval after updating the VMA. The VMA is write-locked at
this point, so no new faults can queue under the old modes and woken
threads cannot retry until mmap_write_unlock(). Waiters for retained
modes in the same interval may also wake and refault.
The hang reproduces for MISSING-to-WP and MINOR-to-MISSING transitions,
with both read and unread fault events.
Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc: stable at vger.kernel.org
Reviewed-by: Gregory Price (Meta) <gourry at gourry.net>
[7 lines not shown]
mm/mremap: recheck PUDs under the page table lock
Once get_old_pud() is fixed to accept PUD leaves, unmap_mapping_range() can
clear a leaf between the lookup and the move. Holding mmap_lock in write
mode does not prevent this.
If the zap happens before move_page_tables() tests the entry, an empty
PUD can reach move_normal_pud(), where pud_populate() turns it into a
present page table entry. If it happens after the test, move_huge_pud()
can instead try to move an empty entry, triggering CONFIG_DEBUG_VM
warnings on powerpc.
Recheck the source under the page table lock in both helpers. Treat an
empty source in move_normal_pud() as a completed move, and use
__pud_trans_huge_lock() in move_huge_pud().
In the future we should likely have the code lookup a PUD/PMD lockless
once, instead of multiple times, because one of the problematic bits
here is the:
[11 lines not shown]
mm/khugepaged: fix PMD table lock leak in try_collapse_pte_mapped_thp()
For a private mapping with userfaultfd, try_collapse_pte_mapped_thp()
takes the PMD table lock before it maps the page table for the second time.
If that (pte_offset_map_rw_nolock) fails, because the page table vanished
in the meantime due to concurrent page table reclaim, it leaves through
the abort label, where the PMD table lock is unlocked if it differs from
PTE table lock.
In case the PMD table lock and the PTE table lock match, which is the
case without CONFIG_SPLIT_PTE_PTLOCKS after pte_offset_map_rw_nolock()
failed, we miss to unlock the PMD table.
To fix it, forget the PTE table lock when we unmap+unlock the PTE table.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 6375e95f381e ("mm: pgtable: reclaim empty PTE page in madvise(MADV_DONTNEED)")
Cc: stable at vger.kernel.org
[9 lines not shown]
mm/userfaultfd: compare exact registration modes before skipping
Changing registration from MISSING|WP to WP returns success but leaves
MISSING enabled. The no-op check sees that WP is already set and skips
the update, so later accesses to missing pages still wait for userspace.
Skip the update only when the current and requested UFFD modes match
exactly.
Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc: stable at vger.kernel.org
Signed-off-by: Gregory Price (Meta) <gourry at gourry.net>
[ david: apply fixup from Lorenzo ]
Tested-by: Muhammad Usama Anjum <usama.anjum at arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-26-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david at kernel.org>
mm/mmu_notifier: set ->mm only after mmgrab()
Radeon uses a non-NULL notifier->mm to decide whether to call
mmu_interval_notifier_remove() when freeing a buffer object.
__mmu_interval_notifier_insert() sets ->mm before validating the range,
so a wrapping userptr range can leave ->mm set after insertion fails.
Cleanup then tries to remove an unregistered notifier for which no mm
reference was acquired.
Set ->mm only after mmgrab(), once insertion can no longer fail. While
we could fix radeon's code instead, setting ->mm on success only makes
the code more robust.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 3506ff69c3ec ("drm/radeon: use mmu_interval_notifier_insert")
Cc: stable at vger.kernel.org
Signed-off-by: Chris Mason <mason at kernel.org>
[ david: simplify description ]
[6 lines not shown]
mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs
move_huge_pud() reads the old PUD and clears it in separate operations.
Hardware accessed or dirty updates between those operations can be lost
when the saved entry is installed at the new address.
The raw pud_clear() also bypasses page_table_check_pud_clear(), while
set_pud_at() accounts for the destination mapping. This leaves the
checker counts unbalanced for mappings tracked by page table checking.
To fix it, simply use pudp_huge_get_and_clear().
Fixes: 7d846db7d0e2 ("mm/mremap: convert huge PUD move to separate helper")
Cc: stable at vger.kernel.org
Reviewed-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>
Reviewed-by: Pedro Falcato <pfalcato at suse.de>
Reviewed-by: Dev Jain <dev.jain at arm.com>
Tested-by: Muhammad Usama Anjum <usama.anjum at arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-30-d6437171ecc3@kernel.org
[2 lines not shown]
mm/mmu_gather: fix flushing ranges with 4 GiB or larger
__tlb_adjust_range() takes the size of the range which has to be flushed
as an unsigned int. Its callers, tlb_flush_{pte,pmd,pud,p4d}_range(), get
and pass an unsigned long. Consequently, a range that is 4 GiB or larger
gets truncated, possibly to 0.
On arm64 with hugetlb, a 64k kernel can have 16 GiB hugetlb folios
mapped contiguously at the PMD level and flush them when unmapping, and a
16k kernel can flush 64 GiB PUDs through tlb_unshare_pmd_ptdesc(). So
at least these two scenarios are affected.
Fix it by flushing the proper range instead of the truncated one by
properly using "unsigned long" for range_size.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: b528e4b6405b ("mm/hugetlb: add tlb_remove_hugetlb_entry for handling hugetlb pages")
Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
[14 lines not shown]