Commit 8026aed0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mm-hotfixes-stable-2025-09-01-17-20' of...

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
parents e3c94a53 c873ccbb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ static inline bool pgtable_l5_enabled(void)
#define pgtable_l5_enabled() cpu_feature_enabled(X86_FEATURE_LA57)
#endif /* USE_EARLY_PGTABLE_L5 */

#define ARCH_PAGE_TABLE_SYNC_MASK \
	(pgtable_l5_enabled() ? PGTBL_PGD_MODIFIED : PGTBL_P4D_MODIFIED)

extern unsigned int pgdir_shift;
extern unsigned int ptrs_per_p4d;

+18 −0
Original line number Diff line number Diff line
@@ -223,6 +223,24 @@ static void sync_global_pgds(unsigned long start, unsigned long end)
		sync_global_pgds_l4(start, end);
}

/*
 * Make kernel mappings visible in all page tables in the system.
 * This is necessary except when the init task populates kernel mappings
 * during the boot process. In that case, all processes originating from
 * the init task copies the kernel mappings, so there is no issue.
 * Otherwise, missing synchronization could lead to kernel crashes due
 * to missing page table entries for certain kernel mappings.
 *
 * Synchronization is performed at the top level, which is the PGD in
 * 5-level paging systems. But in 4-level paging systems, however,
 * pgd_populate() is a no-op, so synchronization is done at the P4D level.
 * sync_global_pgds() handles this difference between paging levels.
 */
void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
{
	sync_global_pgds(start, end);
}

/*
 * NOTE: This function is marked __ref because it calls __init function
 * (alloc_bootmem_pages). It's safe to do it ONLY when after_bootmem == 0.
+4 −1
Original line number Diff line number Diff line
@@ -59,8 +59,11 @@ static int __init of_numa_parse_memory_nodes(void)
			r = -EINVAL;
		}

		for (i = 0; !r && !of_address_to_resource(np, i, &rsrc); i++)
		for (i = 0; !r && !of_address_to_resource(np, i, &rsrc); i++) {
			r = numa_add_memblk(nid, rsrc.start, rsrc.end + 1);
			if (!r)
				node_set(nid, numa_nodes_parsed);
		}

		if (!i || r) {
			of_node_put(np);
+3 −0
Original line number Diff line number Diff line
@@ -1281,6 +1281,9 @@ static void ocfs2_clear_inode(struct inode *inode)
	 * the journal is flushed before journal shutdown. Thus it is safe to
	 * have inodes get cleaned up after journal shutdown.
	 */
	if (!osb->journal)
		return;

	jbd2_journal_release_jbd_inode(osb->journal->j_journal,
				       &oi->ip_jinode);
}
+21 −17
Original line number Diff line number Diff line
@@ -367,6 +367,25 @@ static const struct inode_operations proc_dir_inode_operations = {
	.setattr	= proc_notify_change,
};

static void pde_set_flags(struct proc_dir_entry *pde)
{
	const struct proc_ops *proc_ops = pde->proc_ops;

	if (!proc_ops)
		return;

	if (proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
		pde->flags |= PROC_ENTRY_PERMANENT;
	if (proc_ops->proc_read_iter)
		pde->flags |= PROC_ENTRY_proc_read_iter;
#ifdef CONFIG_COMPAT
	if (proc_ops->proc_compat_ioctl)
		pde->flags |= PROC_ENTRY_proc_compat_ioctl;
#endif
	if (proc_ops->proc_lseek)
		pde->flags |= PROC_ENTRY_proc_lseek;
}

/* returns the registered entry, or frees dp and returns NULL on failure */
struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
		struct proc_dir_entry *dp)
@@ -374,6 +393,8 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
	if (proc_alloc_inum(&dp->low_ino))
		goto out_free_entry;

	pde_set_flags(dp);

	write_lock(&proc_subdir_lock);
	dp->parent = dir;
	if (pde_subdir_insert(dir, dp) == false) {
@@ -561,20 +582,6 @@ struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
	return p;
}

static void pde_set_flags(struct proc_dir_entry *pde)
{
	if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
		pde->flags |= PROC_ENTRY_PERMANENT;
	if (pde->proc_ops->proc_read_iter)
		pde->flags |= PROC_ENTRY_proc_read_iter;
#ifdef CONFIG_COMPAT
	if (pde->proc_ops->proc_compat_ioctl)
		pde->flags |= PROC_ENTRY_proc_compat_ioctl;
#endif
	if (pde->proc_ops->proc_lseek)
		pde->flags |= PROC_ENTRY_proc_lseek;
}

struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
		struct proc_dir_entry *parent,
		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,
	if (!p)
		return NULL;
	p->proc_ops = proc_ops;
	pde_set_flags(p);
	return proc_register(parent, p);
}
EXPORT_SYMBOL(proc_create_data);
@@ -636,7 +642,6 @@ struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
	p->proc_ops = &proc_seq_ops;
	p->seq_ops = ops;
	p->state_size = state_size;
	pde_set_flags(p);
	return proc_register(parent, p);
}
EXPORT_SYMBOL(proc_create_seq_private);
@@ -667,7 +672,6 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
		return NULL;
	p->proc_ops = &proc_single_ops;
	p->single_show = show;
	pde_set_flags(p);
	return proc_register(parent, p);
}
EXPORT_SYMBOL(proc_create_single_data);
Loading