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-hotfixes-stable-2022-10-28' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc hotfixes from Andrew Morton:
"Eight fix pre-6.0 bugs and the remainder address issues which were
introduced in the 6.1-rc merge cycle, or address issues which aren't
considered sufficiently serious to warrant a -stable backport"

* tag 'mm-hotfixes-stable-2022-10-28' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (23 commits)
mm: multi-gen LRU: move lru_gen_add_mm() out of IRQ-off region
lib: maple_tree: remove unneeded initialization in mtree_range_walk()
mmap: fix remap_file_pages() regression
mm/shmem: ensure proper fallback if page faults
mm/userfaultfd: replace kmap/kmap_atomic() with kmap_local_page()
x86: fortify: kmsan: fix KMSAN fortify builds
x86: asm: make sure __put_user_size() evaluates pointer once
Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default
x86/purgatory: disable KMSAN instrumentation
mm: kmsan: export kmsan_copy_page_meta()
mm: migrate: fix return value if all subpages of THPs are migrated successfully
mm/uffd: fix vma check on userfault for wp
mm: prep_compound_tail() clear page->private
mm,madvise,hugetlb: fix unexpected data loss with MADV_DONTNEED on hugetlbfs
mm/page_isolation: fix clang deadcode warning
fs/ext4/super.c: remove unused `deprecated_msg'
ipc/msg.c: fix percpu_counter use after free
memory tier, sysfs: rename attribute "nodes" to "nodelist"
MAINTAINERS: git://github.com -> https://github.com for nilfs2
mm/kmemleak: prevent soft lockup in kmemleak_scan()'s object iteration loops
...

+196 -68
+2 -2
Documentation/ABI/testing/sysfs-kernel-mm-memory-tiers
··· 10 10 11 11 12 12 What: /sys/devices/virtual/memory_tiering/memory_tierN/ 13 - /sys/devices/virtual/memory_tiering/memory_tierN/nodes 13 + /sys/devices/virtual/memory_tiering/memory_tierN/nodelist 14 14 Date: August 2022 15 15 Contact: Linux memory management mailing list <linux-mm@kvack.org> 16 16 Description: Directory with details of a specific memory tier ··· 21 21 A smaller value of N implies a higher (faster) memory tier in the 22 22 hierarchy. 23 23 24 - nodes: NUMA nodes that are part of this memory tier. 24 + nodelist: NUMA nodes that are part of this memory tier. 25 25
+1 -1
MAINTAINERS
··· 14523 14523 S: Supported 14524 14524 W: https://nilfs.sourceforge.io/ 14525 14525 W: https://nilfs.osdn.jp/ 14526 - T: git git://github.com/konis/nilfs2.git 14526 + T: git https://github.com/konis/nilfs2.git 14527 14527 F: Documentation/filesystems/nilfs2.rst 14528 14528 F: fs/nilfs2/ 14529 14529 F: include/trace/events/nilfs2.h
+7 -4
arch/x86/include/asm/string_64.h
··· 10 10 /* Even with __builtin_ the compiler may decide to use the out of line 11 11 function. */ 12 12 13 + #if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY) 14 + #include <linux/kmsan_string.h> 15 + #endif 16 + 13 17 #define __HAVE_ARCH_MEMCPY 1 14 - #if defined(__SANITIZE_MEMORY__) 18 + #if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY) 15 19 #undef memcpy 16 - void *__msan_memcpy(void *dst, const void *src, size_t size); 17 20 #define memcpy __msan_memcpy 18 21 #else 19 22 extern void *memcpy(void *to, const void *from, size_t len); ··· 24 21 extern void *__memcpy(void *to, const void *from, size_t len); 25 22 26 23 #define __HAVE_ARCH_MEMSET 27 - #if defined(__SANITIZE_MEMORY__) 24 + #if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY) 28 25 extern void *__msan_memset(void *s, int c, size_t n); 29 26 #undef memset 30 27 #define memset __msan_memset ··· 70 67 } 71 68 72 69 #define __HAVE_ARCH_MEMMOVE 73 - #if defined(__SANITIZE_MEMORY__) 70 + #if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY) 74 71 #undef memmove 75 72 void *__msan_memmove(void *dest, const void *src, size_t len); 76 73 #define memmove __msan_memmove
+7 -6
arch/x86/include/asm/uaccess.h
··· 254 254 #define __put_user_size(x, ptr, size, label) \ 255 255 do { \ 256 256 __typeof__(*(ptr)) __x = (x); /* eval x once */ \ 257 - __chk_user_ptr(ptr); \ 257 + __typeof__(ptr) __ptr = (ptr); /* eval ptr once */ \ 258 + __chk_user_ptr(__ptr); \ 258 259 switch (size) { \ 259 260 case 1: \ 260 - __put_user_goto(__x, ptr, "b", "iq", label); \ 261 + __put_user_goto(__x, __ptr, "b", "iq", label); \ 261 262 break; \ 262 263 case 2: \ 263 - __put_user_goto(__x, ptr, "w", "ir", label); \ 264 + __put_user_goto(__x, __ptr, "w", "ir", label); \ 264 265 break; \ 265 266 case 4: \ 266 - __put_user_goto(__x, ptr, "l", "ir", label); \ 267 + __put_user_goto(__x, __ptr, "l", "ir", label); \ 267 268 break; \ 268 269 case 8: \ 269 - __put_user_goto_u64(__x, ptr, label); \ 270 + __put_user_goto_u64(__x, __ptr, label); \ 270 271 break; \ 271 272 default: \ 272 273 __put_user_bad(); \ 273 274 } \ 274 - instrument_put_user(__x, ptr, size); \ 275 + instrument_put_user(__x, __ptr, size); \ 275 276 } while (0) 276 277 277 278 #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+1
arch/x86/purgatory/Makefile
··· 26 26 KASAN_SANITIZE := n 27 27 UBSAN_SANITIZE := n 28 28 KCSAN_SANITIZE := n 29 + KMSAN_SANITIZE := n 29 30 KCOV_INSTRUMENT := n 30 31 31 32 # These are adjustments to the compiler flags used for objects that
+1 -1
fs/exec.c
··· 1012 1012 active_mm = tsk->active_mm; 1013 1013 tsk->active_mm = mm; 1014 1014 tsk->mm = mm; 1015 - lru_gen_add_mm(mm); 1016 1015 /* 1017 1016 * This prevents preemption while active_mm is being loaded and 1018 1017 * it and mm are being updated, which could cause problems for ··· 1024 1025 activate_mm(active_mm, mm); 1025 1026 if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) 1026 1027 local_irq_enable(); 1028 + lru_gen_add_mm(mm); 1027 1029 task_unlock(tsk); 1028 1030 lru_gen_use_mm(mm); 1029 1031 if (old_mm) {
-4
fs/ext4/super.c
··· 1741 1741 1742 1742 #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) 1743 1743 1744 - static const char deprecated_msg[] = 1745 - "Mount option \"%s\" will be removed by %s\n" 1746 - "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; 1747 - 1748 1744 #define MOPT_SET 0x0001 1749 1745 #define MOPT_CLEAR 0x0002 1750 1746 #define MOPT_NOSUPPORT 0x0004
+14 -9
fs/squashfs/file.c
··· 506 506 squashfs_i(inode)->fragment_size); 507 507 struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; 508 508 unsigned int n, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; 509 + int error = buffer->error; 509 510 510 - if (buffer->error) 511 + if (error) 511 512 goto out; 512 513 513 514 expected += squashfs_i(inode)->fragment_offset; ··· 530 529 531 530 out: 532 531 squashfs_cache_put(buffer); 533 - return buffer->error; 532 + return error; 534 533 } 535 534 536 535 static void squashfs_readahead(struct readahead_control *ractl) ··· 558 557 int res, bsize; 559 558 u64 block = 0; 560 559 unsigned int expected; 560 + struct page *last_page; 561 + 562 + expected = start >> msblk->block_log == file_end ? 563 + (i_size_read(inode) & (msblk->block_size - 1)) : 564 + msblk->block_size; 565 + 566 + max_pages = (expected + PAGE_SIZE - 1) >> PAGE_SHIFT; 561 567 562 568 nr_pages = __readahead_batch(ractl, pages, max_pages); 563 569 if (!nr_pages) ··· 574 566 goto skip_pages; 575 567 576 568 index = pages[0]->index >> shift; 569 + 577 570 if ((pages[nr_pages - 1]->index >> shift) != index) 578 571 goto skip_pages; 579 - 580 - expected = index == file_end ? 581 - (i_size_read(inode) & (msblk->block_size - 1)) : 582 - msblk->block_size; 583 572 584 573 if (index == file_end && squashfs_i(inode)->fragment_block != 585 574 SQUASHFS_INVALID_BLK) { ··· 598 593 599 594 res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); 600 595 601 - squashfs_page_actor_free(actor); 596 + last_page = squashfs_page_actor_free(actor); 602 597 603 598 if (res == expected) { 604 599 int bytes; 605 600 606 601 /* Last page (if present) may have trailing bytes not filled */ 607 602 bytes = res % PAGE_SIZE; 608 - if (pages[nr_pages - 1]->index == file_end && bytes) 609 - memzero_page(pages[nr_pages - 1], bytes, 603 + if (index == file_end && bytes && last_page) 604 + memzero_page(last_page, bytes, 610 605 PAGE_SIZE - bytes); 611 606 612 607 for (i = 0; i < nr_pages; i++) {
+3
fs/squashfs/page_actor.c
··· 71 71 (actor->next_index != actor->page[actor->next_page]->index)) { 72 72 actor->next_index++; 73 73 actor->returned_pages++; 74 + actor->last_page = NULL; 74 75 return actor->alloc_buffer ? actor->tmp_buffer : ERR_PTR(-ENOMEM); 75 76 } 76 77 77 78 actor->next_index++; 78 79 actor->returned_pages++; 80 + actor->last_page = actor->page[actor->next_page]; 79 81 return actor->pageaddr = kmap_local_page(actor->page[actor->next_page++]); 80 82 } 81 83 ··· 127 125 actor->returned_pages = 0; 128 126 actor->next_index = page[0]->index & ~((1 << (msblk->block_log - PAGE_SHIFT)) - 1); 129 127 actor->pageaddr = NULL; 128 + actor->last_page = NULL; 130 129 actor->alloc_buffer = msblk->decompressor->alloc_buffer; 131 130 actor->squashfs_first_page = direct_first_page; 132 131 actor->squashfs_next_page = direct_next_page;
+5 -1
fs/squashfs/page_actor.h
··· 16 16 void *(*squashfs_first_page)(struct squashfs_page_actor *); 17 17 void *(*squashfs_next_page)(struct squashfs_page_actor *); 18 18 void (*squashfs_finish_page)(struct squashfs_page_actor *); 19 + struct page *last_page; 19 20 int pages; 20 21 int length; 21 22 int next_page; ··· 30 29 extern struct squashfs_page_actor *squashfs_page_actor_init_special( 31 30 struct squashfs_sb_info *msblk, 32 31 struct page **page, int pages, int length); 33 - static inline void squashfs_page_actor_free(struct squashfs_page_actor *actor) 32 + static inline struct page *squashfs_page_actor_free(struct squashfs_page_actor *actor) 34 33 { 34 + struct page *last_page = actor->last_page; 35 + 35 36 kfree(actor->tmp_buffer); 36 37 kfree(actor); 38 + return last_page; 37 39 } 38 40 static inline void *squashfs_first_page(struct squashfs_page_actor *actor) 39 41 {
+15 -2
include/linux/fortify-string.h
··· 43 43 extern char *__underlying_strncat(char *p, const char *q, __kernel_size_t count) __RENAME(strncat); 44 44 extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy); 45 45 #else 46 - #define __underlying_memchr __builtin_memchr 47 - #define __underlying_memcmp __builtin_memcmp 46 + 47 + #if defined(__SANITIZE_MEMORY__) 48 + /* 49 + * For KMSAN builds all memcpy/memset/memmove calls should be replaced by the 50 + * corresponding __msan_XXX functions. 51 + */ 52 + #include <linux/kmsan_string.h> 53 + #define __underlying_memcpy __msan_memcpy 54 + #define __underlying_memmove __msan_memmove 55 + #define __underlying_memset __msan_memset 56 + #else 48 57 #define __underlying_memcpy __builtin_memcpy 49 58 #define __underlying_memmove __builtin_memmove 50 59 #define __underlying_memset __builtin_memset 60 + #endif 61 + 62 + #define __underlying_memchr __builtin_memchr 63 + #define __underlying_memcmp __builtin_memcmp 51 64 #define __underlying_strcat __builtin_strcat 52 65 #define __underlying_strcpy __builtin_strcpy 53 66 #define __underlying_strlen __builtin_strlen
+21
include/linux/kmsan_string.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * KMSAN string functions API used in other headers. 4 + * 5 + * Copyright (C) 2022 Google LLC 6 + * Author: Alexander Potapenko <glider@google.com> 7 + * 8 + */ 9 + #ifndef _LINUX_KMSAN_STRING_H 10 + #define _LINUX_KMSAN_STRING_H 11 + 12 + /* 13 + * KMSAN overrides the default memcpy/memset/memmove implementations in the 14 + * kernel, which requires having __msan_XXX function prototypes in several other 15 + * headers. Keep them in one place instead of open-coding. 16 + */ 17 + void *__msan_memcpy(void *dst, const void *src, size_t size); 18 + void *__msan_memset(void *s, int c, size_t n); 19 + void *__msan_memmove(void *dest, const void *src, size_t len); 20 + 21 + #endif /* _LINUX_KMSAN_STRING_H */
+3 -3
include/linux/userfaultfd_k.h
··· 146 146 static inline bool vma_can_userfault(struct vm_area_struct *vma, 147 147 unsigned long vm_flags) 148 148 { 149 - if (vm_flags & VM_UFFD_MINOR) 150 - return is_vm_hugetlb_page(vma) || vma_is_shmem(vma); 151 - 149 + if ((vm_flags & VM_UFFD_MINOR) && 150 + (!is_vm_hugetlb_page(vma) && !vma_is_shmem(vma))) 151 + return false; 152 152 #ifndef CONFIG_PTE_MARKER_UFFD_WP 153 153 /* 154 154 * If user requested uffd-wp but not enabled pte markers for
+2 -2
ipc/msg.c
··· 1329 1329 #ifdef CONFIG_IPC_NS 1330 1330 void msg_exit_ns(struct ipc_namespace *ns) 1331 1331 { 1332 - percpu_counter_destroy(&ns->percpu_msg_bytes); 1333 - percpu_counter_destroy(&ns->percpu_msg_hdrs); 1334 1332 free_ipcs(ns, &msg_ids(ns), freeque); 1335 1333 idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr); 1336 1334 rhashtable_destroy(&ns->ids[IPC_MSG_IDS].key_ht); 1335 + percpu_counter_destroy(&ns->percpu_msg_bytes); 1336 + percpu_counter_destroy(&ns->percpu_msg_hdrs); 1337 1337 } 1338 1338 #endif 1339 1339
+2 -1
lib/Kconfig.debug
··· 400 400 default 1536 if (!64BIT && XTENSA) 401 401 default 1024 if !64BIT 402 402 default 2048 if 64BIT 403 + default 0 if KMSAN 403 404 help 404 - Tell gcc to warn at build time for stack frames larger than this. 405 + Tell the compiler to warn at build time for stack frames larger than this. 405 406 Setting this too low will cause a lot of warnings. 406 407 Setting it to 0 disables the warning. 407 408
+2 -2
lib/maple_tree.c
··· 2903 2903 unsigned long max, min; 2904 2904 unsigned long prev_max, prev_min; 2905 2905 2906 - last = next = mas->node; 2907 - prev_min = min = mas->min; 2906 + next = mas->node; 2907 + min = mas->min; 2908 2908 max = mas->max; 2909 2909 do { 2910 2910 offset = 0;
+1 -1
mm/huge_memory.c
··· 2462 2462 * Fix up and warn once if private is unexpectedly set. 2463 2463 */ 2464 2464 if (!folio_test_swapcache(page_folio(head))) { 2465 - VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, head); 2465 + VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, page_tail); 2466 2466 page_tail->private = 0; 2467 2467 } 2468 2468
+42 -19
mm/kmemleak.c
··· 1461 1461 } 1462 1462 1463 1463 /* 1464 + * Conditionally call resched() in a object iteration loop while making sure 1465 + * that the given object won't go away without RCU read lock by performing a 1466 + * get_object() if !pinned. 1467 + * 1468 + * Return: false if can't do a cond_resched() due to get_object() failure 1469 + * true otherwise 1470 + */ 1471 + static bool kmemleak_cond_resched(struct kmemleak_object *object, bool pinned) 1472 + { 1473 + if (!pinned && !get_object(object)) 1474 + return false; 1475 + 1476 + rcu_read_unlock(); 1477 + cond_resched(); 1478 + rcu_read_lock(); 1479 + if (!pinned) 1480 + put_object(object); 1481 + return true; 1482 + } 1483 + 1484 + /* 1464 1485 * Scan data sections and all the referenced memory blocks allocated via the 1465 1486 * kernel's standard allocators. This function must be called with the 1466 1487 * scan_mutex held. ··· 1492 1471 struct zone *zone; 1493 1472 int __maybe_unused i; 1494 1473 int new_leaks = 0; 1495 - int loop1_cnt = 0; 1474 + int loop_cnt = 0; 1496 1475 1497 1476 jiffies_last_scan = jiffies; 1498 1477 ··· 1501 1480 list_for_each_entry_rcu(object, &object_list, object_list) { 1502 1481 bool obj_pinned = false; 1503 1482 1504 - loop1_cnt++; 1505 1483 raw_spin_lock_irq(&object->lock); 1506 1484 #ifdef DEBUG 1507 1485 /* ··· 1534 1514 raw_spin_unlock_irq(&object->lock); 1535 1515 1536 1516 /* 1537 - * Do a cond_resched() to avoid soft lockup every 64k objects. 1538 - * Make sure a reference has been taken so that the object 1539 - * won't go away without RCU read lock. 1517 + * Do a cond_resched() every 64k objects to avoid soft lockup. 1540 1518 */ 1541 - if (!(loop1_cnt & 0xffff)) { 1542 - if (!obj_pinned && !get_object(object)) { 1543 - /* Try the next object instead */ 1544 - loop1_cnt--; 1545 - continue; 1546 - } 1547 - 1548 - rcu_read_unlock(); 1549 - cond_resched(); 1550 - rcu_read_lock(); 1551 - 1552 - if (!obj_pinned) 1553 - put_object(object); 1554 - } 1519 + if (!(++loop_cnt & 0xffff) && 1520 + !kmemleak_cond_resched(object, obj_pinned)) 1521 + loop_cnt--; /* Try again on next object */ 1555 1522 } 1556 1523 rcu_read_unlock(); 1557 1524 ··· 1605 1598 * scan and color them gray until the next scan. 1606 1599 */ 1607 1600 rcu_read_lock(); 1601 + loop_cnt = 0; 1608 1602 list_for_each_entry_rcu(object, &object_list, object_list) { 1603 + /* 1604 + * Do a cond_resched() every 64k objects to avoid soft lockup. 1605 + */ 1606 + if (!(++loop_cnt & 0xffff) && 1607 + !kmemleak_cond_resched(object, false)) 1608 + loop_cnt--; /* Try again on next object */ 1609 + 1609 1610 /* 1610 1611 * This is racy but we can save the overhead of lock/unlock 1611 1612 * calls. The missed objects, if any, should be caught in ··· 1647 1632 * Scanning result reporting. 1648 1633 */ 1649 1634 rcu_read_lock(); 1635 + loop_cnt = 0; 1650 1636 list_for_each_entry_rcu(object, &object_list, object_list) { 1637 + /* 1638 + * Do a cond_resched() every 64k objects to avoid soft lockup. 1639 + */ 1640 + if (!(++loop_cnt & 0xffff) && 1641 + !kmemleak_cond_resched(object, false)) 1642 + loop_cnt--; /* Try again on next object */ 1643 + 1651 1644 /* 1652 1645 * This is racy but we can save the overhead of lock/unlock 1653 1646 * calls. The missed objects, if any, should be caught in
+1
mm/kmsan/instrumentation.c
··· 14 14 15 15 #include "kmsan.h" 16 16 #include <linux/gfp.h> 17 + #include <linux/kmsan_string.h> 17 18 #include <linux/mm.h> 18 19 #include <linux/uaccess.h> 19 20
+1
mm/kmsan/shadow.c
··· 167 167 __memcpy(origin_ptr_for(dst), origin_ptr_for(src), PAGE_SIZE); 168 168 kmsan_leave_runtime(); 169 169 } 170 + EXPORT_SYMBOL(kmsan_copy_page_meta); 170 171 171 172 void kmsan_alloc_page(struct page *page, unsigned int order, gfp_t flags) 172 173 {
+11 -1
mm/madvise.c
··· 813 813 if (start & ~huge_page_mask(hstate_vma(vma))) 814 814 return false; 815 815 816 - *end = ALIGN(*end, huge_page_size(hstate_vma(vma))); 816 + /* 817 + * Madvise callers expect the length to be rounded up to PAGE_SIZE 818 + * boundaries, and may be unaware that this VMA uses huge pages. 819 + * Avoid unexpected data loss by rounding down the number of 820 + * huge pages freed. 821 + */ 822 + *end = ALIGN_DOWN(*end, huge_page_size(hstate_vma(vma))); 823 + 817 824 return true; 818 825 } 819 826 ··· 834 827 *prev = vma; 835 828 if (!madvise_dontneed_free_valid_vma(vma, start, &end, behavior)) 836 829 return -EINVAL; 830 + 831 + if (start == end) 832 + return 0; 837 833 838 834 if (!userfaultfd_remove(vma, start, end)) { 839 835 *prev = NULL; /* mmap_lock has been dropped, prev is stale */
+4 -4
mm/memory-tiers.c
··· 131 131 kfree(tier); 132 132 } 133 133 134 - static ssize_t nodes_show(struct device *dev, 135 - struct device_attribute *attr, char *buf) 134 + static ssize_t nodelist_show(struct device *dev, 135 + struct device_attribute *attr, char *buf) 136 136 { 137 137 int ret; 138 138 nodemask_t nmask; ··· 143 143 mutex_unlock(&memory_tier_lock); 144 144 return ret; 145 145 } 146 - static DEVICE_ATTR_RO(nodes); 146 + static DEVICE_ATTR_RO(nodelist); 147 147 148 148 static struct attribute *memtier_dev_attrs[] = { 149 - &dev_attr_nodes.attr, 149 + &dev_attr_nodelist.attr, 150 150 NULL 151 151 }; 152 152
+7
mm/migrate.c
··· 1582 1582 */ 1583 1583 list_splice(&ret_pages, from); 1584 1584 1585 + /* 1586 + * Return 0 in case all subpages of fail-to-migrate THPs are 1587 + * migrated successfully. 1588 + */ 1589 + if (list_empty(from)) 1590 + rc = 0; 1591 + 1585 1592 count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded); 1586 1593 count_vm_events(PGMIGRATE_FAIL, nr_failed_pages); 1587 1594 count_vm_events(THP_MIGRATION_SUCCESS, nr_thp_succeeded);
+3
mm/mmap.c
··· 2852 2852 if (next->vm_flags != vma->vm_flags) 2853 2853 goto out; 2854 2854 2855 + if (start + size <= next->vm_end) 2856 + break; 2857 + 2855 2858 prev = next; 2856 2859 } 2857 2860
+1
mm/page_alloc.c
··· 807 807 808 808 p->mapping = TAIL_MAPPING; 809 809 set_compound_head(p, head); 810 + set_page_private(p, 0); 810 811 } 811 812 812 813 void prep_compound_page(struct page *page, unsigned int order)
+1 -1
mm/page_isolation.c
··· 330 330 zone->zone_start_pfn); 331 331 332 332 if (skip_isolation) { 333 - int mt = get_pageblock_migratetype(pfn_to_page(isolate_pageblock)); 333 + int mt __maybe_unused = get_pageblock_migratetype(pfn_to_page(isolate_pageblock)); 334 334 335 335 VM_BUG_ON(!is_migrate_isolate(mt)); 336 336 } else {
+17
mm/shmem.c
··· 2424 2424 2425 2425 if (!zeropage) { /* COPY */ 2426 2426 page_kaddr = kmap_local_folio(folio, 0); 2427 + /* 2428 + * The read mmap_lock is held here. Despite the 2429 + * mmap_lock being read recursive a deadlock is still 2430 + * possible if a writer has taken a lock. For example: 2431 + * 2432 + * process A thread 1 takes read lock on own mmap_lock 2433 + * process A thread 2 calls mmap, blocks taking write lock 2434 + * process B thread 1 takes page fault, read lock on own mmap lock 2435 + * process B thread 2 calls mmap, blocks taking write lock 2436 + * process A thread 1 blocks taking read lock on process B 2437 + * process B thread 1 blocks taking read lock on process A 2438 + * 2439 + * Disable page faults to prevent potential deadlock 2440 + * and retry the copy outside the mmap_lock. 2441 + */ 2442 + pagefault_disable(); 2427 2443 ret = copy_from_user(page_kaddr, 2428 2444 (const void __user *)src_addr, 2429 2445 PAGE_SIZE); 2446 + pagefault_enable(); 2430 2447 kunmap_local(page_kaddr); 2431 2448 2432 2449 /* fallback to copy_from_user outside mmap_lock */
+21 -4
mm/userfaultfd.c
··· 157 157 if (!page) 158 158 goto out; 159 159 160 - page_kaddr = kmap_atomic(page); 160 + page_kaddr = kmap_local_page(page); 161 + /* 162 + * The read mmap_lock is held here. Despite the 163 + * mmap_lock being read recursive a deadlock is still 164 + * possible if a writer has taken a lock. For example: 165 + * 166 + * process A thread 1 takes read lock on own mmap_lock 167 + * process A thread 2 calls mmap, blocks taking write lock 168 + * process B thread 1 takes page fault, read lock on own mmap lock 169 + * process B thread 2 calls mmap, blocks taking write lock 170 + * process A thread 1 blocks taking read lock on process B 171 + * process B thread 1 blocks taking read lock on process A 172 + * 173 + * Disable page faults to prevent potential deadlock 174 + * and retry the copy outside the mmap_lock. 175 + */ 176 + pagefault_disable(); 161 177 ret = copy_from_user(page_kaddr, 162 178 (const void __user *) src_addr, 163 179 PAGE_SIZE); 164 - kunmap_atomic(page_kaddr); 180 + pagefault_enable(); 181 + kunmap_local(page_kaddr); 165 182 166 183 /* fallback to copy_from_user outside mmap_lock */ 167 184 if (unlikely(ret)) { ··· 663 646 mmap_read_unlock(dst_mm); 664 647 BUG_ON(!page); 665 648 666 - page_kaddr = kmap(page); 649 + page_kaddr = kmap_local_page(page); 667 650 err = copy_from_user(page_kaddr, 668 651 (const void __user *) src_addr, 669 652 PAGE_SIZE); 670 - kunmap(page); 653 + kunmap_local(page_kaddr); 671 654 if (unlikely(err)) { 672 655 err = -EFAULT; 673 656 goto out;