Skip to content

Commit 8026aed

Browse files
committed
Merge tag 'mm-hotfixes-stable-2025-09-01-17-20' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "17 hotfixes. 13 are cc:stable and the remainder address post-6.16 issues or aren't considered necessary for -stable kernels. 11 of these fixes are for MM. This includes a three-patch series from Harry Yoo which fixes an intermittent boot failure which can occur on x86 systems. And a two-patch series from Alexander Gordeev which fixes a KASAN crash on S390 systems" * tag 'mm-hotfixes-stable-2025-09-01-17-20' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm: fix possible deadlock in kmemleak x86/mm/64: define ARCH_PAGE_TABLE_SYNC_MASK and arch_sync_kernel_mappings() mm: introduce and use {pgd,p4d}_populate_kernel() mm: move page table sync declarations to linux/pgtable.h proc: fix missing pde_set_flags() for net proc files mm: fix accounting of memmap pages mm/damon/core: prevent unnecessary overflow in damos_set_effective_quota() kexec: add KEXEC_FILE_NO_CMA as a legal flag kasan: fix GCC mem-intrinsic prefix with sw tags mm/kasan: avoid lazy MMU mode hazards mm/kasan: fix vmalloc shadow memory (de-)population races kunit: kasan_test: disable fortify string checker on kasan_strings() test selftests/mm: fix FORCE_READ to read input value correctly mm/userfaultfd: fix kmap_local LIFO ordering for CONFIG_HIGHPTE ocfs2: prevent release journal inode after journal shutdown rust: mm: mark VmaNew as transparent of_numa: fix uninitialized memory nodes causing kernel panic
2 parents e3c94a5 + c873ccb commit 8026aed

File tree

27 files changed

+190
-94
lines changed

27 files changed

+190
-94
lines changed

arch/x86/include/asm/pgtable_64_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ static inline bool pgtable_l5_enabled(void)
3636
#define pgtable_l5_enabled() cpu_feature_enabled(X86_FEATURE_LA57)
3737
#endif /* USE_EARLY_PGTABLE_L5 */
3838

39+
#define ARCH_PAGE_TABLE_SYNC_MASK \
40+
(pgtable_l5_enabled() ? PGTBL_PGD_MODIFIED : PGTBL_P4D_MODIFIED)
41+
3942
extern unsigned int pgdir_shift;
4043
extern unsigned int ptrs_per_p4d;
4144

arch/x86/mm/init_64.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,24 @@ static void sync_global_pgds(unsigned long start, unsigned long end)
223223
sync_global_pgds_l4(start, end);
224224
}
225225

226+
/*
227+
* Make kernel mappings visible in all page tables in the system.
228+
* This is necessary except when the init task populates kernel mappings
229+
* during the boot process. In that case, all processes originating from
230+
* the init task copies the kernel mappings, so there is no issue.
231+
* Otherwise, missing synchronization could lead to kernel crashes due
232+
* to missing page table entries for certain kernel mappings.
233+
*
234+
* Synchronization is performed at the top level, which is the PGD in
235+
* 5-level paging systems. But in 4-level paging systems, however,
236+
* pgd_populate() is a no-op, so synchronization is done at the P4D level.
237+
* sync_global_pgds() handles this difference between paging levels.
238+
*/
239+
void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
240+
{
241+
sync_global_pgds(start, end);
242+
}
243+
226244
/*
227245
* NOTE: This function is marked __ref because it calls __init function
228246
* (alloc_bootmem_pages). It's safe to do it ONLY when after_bootmem == 0.

drivers/of/of_numa.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,11 @@ static int __init of_numa_parse_memory_nodes(void)
5959
r = -EINVAL;
6060
}
6161

62-
for (i = 0; !r && !of_address_to_resource(np, i, &rsrc); i++)
62+
for (i = 0; !r && !of_address_to_resource(np, i, &rsrc); i++) {
6363
r = numa_add_memblk(nid, rsrc.start, rsrc.end + 1);
64+
if (!r)
65+
node_set(nid, numa_nodes_parsed);
66+
}
6467

6568
if (!i || r) {
6669
of_node_put(np);

fs/ocfs2/inode.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,9 @@ static void ocfs2_clear_inode(struct inode *inode)
12811281
* the journal is flushed before journal shutdown. Thus it is safe to
12821282
* have inodes get cleaned up after journal shutdown.
12831283
*/
1284+
if (!osb->journal)
1285+
return;
1286+
12841287
jbd2_journal_release_jbd_inode(osb->journal->j_journal,
12851288
&oi->ip_jinode);
12861289
}

fs/proc/generic.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -367,13 +367,34 @@ static const struct inode_operations proc_dir_inode_operations = {
367367
.setattr = proc_notify_change,
368368
};
369369

370+
static void pde_set_flags(struct proc_dir_entry *pde)
371+
{
372+
const struct proc_ops *proc_ops = pde->proc_ops;
373+
374+
if (!proc_ops)
375+
return;
376+
377+
if (proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
378+
pde->flags |= PROC_ENTRY_PERMANENT;
379+
if (proc_ops->proc_read_iter)
380+
pde->flags |= PROC_ENTRY_proc_read_iter;
381+
#ifdef CONFIG_COMPAT
382+
if (proc_ops->proc_compat_ioctl)
383+
pde->flags |= PROC_ENTRY_proc_compat_ioctl;
384+
#endif
385+
if (proc_ops->proc_lseek)
386+
pde->flags |= PROC_ENTRY_proc_lseek;
387+
}
388+
370389
/* returns the registered entry, or frees dp and returns NULL on failure */
371390
struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
372391
struct proc_dir_entry *dp)
373392
{
374393
if (proc_alloc_inum(&dp->low_ino))
375394
goto out_free_entry;
376395

396+
pde_set_flags(dp);
397+
377398
write_lock(&proc_subdir_lock);
378399
dp->parent = dir;
379400
if (pde_subdir_insert(dir, dp) == false) {
@@ -561,20 +582,6 @@ struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
561582
return p;
562583
}
563584

564-
static void pde_set_flags(struct proc_dir_entry *pde)
565-
{
566-
if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
567-
pde->flags |= PROC_ENTRY_PERMANENT;
568-
if (pde->proc_ops->proc_read_iter)
569-
pde->flags |= PROC_ENTRY_proc_read_iter;
570-
#ifdef CONFIG_COMPAT
571-
if (pde->proc_ops->proc_compat_ioctl)
572-
pde->flags |= PROC_ENTRY_proc_compat_ioctl;
573-
#endif
574-
if (pde->proc_ops->proc_lseek)
575-
pde->flags |= PROC_ENTRY_proc_lseek;
576-
}
577-
578585
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
579586
struct proc_dir_entry *parent,
580587
const struct proc_ops *proc_ops, void *data)
@@ -585,7 +592,6 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
585592
if (!p)
586593
return NULL;
587594
p->proc_ops = proc_ops;
588-
pde_set_flags(p);
589595
return proc_register(parent, p);
590596
}
591597
EXPORT_SYMBOL(proc_create_data);
@@ -636,7 +642,6 @@ struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
636642
p->proc_ops = &proc_seq_ops;
637643
p->seq_ops = ops;
638644
p->state_size = state_size;
639-
pde_set_flags(p);
640645
return proc_register(parent, p);
641646
}
642647
EXPORT_SYMBOL(proc_create_seq_private);
@@ -667,7 +672,6 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
667672
return NULL;
668673
p->proc_ops = &proc_single_ops;
669674
p->single_show = show;
670-
pde_set_flags(p);
671675
return proc_register(parent, p);
672676
}
673677
EXPORT_SYMBOL(proc_create_single_data);

include/linux/kexec.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ bool kexec_load_permitted(int kexec_image_type);
460460

461461
/* List of defined/legal kexec file flags */
462462
#define KEXEC_FILE_FLAGS (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
463-
KEXEC_FILE_NO_INITRAMFS | KEXEC_FILE_DEBUG)
463+
KEXEC_FILE_NO_INITRAMFS | KEXEC_FILE_DEBUG | \
464+
KEXEC_FILE_NO_CMA)
464465

465466
/* flag to track if kexec reboot is in progress */
466467
extern bool kexec_in_progress;

include/linux/pgalloc.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _LINUX_PGALLOC_H
3+
#define _LINUX_PGALLOC_H
4+
5+
#include <linux/pgtable.h>
6+
#include <asm/pgalloc.h>
7+
8+
/*
9+
* {pgd,p4d}_populate_kernel() are defined as macros to allow
10+
* compile-time optimization based on the configured page table levels.
11+
* Without this, linking may fail because callers (e.g., KASAN) may rely
12+
* on calls to these functions being optimized away when passing symbols
13+
* that exist only for certain page table levels.
14+
*/
15+
#define pgd_populate_kernel(addr, pgd, p4d) \
16+
do { \
17+
pgd_populate(&init_mm, pgd, p4d); \
18+
if (ARCH_PAGE_TABLE_SYNC_MASK & PGTBL_PGD_MODIFIED) \
19+
arch_sync_kernel_mappings(addr, addr); \
20+
} while (0)
21+
22+
#define p4d_populate_kernel(addr, p4d, pud) \
23+
do { \
24+
p4d_populate(&init_mm, p4d, pud); \
25+
if (ARCH_PAGE_TABLE_SYNC_MASK & PGTBL_P4D_MODIFIED) \
26+
arch_sync_kernel_mappings(addr, addr); \
27+
} while (0)
28+
29+
#endif /* _LINUX_PGALLOC_H */

include/linux/pgtable.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,22 @@ static inline void modify_prot_commit_ptes(struct vm_area_struct *vma, unsigned
14671467
}
14681468
#endif
14691469

1470+
/*
1471+
* Architectures can set this mask to a combination of PGTBL_P?D_MODIFIED values
1472+
* and let generic vmalloc, ioremap and page table update code know when
1473+
* arch_sync_kernel_mappings() needs to be called.
1474+
*/
1475+
#ifndef ARCH_PAGE_TABLE_SYNC_MASK
1476+
#define ARCH_PAGE_TABLE_SYNC_MASK 0
1477+
#endif
1478+
1479+
/*
1480+
* There is no default implementation for arch_sync_kernel_mappings(). It is
1481+
* relied upon the compiler to optimize calls out if ARCH_PAGE_TABLE_SYNC_MASK
1482+
* is 0.
1483+
*/
1484+
void arch_sync_kernel_mappings(unsigned long start, unsigned long end);
1485+
14701486
#endif /* CONFIG_MMU */
14711487

14721488
/*
@@ -1938,10 +1954,11 @@ static inline bool arch_has_pfn_modify_check(void)
19381954
/*
19391955
* Page Table Modification bits for pgtbl_mod_mask.
19401956
*
1941-
* These are used by the p?d_alloc_track*() set of functions an in the generic
1942-
* vmalloc/ioremap code to track at which page-table levels entries have been
1943-
* modified. Based on that the code can better decide when vmalloc and ioremap
1944-
* mapping changes need to be synchronized to other page-tables in the system.
1957+
* These are used by the p?d_alloc_track*() and p*d_populate_kernel()
1958+
* functions in the generic vmalloc, ioremap and page table update code
1959+
* to track at which page-table levels entries have been modified.
1960+
* Based on that the code can better decide when page table changes need
1961+
* to be synchronized to other page-tables in the system.
19451962
*/
19461963
#define __PGTBL_PGD_MODIFIED 0
19471964
#define __PGTBL_P4D_MODIFIED 1

include/linux/vmalloc.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -219,22 +219,6 @@ extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
219219
int vmap_pages_range(unsigned long addr, unsigned long end, pgprot_t prot,
220220
struct page **pages, unsigned int page_shift);
221221

222-
/*
223-
* Architectures can set this mask to a combination of PGTBL_P?D_MODIFIED values
224-
* and let generic vmalloc and ioremap code know when arch_sync_kernel_mappings()
225-
* needs to be called.
226-
*/
227-
#ifndef ARCH_PAGE_TABLE_SYNC_MASK
228-
#define ARCH_PAGE_TABLE_SYNC_MASK 0
229-
#endif
230-
231-
/*
232-
* There is no default implementation for arch_sync_kernel_mappings(). It is
233-
* relied upon the compiler to optimize calls out if ARCH_PAGE_TABLE_SYNC_MASK
234-
* is 0.
235-
*/
236-
void arch_sync_kernel_mappings(unsigned long start, unsigned long end);
237-
238222
/*
239223
* Lowlevel-APIs (not for driver use!)
240224
*/

mm/damon/core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,8 +2073,8 @@ static void damos_set_effective_quota(struct damos_quota *quota)
20732073

20742074
if (quota->ms) {
20752075
if (quota->total_charged_ns)
2076-
throughput = quota->total_charged_sz * 1000000 /
2077-
quota->total_charged_ns;
2076+
throughput = mult_frac(quota->total_charged_sz, 1000000,
2077+
quota->total_charged_ns);
20782078
else
20792079
throughput = PAGE_SIZE * 1024;
20802080
esz = min(throughput * quota->ms, esz);

0 commit comments

Comments
 (0)