Skip to content

Commit 0bcb517

Browse files
committed
Merge tag 'mm-hotfixes-stable-2026-03-28-10-45' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "10 hotfixes. 8 are cc:stable. 9 are for MM. There's a 3-patch series of DAMON fixes from Josh Law and SeongJae Park. The rest are singletons - please see the changelogs for details" * tag 'mm-hotfixes-stable-2026-03-28-10-45' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm/mseal: update VMA end correctly on merge bug: avoid format attribute warning for clang as well mm/pagewalk: fix race between concurrent split and refault mm/memory: fix PMD/PUD checks in follow_pfnmap_start() mm/damon/sysfs: check contexts->nr in repeat_call_fn mm/damon/sysfs: check contexts->nr before accessing contexts_arr[0] mm/damon/sysfs: fix param_ctx leak on damon_sysfs_new_test_ctx() failure mm/swap: fix swap cache memcg accounting MAINTAINERS, mailmap: update email address for Harry Yoo mm/huge_memory: fix folio isn't locked in softleaf_to_folio()
2 parents cbfffcc + 2697dd8 commit 0bcb517

9 files changed

Lines changed: 77 additions & 32 deletions

File tree

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ Hans Verkuil <hverkuil@kernel.org> <hverkuil-cisco@xs4all.nl>
316316
Hans Verkuil <hverkuil@kernel.org> <hansverk@cisco.com>
317317
Hao Ge <hao.ge@linux.dev> <gehao@kylinos.cn>
318318
Harry Yoo <harry.yoo@oracle.com> <42.hyeyoo@gmail.com>
319+
Harry Yoo <harry@kernel.org> <harry.yoo@oracle.com>
319320
Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
320321
Heiko Carstens <hca@linux.ibm.com> <heiko.carstens@de.ibm.com>
321322
Heiko Stuebner <heiko@sntech.de> <heiko.stuebner@bqreaders.com>

MAINTAINERS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16883,7 +16883,7 @@ M: Lorenzo Stoakes <ljs@kernel.org>
1688316883
R: Rik van Riel <riel@surriel.com>
1688416884
R: Liam R. Howlett <Liam.Howlett@oracle.com>
1688516885
R: Vlastimil Babka <vbabka@kernel.org>
16886-
R: Harry Yoo <harry.yoo@oracle.com>
16886+
R: Harry Yoo <harry@kernel.org>
1688716887
R: Jann Horn <jannh@google.com>
1688816888
L: linux-mm@kvack.org
1688916889
S: Maintained
@@ -24349,7 +24349,7 @@ F: drivers/nvmem/layouts/sl28vpd.c
2434924349

2435024350
SLAB ALLOCATOR
2435124351
M: Vlastimil Babka <vbabka@kernel.org>
24352-
M: Harry Yoo <harry.yoo@oracle.com>
24352+
M: Harry Yoo <harry@kernel.org>
2435324353
M: Andrew Morton <akpm@linux-foundation.org>
2435424354
R: Hao Li <hao.li@linux.dev>
2435524355
R: Christoph Lameter <cl@gentwo.org>

include/linux/leafops.h

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,23 @@ static inline unsigned long softleaf_to_pfn(softleaf_t entry)
363363
return swp_offset(entry) & SWP_PFN_MASK;
364364
}
365365

366+
static inline void softleaf_migration_sync(softleaf_t entry,
367+
struct folio *folio)
368+
{
369+
/*
370+
* Ensure we do not race with split, which might alter tail pages into new
371+
* folios and thus result in observing an unlocked folio.
372+
* This matches the write barrier in __split_folio_to_order().
373+
*/
374+
smp_rmb();
375+
376+
/*
377+
* Any use of migration entries may only occur while the
378+
* corresponding page is locked
379+
*/
380+
VM_WARN_ON_ONCE(!folio_test_locked(folio));
381+
}
382+
366383
/**
367384
* softleaf_to_page() - Obtains struct page for PFN encoded within leaf entry.
368385
* @entry: Leaf entry, softleaf_has_pfn(@entry) must return true.
@@ -374,11 +391,8 @@ static inline struct page *softleaf_to_page(softleaf_t entry)
374391
struct page *page = pfn_to_page(softleaf_to_pfn(entry));
375392

376393
VM_WARN_ON_ONCE(!softleaf_has_pfn(entry));
377-
/*
378-
* Any use of migration entries may only occur while the
379-
* corresponding page is locked
380-
*/
381-
VM_WARN_ON_ONCE(softleaf_is_migration(entry) && !PageLocked(page));
394+
if (softleaf_is_migration(entry))
395+
softleaf_migration_sync(entry, page_folio(page));
382396

383397
return page;
384398
}
@@ -394,12 +408,8 @@ static inline struct folio *softleaf_to_folio(softleaf_t entry)
394408
struct folio *folio = pfn_folio(softleaf_to_pfn(entry));
395409

396410
VM_WARN_ON_ONCE(!softleaf_has_pfn(entry));
397-
/*
398-
* Any use of migration entries may only occur while the
399-
* corresponding folio is locked.
400-
*/
401-
VM_WARN_ON_ONCE(softleaf_is_migration(entry) &&
402-
!folio_test_locked(folio));
411+
if (softleaf_is_migration(entry))
412+
softleaf_migration_sync(entry, folio);
403413

404414
return folio;
405415
}

lib/bug.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,8 @@ struct bug_entry *find_bug(unsigned long bugaddr)
173173
return module_find_bug(bugaddr);
174174
}
175175

176-
__diag_push();
177-
__diag_ignore(GCC, all, "-Wsuggest-attribute=format",
178-
"Not a valid __printf() conversion candidate.");
179-
static void __warn_printf(const char *fmt, struct pt_regs *regs)
176+
static __printf(1, 0)
177+
void __warn_printf(const char *fmt, struct pt_regs *regs)
180178
{
181179
if (!fmt)
182180
return;
@@ -195,7 +193,6 @@ static void __warn_printf(const char *fmt, struct pt_regs *regs)
195193

196194
printk("%s", fmt);
197195
}
198-
__diag_pop();
199196

200197
static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long bugaddr, struct pt_regs *regs)
201198
{

mm/damon/sysfs.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1524,8 +1524,10 @@ static int damon_sysfs_commit_input(void *data)
15241524
if (IS_ERR(param_ctx))
15251525
return PTR_ERR(param_ctx);
15261526
test_ctx = damon_sysfs_new_test_ctx(kdamond->damon_ctx);
1527-
if (!test_ctx)
1527+
if (!test_ctx) {
1528+
damon_destroy_ctx(param_ctx);
15281529
return -ENOMEM;
1530+
}
15291531
err = damon_commit_ctx(test_ctx, param_ctx);
15301532
if (err)
15311533
goto out;
@@ -1618,9 +1620,12 @@ static int damon_sysfs_repeat_call_fn(void *data)
16181620

16191621
if (!mutex_trylock(&damon_sysfs_lock))
16201622
return 0;
1623+
if (sysfs_kdamond->contexts->nr != 1)
1624+
goto out;
16211625
damon_sysfs_upd_tuned_intervals(sysfs_kdamond);
16221626
damon_sysfs_upd_schemes_stats(sysfs_kdamond);
16231627
damon_sysfs_upd_schemes_effective_quotas(sysfs_kdamond);
1628+
out:
16241629
mutex_unlock(&damon_sysfs_lock);
16251630
return 0;
16261631
}
@@ -1747,6 +1752,9 @@ static int damon_sysfs_update_schemes_tried_regions(
17471752
static int damon_sysfs_handle_cmd(enum damon_sysfs_cmd cmd,
17481753
struct damon_sysfs_kdamond *kdamond)
17491754
{
1755+
if (cmd != DAMON_SYSFS_CMD_OFF && kdamond->contexts->nr != 1)
1756+
return -EINVAL;
1757+
17501758
switch (cmd) {
17511759
case DAMON_SYSFS_CMD_ON:
17521760
return damon_sysfs_turn_damon_on(kdamond);

mm/memory.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6815,11 +6815,16 @@ int follow_pfnmap_start(struct follow_pfnmap_args *args)
68156815

68166816
pudp = pud_offset(p4dp, address);
68176817
pud = pudp_get(pudp);
6818-
if (pud_none(pud))
6818+
if (!pud_present(pud))
68196819
goto out;
68206820
if (pud_leaf(pud)) {
68216821
lock = pud_lock(mm, pudp);
6822-
if (!unlikely(pud_leaf(pud))) {
6822+
pud = pudp_get(pudp);
6823+
6824+
if (unlikely(!pud_present(pud))) {
6825+
spin_unlock(lock);
6826+
goto out;
6827+
} else if (unlikely(!pud_leaf(pud))) {
68236828
spin_unlock(lock);
68246829
goto retry;
68256830
}
@@ -6831,9 +6836,16 @@ int follow_pfnmap_start(struct follow_pfnmap_args *args)
68316836

68326837
pmdp = pmd_offset(pudp, address);
68336838
pmd = pmdp_get_lockless(pmdp);
6839+
if (!pmd_present(pmd))
6840+
goto out;
68346841
if (pmd_leaf(pmd)) {
68356842
lock = pmd_lock(mm, pmdp);
6836-
if (!unlikely(pmd_leaf(pmd))) {
6843+
pmd = pmdp_get(pmdp);
6844+
6845+
if (unlikely(!pmd_present(pmd))) {
6846+
spin_unlock(lock);
6847+
goto out;
6848+
} else if (unlikely(!pmd_leaf(pmd))) {
68376849
spin_unlock(lock);
68386850
goto retry;
68396851
}

mm/mseal.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ static int mseal_apply(struct mm_struct *mm,
5656
unsigned long start, unsigned long end)
5757
{
5858
struct vm_area_struct *vma, *prev;
59-
unsigned long curr_start = start;
6059
VMA_ITERATOR(vmi, mm, start);
6160

6261
/* We know there are no gaps so this will be non-NULL. */
@@ -66,6 +65,7 @@ static int mseal_apply(struct mm_struct *mm,
6665
prev = vma;
6766

6867
for_each_vma_range(vmi, vma, end) {
68+
const unsigned long curr_start = MAX(vma->vm_start, start);
6969
const unsigned long curr_end = MIN(vma->vm_end, end);
7070

7171
if (!(vma->vm_flags & VM_SEALED)) {
@@ -79,7 +79,6 @@ static int mseal_apply(struct mm_struct *mm,
7979
}
8080

8181
prev = vma;
82-
curr_start = curr_end;
8382
}
8483

8584
return 0;

mm/pagewalk.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
9797
static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
9898
struct mm_walk *walk)
9999
{
100+
pud_t pudval = pudp_get(pud);
100101
pmd_t *pmd;
101102
unsigned long next;
102103
const struct mm_walk_ops *ops = walk->ops;
@@ -105,6 +106,24 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
105106
int err = 0;
106107
int depth = real_depth(3);
107108

109+
/*
110+
* For PTE handling, pte_offset_map_lock() takes care of checking
111+
* whether there actually is a page table. But it also has to be
112+
* very careful about concurrent page table reclaim.
113+
*
114+
* Similarly, we have to be careful here - a PUD entry that points
115+
* to a PMD table cannot go away, so we can just walk it. But if
116+
* it's something else, we need to ensure we didn't race something,
117+
* so need to retry.
118+
*
119+
* A pertinent example of this is a PUD refault after PUD split -
120+
* we will need to split again or risk accessing invalid memory.
121+
*/
122+
if (!pud_present(pudval) || pud_leaf(pudval)) {
123+
walk->action = ACTION_AGAIN;
124+
return 0;
125+
}
126+
108127
pmd = pmd_offset(pud, addr);
109128
do {
110129
again:
@@ -218,12 +237,12 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
218237
else if (pud_leaf(*pud) || !pud_present(*pud))
219238
continue; /* Nothing to do. */
220239

221-
if (pud_none(*pud))
222-
goto again;
223-
224240
err = walk_pmd_range(pud, addr, next, walk);
225241
if (err)
226242
break;
243+
244+
if (walk->action == ACTION_AGAIN)
245+
goto again;
227246
} while (pud++, addr = next, addr != end);
228247

229248
return err;

mm/swap_state.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,10 @@ static struct folio *__swap_cache_prepare_and_add(swp_entry_t entry,
494494

495495
__folio_set_locked(folio);
496496
__folio_set_swapbacked(folio);
497+
498+
if (!charged && mem_cgroup_swapin_charge_folio(folio, NULL, gfp, entry))
499+
goto failed;
500+
497501
for (;;) {
498502
ret = swap_cache_add_folio(folio, entry, &shadow);
499503
if (!ret)
@@ -514,11 +518,6 @@ static struct folio *__swap_cache_prepare_and_add(swp_entry_t entry,
514518
goto failed;
515519
}
516520

517-
if (!charged && mem_cgroup_swapin_charge_folio(folio, NULL, gfp, entry)) {
518-
swap_cache_del_folio(folio);
519-
goto failed;
520-
}
521-
522521
memcg1_swapin(entry, folio_nr_pages(folio));
523522
if (shadow)
524523
workingset_refault(folio, shadow);

0 commit comments

Comments
 (0)