Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mm-stable-2025-06-06-16-09' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull more MM updates from Andrew Morton:
"The series 'Fix uprobe pte be overwritten when expanding vma' fixes a
longstanding and quite obscure bug related to the vma merging of the
uprobe mmap page"

* tag 'mm-stable-2025-06-06-16-09' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
selftests/mm: add test about uprobe pte be orphan during vma merge
selftests/mm: extract read_sysfs and write_sysfs into vm_util
mm: expose abnormal new_pte during move_ptes
mm: fix uprobe pte be overwritten when expanding vma
mm/damon: s/primitives/code/ on comments

+122 -44
+1 -1
mm/damon/modules-common.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Common Primitives for DAMON Modules 3 + * Common Code for DAMON Modules 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/modules-common.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 - * Common Primitives for DAMON Modules 3 + * Common Code for DAMON Modules 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/ops-common.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Common Primitives for Data Access Monitoring 3 + * Common Code for Data Access Monitoring 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/ops-common.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 - * Common Primitives for Data Access Monitoring 3 + * Common Code for Data Access Monitoring 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/paddr.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * DAMON Primitives for The Physical Address Space 3 + * DAMON Code for The Physical Address Space 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/sysfs-common.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Common Primitives for DAMON Sysfs Interface 3 + * Common Code for DAMON Sysfs Interface 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/sysfs-common.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 /* 3 - * Common Primitives for DAMON Sysfs Interface 3 + * Common Code for DAMON Sysfs Interface 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+1 -1
mm/damon/vaddr.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * DAMON Primitives for Virtual Address Spaces 3 + * DAMON Code for Virtual Address Spaces 4 4 * 5 5 * Author: SeongJae Park <sj@kernel.org> 6 6 */
+2
mm/mremap.c
··· 237 237 238 238 for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE, 239 239 new_pte++, new_addr += PAGE_SIZE) { 240 + VM_WARN_ON_ONCE(!pte_none(*new_pte)); 241 + 240 242 if (pte_none(ptep_get(old_pte))) 241 243 continue; 242 244
+17 -3
mm/vma.c
··· 169 169 vp->file = vma->vm_file; 170 170 if (vp->file) 171 171 vp->mapping = vma->vm_file->f_mapping; 172 + 173 + if (vmg && vmg->skip_vma_uprobe) 174 + vp->skip_vma_uprobe = true; 172 175 } 173 176 174 177 /* ··· 361 358 362 359 if (vp->file) { 363 360 i_mmap_unlock_write(vp->mapping); 364 - uprobe_mmap(vp->vma); 365 361 366 - if (vp->adj_next) 367 - uprobe_mmap(vp->adj_next); 362 + if (!vp->skip_vma_uprobe) { 363 + uprobe_mmap(vp->vma); 364 + 365 + if (vp->adj_next) 366 + uprobe_mmap(vp->adj_next); 367 + } 368 368 } 369 369 370 370 if (vp->remove) { ··· 1835 1829 pgoff = addr >> PAGE_SHIFT; 1836 1830 faulted_in_anon_vma = false; 1837 1831 } 1832 + 1833 + /* 1834 + * If the VMA we are copying might contain a uprobe PTE, ensure 1835 + * that we do not establish one upon merge. Otherwise, when mremap() 1836 + * moves page tables, it will orphan the newly created PTE. 1837 + */ 1838 + if (vma->vm_file) 1839 + vmg.skip_vma_uprobe = true; 1838 1840 1839 1841 new_vma = find_vma_prev(mm, addr, &vmg.prev); 1840 1842 if (new_vma && new_vma->vm_start < addr + len)
+7
mm/vma.h
··· 19 19 struct vm_area_struct *insert; 20 20 struct vm_area_struct *remove; 21 21 struct vm_area_struct *remove2; 22 + 23 + bool skip_vma_uprobe :1; 22 24 }; 23 25 24 26 struct unlink_vma_file_batch { ··· 121 119 * execute the merge, returning NULL. 122 120 */ 123 121 bool give_up_on_oom :1; 122 + 123 + /* 124 + * If set, skip uprobe_mmap upon merged vma. 125 + */ 126 + bool skip_vma_uprobe :1; 124 127 125 128 /* Internal flags set during merge process: */ 126 129
+2 -30
tools/testing/selftests/mm/ksm_tests.c
··· 58 58 59 59 static int ksm_write_sysfs(const char *file_path, unsigned long val) 60 60 { 61 - FILE *f = fopen(file_path, "w"); 62 - 63 - if (!f) { 64 - fprintf(stderr, "f %s\n", file_path); 65 - perror("fopen"); 66 - return 1; 67 - } 68 - if (fprintf(f, "%lu", val) < 0) { 69 - perror("fprintf"); 70 - fclose(f); 71 - return 1; 72 - } 73 - fclose(f); 74 - 75 - return 0; 61 + return write_sysfs(file_path, val); 76 62 } 77 63 78 64 static int ksm_read_sysfs(const char *file_path, unsigned long *val) 79 65 { 80 - FILE *f = fopen(file_path, "r"); 81 - 82 - if (!f) { 83 - fprintf(stderr, "f %s\n", file_path); 84 - perror("fopen"); 85 - return 1; 86 - } 87 - if (fscanf(f, "%lu", val) != 1) { 88 - perror("fscanf"); 89 - fclose(f); 90 - return 1; 91 - } 92 - fclose(f); 93 - 94 - return 0; 66 + return read_sysfs(file_path, val); 95 67 } 96 68 97 69 static void ksm_print_sysfs(void)
+43
tools/testing/selftests/mm/merge.c
··· 2 2 3 3 #define _GNU_SOURCE 4 4 #include "../kselftest_harness.h" 5 + #include <fcntl.h> 5 6 #include <stdio.h> 6 7 #include <stdlib.h> 7 8 #include <unistd.h> 8 9 #include <sys/mman.h> 10 + #include <sys/syscall.h> 9 11 #include <sys/wait.h> 12 + #include <linux/perf_event.h> 10 13 #include "vm_util.h" 11 14 12 15 FIXTURE(merge) ··· 453 450 ASSERT_TRUE(find_vma_procmap(procmap, ptr2)); 454 451 ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr2); 455 452 ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr2 + 5 * page_size); 453 + } 454 + 455 + TEST_F(merge, handle_uprobe_upon_merged_vma) 456 + { 457 + const size_t attr_sz = sizeof(struct perf_event_attr); 458 + unsigned int page_size = self->page_size; 459 + const char *probe_file = "./foo"; 460 + char *carveout = self->carveout; 461 + struct perf_event_attr attr; 462 + unsigned long type; 463 + void *ptr1, *ptr2; 464 + int fd; 465 + 466 + fd = open(probe_file, O_RDWR|O_CREAT, 0600); 467 + ASSERT_GE(fd, 0); 468 + 469 + ASSERT_EQ(ftruncate(fd, page_size), 0); 470 + ASSERT_EQ(read_sysfs("/sys/bus/event_source/devices/uprobe/type", &type), 0); 471 + 472 + memset(&attr, 0, attr_sz); 473 + attr.size = attr_sz; 474 + attr.type = type; 475 + attr.config1 = (__u64)(long)probe_file; 476 + attr.config2 = 0x0; 477 + 478 + ASSERT_GE(syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0), 0); 479 + 480 + ptr1 = mmap(&carveout[page_size], 10 * page_size, PROT_EXEC, 481 + MAP_PRIVATE | MAP_FIXED, fd, 0); 482 + ASSERT_NE(ptr1, MAP_FAILED); 483 + 484 + ptr2 = mremap(ptr1, page_size, 2 * page_size, 485 + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1 + 5 * page_size); 486 + ASSERT_NE(ptr2, MAP_FAILED); 487 + 488 + ASSERT_NE(mremap(ptr2, page_size, page_size, 489 + MREMAP_MAYMOVE | MREMAP_FIXED, ptr1), MAP_FAILED); 490 + 491 + close(fd); 492 + remove(probe_file); 456 493 } 457 494 458 495 TEST_HARNESS_MAIN
+3 -3
tools/testing/selftests/mm/thuge-gen.c
··· 77 77 system(buf); 78 78 } 79 79 80 - unsigned long read_sysfs(int warn, char *fmt, ...) 80 + unsigned long thuge_read_sysfs(int warn, char *fmt, ...) 81 81 { 82 82 char *line = NULL; 83 83 size_t linelen = 0; ··· 106 106 107 107 unsigned long read_free(unsigned long ps) 108 108 { 109 - return read_sysfs(ps != getpagesize(), 109 + return thuge_read_sysfs(ps != getpagesize(), 110 110 "/sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages", 111 111 ps >> 10); 112 112 } ··· 195 195 } 196 196 globfree(&g); 197 197 198 - if (read_sysfs(0, "/proc/sys/kernel/shmmax") < NUM_PAGES * largest) 198 + if (thuge_read_sysfs(0, "/proc/sys/kernel/shmmax") < NUM_PAGES * largest) 199 199 ksft_exit_fail_msg("Please do echo %lu > /proc/sys/kernel/shmmax", 200 200 largest * NUM_PAGES); 201 201
+38
tools/testing/selftests/mm/vm_util.c
··· 486 486 { 487 487 return close(procmap->fd); 488 488 } 489 + 490 + int write_sysfs(const char *file_path, unsigned long val) 491 + { 492 + FILE *f = fopen(file_path, "w"); 493 + 494 + if (!f) { 495 + fprintf(stderr, "f %s\n", file_path); 496 + perror("fopen"); 497 + return 1; 498 + } 499 + if (fprintf(f, "%lu", val) < 0) { 500 + perror("fprintf"); 501 + fclose(f); 502 + return 1; 503 + } 504 + fclose(f); 505 + 506 + return 0; 507 + } 508 + 509 + int read_sysfs(const char *file_path, unsigned long *val) 510 + { 511 + FILE *f = fopen(file_path, "r"); 512 + 513 + if (!f) { 514 + fprintf(stderr, "f %s\n", file_path); 515 + perror("fopen"); 516 + return 1; 517 + } 518 + if (fscanf(f, "%lu", val) != 1) { 519 + perror("fscanf"); 520 + fclose(f); 521 + return 1; 522 + } 523 + fclose(f); 524 + 525 + return 0; 526 + }
+2
tools/testing/selftests/mm/vm_util.h
··· 88 88 int query_procmap(struct procmap_fd *procmap); 89 89 bool find_vma_procmap(struct procmap_fd *procmap, void *address); 90 90 int close_procmap(struct procmap_fd *procmap); 91 + int write_sysfs(const char *file_path, unsigned long val); 92 + int read_sysfs(const char *file_path, unsigned long *val); 91 93 92 94 static inline int open_self_procmap(struct procmap_fd *procmap_out) 93 95 {