Skip to content

Commit 27b9989

Browse files
committed
Merge tag 'mm-hotfixes-stable-2025-06-13-21-56' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "9 hotfixes. 3 are cc:stable and the remainder address post-6.15 issues or aren't considered necessary for -stable kernels. Only 4 are for MM" * tag 'mm-hotfixes-stable-2025-06-13-21-56' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm: add mmap_prepare() compatibility layer for nested file systems init: fix build warnings about export.h MAINTAINERS: add Barry as a THP reviewer drivers/rapidio/rio_cm.c: prevent possible heap overwrite mm: close theoretical race where stale TLB entries could linger mm/vma: reset VMA iterator on commit_merge() OOM failure docs: proc: update VmFlags documentation in smaps scatterlist: fix extraneous '@'-sign kernel-doc notation selftests/mm: skip failed memfd setups in gup_longterm
2 parents 4774cfe + bb666b7 commit 27b9989

File tree

14 files changed

+134
-29
lines changed

14 files changed

+134
-29
lines changed

Documentation/filesystems/proc.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,6 @@ encoded manner. The codes are the following:
584584
ms may share
585585
gd stack segment growns down
586586
pf pure PFN range
587-
dw disabled write to the mapped file
588587
lo pages are locked in memory
589588
io memory mapped I/O area
590589
sr sequential read advise provided
@@ -607,8 +606,11 @@ encoded manner. The codes are the following:
607606
mt arm64 MTE allocation tags are enabled
608607
um userfaultfd missing tracking
609608
uw userfaultfd wr-protect tracking
609+
ui userfaultfd minor fault
610610
ss shadow/guarded control stack page
611611
sl sealed
612+
lf lock on fault pages
613+
dp always lazily freeable mapping
612614
== =======================================
613615

614616
Note that there is no guarantee that every flag and associated mnemonic will

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15921,6 +15921,7 @@ R: Liam R. Howlett <[email protected]>
1592115921
R: Nico Pache <[email protected]>
1592215922
R: Ryan Roberts <[email protected]>
1592315923
R: Dev Jain <[email protected]>
15924+
R: Barry Song <[email protected]>
1592415925
1592515926
S: Maintained
1592615927
W: http://www.linux-mm.org

drivers/rapidio/rio_cm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,9 @@ static int riocm_ch_send(u16 ch_id, void *buf, int len)
783783
if (buf == NULL || ch_id == 0 || len == 0 || len > RIO_MAX_MSG_SIZE)
784784
return -EINVAL;
785785

786+
if (len < sizeof(struct rio_ch_chan_hdr))
787+
return -EINVAL; /* insufficient data from user */
788+
786789
ch = riocm_get_channel(ch_id);
787790
if (!ch) {
788791
riocm_error("%s(%d) ch_%d not found", current->comm,

include/linux/fs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,10 +2274,12 @@ static inline bool file_has_valid_mmap_hooks(struct file *file)
22742274
return true;
22752275
}
22762276

2277+
int compat_vma_mmap_prepare(struct file *file, struct vm_area_struct *vma);
2278+
22772279
static inline int call_mmap(struct file *file, struct vm_area_struct *vma)
22782280
{
2279-
if (WARN_ON_ONCE(file->f_op->mmap_prepare))
2280-
return -EINVAL;
2281+
if (file->f_op->mmap_prepare)
2282+
return compat_vma_mmap_prepare(file, vma);
22812283

22822284
return file->f_op->mmap(file, vma);
22832285
}

include/linux/scatterlist.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static inline bool sg_is_last(struct scatterlist *sg)
9999
* @sg: The current sg entry
100100
*
101101
* Description:
102-
* Usually the next entry will be @sg@ + 1, but if this sg element is part
102+
* Usually the next entry will be @sg + 1, but if this sg element is part
103103
* of a chained scatterlist, it could jump to the start of a new
104104
* scatterlist array.
105105
*
@@ -254,7 +254,7 @@ static inline void __sg_chain(struct scatterlist *chain_sg,
254254
* @sgl: Second scatterlist
255255
*
256256
* Description:
257-
* Links @prv@ and @sgl@ together, to form a longer scatterlist.
257+
* Links @prv and @sgl together, to form a longer scatterlist.
258258
*
259259
**/
260260
static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,

init/initramfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22
#include <linux/init.h>
33
#include <linux/async.h>
4+
#include <linux/export.h>
45
#include <linux/fs.h>
56
#include <linux/slab.h>
67
#include <linux/types.h>

init/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define DEBUG /* Enable initcall_debug */
1414

1515
#include <linux/types.h>
16+
#include <linux/export.h>
1617
#include <linux/extable.h>
1718
#include <linux/module.h>
1819
#include <linux/proc_fs.h>

lib/scatterlist.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ EXPORT_SYMBOL(sg_nents_for_len);
7373
* Should only be used casually, it (currently) scans the entire list
7474
* to get the last entry.
7575
*
76-
* Note that the @sgl@ pointer passed in need not be the first one,
77-
* the important bit is that @nents@ denotes the number of entries that
78-
* exist from @sgl@.
76+
* Note that the @sgl pointer passed in need not be the first one,
77+
* the important bit is that @nents denotes the number of entries that
78+
* exist from @sgl.
7979
*
8080
**/
8181
struct scatterlist *sg_last(struct scatterlist *sgl, unsigned int nents)
@@ -345,7 +345,7 @@ EXPORT_SYMBOL(__sg_alloc_table);
345345
* @gfp_mask: GFP allocation mask
346346
*
347347
* Description:
348-
* Allocate and initialize an sg table. If @nents@ is larger than
348+
* Allocate and initialize an sg table. If @nents is larger than
349349
* SG_MAX_SINGLE_ALLOC a chained sg table will be setup.
350350
*
351351
**/

mm/madvise.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
508508
pte_offset_map_lock(mm, pmd, addr, &ptl);
509509
if (!start_pte)
510510
break;
511+
flush_tlb_batched_pending(mm);
511512
arch_enter_lazy_mmu_mode();
512513
if (!err)
513514
nr = 0;
@@ -741,6 +742,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
741742
start_pte = pte;
742743
if (!start_pte)
743744
break;
745+
flush_tlb_batched_pending(mm);
744746
arch_enter_lazy_mmu_mode();
745747
if (!err)
746748
nr = 0;

mm/util.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,3 +1131,43 @@ void flush_dcache_folio(struct folio *folio)
11311131
}
11321132
EXPORT_SYMBOL(flush_dcache_folio);
11331133
#endif
1134+
1135+
/**
1136+
* compat_vma_mmap_prepare() - Apply the file's .mmap_prepare() hook to an
1137+
* existing VMA
1138+
* @file: The file which possesss an f_op->mmap_prepare() hook
1139+
* @vma: The VMA to apply the .mmap_prepare() hook to.
1140+
*
1141+
* Ordinarily, .mmap_prepare() is invoked directly upon mmap(). However, certain
1142+
* 'wrapper' file systems invoke a nested mmap hook of an underlying file.
1143+
*
1144+
* Until all filesystems are converted to use .mmap_prepare(), we must be
1145+
* conservative and continue to invoke these 'wrapper' filesystems using the
1146+
* deprecated .mmap() hook.
1147+
*
1148+
* However we have a problem if the underlying file system possesses an
1149+
* .mmap_prepare() hook, as we are in a different context when we invoke the
1150+
* .mmap() hook, already having a VMA to deal with.
1151+
*
1152+
* compat_vma_mmap_prepare() is a compatibility function that takes VMA state,
1153+
* establishes a struct vm_area_desc descriptor, passes to the underlying
1154+
* .mmap_prepare() hook and applies any changes performed by it.
1155+
*
1156+
* Once the conversion of filesystems is complete this function will no longer
1157+
* be required and will be removed.
1158+
*
1159+
* Returns: 0 on success or error.
1160+
*/
1161+
int compat_vma_mmap_prepare(struct file *file, struct vm_area_struct *vma)
1162+
{
1163+
struct vm_area_desc desc;
1164+
int err;
1165+
1166+
err = file->f_op->mmap_prepare(vma_to_desc(vma, &desc));
1167+
if (err)
1168+
return err;
1169+
set_vma_from_desc(vma, &desc);
1170+
1171+
return 0;
1172+
}
1173+
EXPORT_SYMBOL(compat_vma_mmap_prepare);

mm/vma.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -967,26 +967,9 @@ static __must_check struct vm_area_struct *vma_merge_existing_range(
967967
err = dup_anon_vma(next, middle, &anon_dup);
968968
}
969969

970-
if (err)
970+
if (err || commit_merge(vmg))
971971
goto abort;
972972

973-
err = commit_merge(vmg);
974-
if (err) {
975-
VM_WARN_ON(err != -ENOMEM);
976-
977-
if (anon_dup)
978-
unlink_anon_vmas(anon_dup);
979-
980-
/*
981-
* We've cleaned up any cloned anon_vma's, no VMAs have been
982-
* modified, no harm no foul if the user requests that we not
983-
* report this and just give up, leaving the VMAs unmerged.
984-
*/
985-
if (!vmg->give_up_on_oom)
986-
vmg->state = VMA_MERGE_ERROR_NOMEM;
987-
return NULL;
988-
}
989-
990973
khugepaged_enter_vma(vmg->target, vmg->flags);
991974
vmg->state = VMA_MERGE_SUCCESS;
992975
return vmg->target;
@@ -995,6 +978,9 @@ static __must_check struct vm_area_struct *vma_merge_existing_range(
995978
vma_iter_set(vmg->vmi, start);
996979
vma_iter_load(vmg->vmi);
997980

981+
if (anon_dup)
982+
unlink_anon_vmas(anon_dup);
983+
998984
/*
999985
* This means we have failed to clone anon_vma's correctly, but no
1000986
* actual changes to VMAs have occurred, so no harm no foul - if the
@@ -3127,7 +3113,6 @@ int __vm_munmap(unsigned long start, size_t len, bool unlock)
31273113
return ret;
31283114
}
31293115

3130-
31313116
/* Insert vm structure into process list sorted by address
31323117
* and into the inode's i_mmap tree. If vm_file is non-NULL
31333118
* then i_mmap_rwsem is taken here.

mm/vma.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,53 @@ static inline int vma_iter_store_gfp(struct vma_iterator *vmi,
222222
return 0;
223223
}
224224

225+
226+
/*
227+
* Temporary helper functions for file systems which wrap an invocation of
228+
* f_op->mmap() but which might have an underlying file system which implements
229+
* f_op->mmap_prepare().
230+
*/
231+
232+
static inline struct vm_area_desc *vma_to_desc(struct vm_area_struct *vma,
233+
struct vm_area_desc *desc)
234+
{
235+
desc->mm = vma->vm_mm;
236+
desc->start = vma->vm_start;
237+
desc->end = vma->vm_end;
238+
239+
desc->pgoff = vma->vm_pgoff;
240+
desc->file = vma->vm_file;
241+
desc->vm_flags = vma->vm_flags;
242+
desc->page_prot = vma->vm_page_prot;
243+
244+
desc->vm_ops = NULL;
245+
desc->private_data = NULL;
246+
247+
return desc;
248+
}
249+
250+
static inline void set_vma_from_desc(struct vm_area_struct *vma,
251+
struct vm_area_desc *desc)
252+
{
253+
/*
254+
* Since we're invoking .mmap_prepare() despite having a partially
255+
* established VMA, we must take care to handle setting fields
256+
* correctly.
257+
*/
258+
259+
/* Mutable fields. Populated with initial state. */
260+
vma->vm_pgoff = desc->pgoff;
261+
if (vma->vm_file != desc->file)
262+
vma_set_file(vma, desc->file);
263+
if (vma->vm_flags != desc->vm_flags)
264+
vm_flags_set(vma, desc->vm_flags);
265+
vma->vm_page_prot = desc->page_prot;
266+
267+
/* User-defined fields. */
268+
vma->vm_ops = desc->vm_ops;
269+
vma->vm_private_data = desc->private_data;
270+
}
271+
225272
int
226273
do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
227274
struct mm_struct *mm, unsigned long start,

tools/testing/selftests/mm/gup_longterm.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,11 @@ static void run_with_memfd(test_fn fn, const char *desc)
298298
log_test_start("%s ... with memfd", desc);
299299

300300
fd = memfd_create("test", 0);
301-
if (fd < 0)
301+
if (fd < 0) {
302302
ksft_print_msg("memfd_create() failed (%s)\n", strerror(errno));
303+
log_test_result(KSFT_SKIP);
304+
return;
305+
}
303306

304307
fn(fd, pagesize);
305308
close(fd);
@@ -366,6 +369,8 @@ static void run_with_memfd_hugetlb(test_fn fn, const char *desc,
366369
fd = memfd_create("test", flags);
367370
if (fd < 0) {
368371
ksft_print_msg("memfd_create() failed (%s)\n", strerror(errno));
372+
log_test_result(KSFT_SKIP);
373+
return;
369374
}
370375

371376
fn(fd, hugetlbsize);

tools/testing/vma/vma_internal.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ typedef __bitwise unsigned int vm_fault_t;
159159

160160
#define ASSERT_EXCLUSIVE_WRITER(x)
161161

162+
/**
163+
* swap - swap values of @a and @b
164+
* @a: first value
165+
* @b: second value
166+
*/
167+
#define swap(a, b) \
168+
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
169+
162170
struct kref {
163171
refcount_t refcount;
164172
};
@@ -1468,4 +1476,12 @@ static inline void fixup_hugetlb_reservations(struct vm_area_struct *vma)
14681476
(void)vma;
14691477
}
14701478

1479+
static inline void vma_set_file(struct vm_area_struct *vma, struct file *file)
1480+
{
1481+
/* Changing an anonymous vma with this is illegal */
1482+
get_file(file);
1483+
swap(vma->vm_file, file);
1484+
fput(file);
1485+
}
1486+
14711487
#endif /* __MM_VMA_INTERNAL_H */

0 commit comments

Comments
 (0)