Skip to content

Commit 09d95bc

Browse files
committed
Merge tag 'mm-hotfixes-stable-2025-09-27-22-35' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "7 hotfixes. 4 are cc:stable and the remainder address post-6.16 issues or aren't considered necessary for -stable kernels. 6 of these fixes are for MM. All singletons, please see the changelogs for details" * tag 'mm-hotfixes-stable-2025-09-27-22-35' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: include/linux/pgtable.h: convert arch_enter_lazy_mmu_mode() and friends to static inlines mm/damon/sysfs: do not ignore callback's return value in damon_sysfs_damon_call() mailmap: add entry for Bence Csókás fs/proc/task_mmu: check p->vec_buf for NULL kmsan: fix out-of-bounds access to shadow memory mm/hugetlb: fix copy_hugetlb_page_range() to use ->pt_share_count mm/hugetlb: fix folio is still mapped when deleted
2 parents 51a24b7 + 7e89979 commit 09d95bc

File tree

9 files changed

+49
-21
lines changed

9 files changed

+49
-21
lines changed

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ Ben M Cahill <ben.m.cahill@intel.com>
134134
Ben Widawsky <bwidawsk@kernel.org> <ben@bwidawsk.net>
135135
Ben Widawsky <bwidawsk@kernel.org> <ben.widawsky@intel.com>
136136
Ben Widawsky <bwidawsk@kernel.org> <benjamin.widawsky@intel.com>
137+
Bence Csókás <bence98@sch.bme.hu> <csokas.bence@prolan.hu>
137138
Benjamin Poirier <benjamin.poirier@gmail.com> <bpoirier@suse.de>
138139
Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@gmail.com>
139140
Benjamin Tissoires <bentiss@kernel.org> <benjamin.tissoires@redhat.com>

fs/hugetlbfs/inode.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -517,14 +517,16 @@ static bool remove_inode_single_folio(struct hstate *h, struct inode *inode,
517517

518518
/*
519519
* If folio is mapped, it was faulted in after being
520-
* unmapped in caller. Unmap (again) while holding
521-
* the fault mutex. The mutex will prevent faults
522-
* until we finish removing the folio.
520+
* unmapped in caller or hugetlb_vmdelete_list() skips
521+
* unmapping it due to fail to grab lock. Unmap (again)
522+
* while holding the fault mutex. The mutex will prevent
523+
* faults until we finish removing the folio. Hold folio
524+
* lock to guarantee no concurrent migration.
523525
*/
526+
folio_lock(folio);
524527
if (unlikely(folio_mapped(folio)))
525528
hugetlb_unmap_file_folio(h, mapping, folio, index);
526529

527-
folio_lock(folio);
528530
/*
529531
* We must remove the folio from page cache before removing
530532
* the region/ reserve map (hugetlb_unreserve_pages). In

fs/proc/task_mmu.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,9 @@ static void pagemap_scan_backout_range(struct pagemap_scan_private *p,
24172417
{
24182418
struct page_region *cur_buf = &p->vec_buf[p->vec_buf_index];
24192419

2420+
if (!p->vec_buf)
2421+
return;
2422+
24202423
if (cur_buf->start != addr)
24212424
cur_buf->end = addr;
24222425
else

include/linux/mm_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,11 @@ static inline int ptdesc_pmd_pts_count(struct ptdesc *ptdesc)
631631
{
632632
return atomic_read(&ptdesc->pt_share_count);
633633
}
634+
635+
static inline bool ptdesc_pmd_is_shared(struct ptdesc *ptdesc)
636+
{
637+
return !!ptdesc_pmd_pts_count(ptdesc);
638+
}
634639
#else
635640
static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
636641
{

include/linux/pgtable.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@ static inline int pmd_dirty(pmd_t pmd)
232232
* and the mode cannot be used in interrupt context.
233233
*/
234234
#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
235-
#define arch_enter_lazy_mmu_mode() do {} while (0)
236-
#define arch_leave_lazy_mmu_mode() do {} while (0)
237-
#define arch_flush_lazy_mmu_mode() do {} while (0)
235+
static inline void arch_enter_lazy_mmu_mode(void) {}
236+
static inline void arch_leave_lazy_mmu_mode(void) {}
237+
static inline void arch_flush_lazy_mmu_mode(void) {}
238238
#endif
239239

240240
#ifndef pte_batch_hint

mm/damon/sysfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1592,12 +1592,14 @@ static int damon_sysfs_damon_call(int (*fn)(void *data),
15921592
struct damon_sysfs_kdamond *kdamond)
15931593
{
15941594
struct damon_call_control call_control = {};
1595+
int err;
15951596

15961597
if (!kdamond->damon_ctx)
15971598
return -EINVAL;
15981599
call_control.fn = fn;
15991600
call_control.data = kdamond;
1600-
return damon_call(kdamond->damon_ctx, &call_control);
1601+
err = damon_call(kdamond->damon_ctx, &call_control);
1602+
return err ? err : call_control.return_code;
16011603
}
16021604

16031605
struct damon_sysfs_schemes_walk_data {

mm/hugetlb.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5594,18 +5594,13 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
55945594
break;
55955595
}
55965596

5597-
/*
5598-
* If the pagetables are shared don't copy or take references.
5599-
*
5600-
* dst_pte == src_pte is the common case of src/dest sharing.
5601-
* However, src could have 'unshared' and dst shares with
5602-
* another vma. So page_count of ptep page is checked instead
5603-
* to reliably determine whether pte is shared.
5604-
*/
5605-
if (page_count(virt_to_page(dst_pte)) > 1) {
5597+
#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
5598+
/* If the pagetables are shared, there is nothing to do */
5599+
if (ptdesc_pmd_is_shared(virt_to_ptdesc(dst_pte))) {
56065600
addr |= last_addr_mask;
56075601
continue;
56085602
}
5603+
#endif
56095604

56105605
dst_ptl = huge_pte_lock(h, dst, dst_pte);
56115606
src_ptl = huge_pte_lockptr(h, src, src_pte);
@@ -7602,7 +7597,7 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
76027597
hugetlb_vma_assert_locked(vma);
76037598
if (sz != PMD_SIZE)
76047599
return 0;
7605-
if (!ptdesc_pmd_pts_count(virt_to_ptdesc(ptep)))
7600+
if (!ptdesc_pmd_is_shared(virt_to_ptdesc(ptep)))
76067601
return 0;
76077602

76087603
pud_clear(pud);

mm/kmsan/core.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b,
195195
u32 origin, bool checked)
196196
{
197197
u64 address = (u64)addr;
198-
u32 *shadow_start, *origin_start;
198+
void *shadow_start;
199+
u32 *aligned_shadow, *origin_start;
199200
size_t pad = 0;
200201

201202
KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(addr, size));
@@ -214,9 +215,12 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b,
214215
}
215216
__memset(shadow_start, b, size);
216217

217-
if (!IS_ALIGNED(address, KMSAN_ORIGIN_SIZE)) {
218+
if (IS_ALIGNED(address, KMSAN_ORIGIN_SIZE)) {
219+
aligned_shadow = shadow_start;
220+
} else {
218221
pad = address % KMSAN_ORIGIN_SIZE;
219222
address -= pad;
223+
aligned_shadow = shadow_start - pad;
220224
size += pad;
221225
}
222226
size = ALIGN(size, KMSAN_ORIGIN_SIZE);
@@ -230,7 +234,7 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b,
230234
* corresponding shadow slot is zero.
231235
*/
232236
for (int i = 0; i < size / KMSAN_ORIGIN_SIZE; i++) {
233-
if (origin || !shadow_start[i])
237+
if (origin || !aligned_shadow[i])
234238
origin_start[i] = origin;
235239
}
236240
}

mm/kmsan/kmsan_test.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,21 @@ DEFINE_TEST_MEMSETXX(16)
556556
DEFINE_TEST_MEMSETXX(32)
557557
DEFINE_TEST_MEMSETXX(64)
558558

559+
/* Test case: ensure that KMSAN does not access shadow memory out of bounds. */
560+
static void test_memset_on_guarded_buffer(struct kunit *test)
561+
{
562+
void *buf = vmalloc(PAGE_SIZE);
563+
564+
kunit_info(test,
565+
"memset() on ends of guarded buffer should not crash\n");
566+
567+
for (size_t size = 0; size <= 128; size++) {
568+
memset(buf, 0xff, size);
569+
memset(buf + PAGE_SIZE - size, 0xff, size);
570+
}
571+
vfree(buf);
572+
}
573+
559574
static noinline void fibonacci(int *array, int size, int start)
560575
{
561576
if (start < 2 || (start == size))
@@ -677,6 +692,7 @@ static struct kunit_case kmsan_test_cases[] = {
677692
KUNIT_CASE(test_memset16),
678693
KUNIT_CASE(test_memset32),
679694
KUNIT_CASE(test_memset64),
695+
KUNIT_CASE(test_memset_on_guarded_buffer),
680696
KUNIT_CASE(test_long_origin_chain),
681697
KUNIT_CASE(test_stackdepot_roundtrip),
682698
KUNIT_CASE(test_unpoison_memory),

0 commit comments

Comments
 (0)