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-2024-05-10-13-14' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull MM fixes from Andrew Morton:
"18 hotfixes, 7 of which are cc:stable.

More fixups for this cycle's page_owner updates. And a few userfaultfd
fixes. Otherwise, random singletons - see the individual changelogs
for details"

* tag 'mm-hotfixes-stable-2024-05-10-13-14' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
mailmap: add entry for Barry Song
selftests/mm: fix powerpc ARCH check
mailmap: add entry for John Garry
XArray: set the marks correctly when splitting an entry
selftests/vDSO: fix runtime errors on LoongArch
selftests/vDSO: fix building errors on LoongArch
mm,page_owner: don't remove __GFP_NOLOCKDEP in add_stack_record_to_list
fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry()
fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan
mm/vmalloc: fix return value of vb_alloc if size is 0
mm: use memalloc_nofs_save() in page_cache_ra_order()
kmsan: compiler_types: declare __no_sanitize_or_inline
lib/test_xarray.c: fix error assumptions on check_xa_multi_store_adv_add()
tools: fix userspace compilation with new test_xarray changes
MAINTAINERS: update URL's for KEYS/KEYRINGS_INTEGRITY and TPM DEVICE DRIVER
mm: page_owner: fix wrong information in dump_page_owner
maple_tree: fix mas_empty_area_rev() null pointer dereference
mm/userfaultfd: reset ptes when close() for wr-protected ones

+116 -64
+6
.mailmap
··· 97 97 Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@spreadtrum.com> 98 98 Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com> 99 99 Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com> 100 + Barry Song <baohua@kernel.org> <21cnbao@gmail.com> 101 + Barry Song <baohua@kernel.org> <v-songbaohua@oppo.com> 102 + Barry Song <baohua@kernel.org> <song.bao.hua@hisilicon.com> 103 + Barry Song <baohua@kernel.org> <Baohua.Song@csr.com> 104 + Barry Song <baohua@kernel.org> <barry.song@analog.com> 100 105 Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com> 101 106 Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com> 102 107 Bartosz Golaszewski <brgl@bgdev.pl> <bgolaszewski@baylibre.com> ··· 309 304 Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com> 310 305 John Crispin <john@phrozen.org> <blogic@openwrt.org> 311 306 John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com> 307 + John Garry <john.g.garry@oracle.com> <john.garry@huawei.com> 312 308 John Keeping <john@keeping.me.uk> <john@metanate.com> 313 309 John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com> 314 310 John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+2 -1
MAINTAINERS
··· 12041 12041 L: linux-integrity@vger.kernel.org 12042 12042 L: keyrings@vger.kernel.org 12043 12043 S: Supported 12044 + W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity 12044 12045 F: security/integrity/platform_certs 12045 12046 12046 12047 KFENCE ··· 22410 22409 R: Jason Gunthorpe <jgg@ziepe.ca> 22411 22410 L: linux-integrity@vger.kernel.org 22412 22411 S: Maintained 22413 - W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity 22412 + W: https://gitlab.com/jarkkojs/linux-tpmdd-test 22414 22413 Q: https://patchwork.kernel.org/project/linux-integrity/list/ 22415 22414 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git 22416 22415 F: Documentation/devicetree/bindings/tpm/
+14 -10
fs/proc/task_mmu.c
··· 1817 1817 } 1818 1818 1819 1819 static void make_uffd_wp_pte(struct vm_area_struct *vma, 1820 - unsigned long addr, pte_t *pte) 1820 + unsigned long addr, pte_t *pte, pte_t ptent) 1821 1821 { 1822 - pte_t ptent = ptep_get(pte); 1823 - 1824 1822 if (pte_present(ptent)) { 1825 1823 pte_t old_pte; 1826 1824 1827 1825 old_pte = ptep_modify_prot_start(vma, addr, pte); 1828 - ptent = pte_mkuffd_wp(ptent); 1826 + ptent = pte_mkuffd_wp(old_pte); 1829 1827 ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent); 1830 1828 } else if (is_swap_pte(ptent)) { 1831 1829 ptent = pte_swp_mkuffd_wp(ptent); ··· 2173 2175 if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) { 2174 2176 /* Fast path for performing exclusive WP */ 2175 2177 for (addr = start; addr != end; pte++, addr += PAGE_SIZE) { 2176 - if (pte_uffd_wp(ptep_get(pte))) 2178 + pte_t ptent = ptep_get(pte); 2179 + 2180 + if ((pte_present(ptent) && pte_uffd_wp(ptent)) || 2181 + pte_swp_uffd_wp_any(ptent)) 2177 2182 continue; 2178 - make_uffd_wp_pte(vma, addr, pte); 2183 + make_uffd_wp_pte(vma, addr, pte, ptent); 2179 2184 if (!flush_end) 2180 2185 start = addr; 2181 2186 flush_end = addr + PAGE_SIZE; ··· 2191 2190 p->arg.return_mask == PAGE_IS_WRITTEN) { 2192 2191 for (addr = start; addr < end; pte++, addr += PAGE_SIZE) { 2193 2192 unsigned long next = addr + PAGE_SIZE; 2193 + pte_t ptent = ptep_get(pte); 2194 2194 2195 - if (pte_uffd_wp(ptep_get(pte))) 2195 + if ((pte_present(ptent) && pte_uffd_wp(ptent)) || 2196 + pte_swp_uffd_wp_any(ptent)) 2196 2197 continue; 2197 2198 ret = pagemap_scan_output(p->cur_vma_category | PAGE_IS_WRITTEN, 2198 2199 p, addr, &next); ··· 2202 2199 break; 2203 2200 if (~p->arg.flags & PM_SCAN_WP_MATCHING) 2204 2201 continue; 2205 - make_uffd_wp_pte(vma, addr, pte); 2202 + make_uffd_wp_pte(vma, addr, pte, ptent); 2206 2203 if (!flush_end) 2207 2204 start = addr; 2208 2205 flush_end = next; ··· 2211 2208 } 2212 2209 2213 2210 for (addr = start; addr != end; pte++, addr += PAGE_SIZE) { 2211 + pte_t ptent = ptep_get(pte); 2214 2212 unsigned long categories = p->cur_vma_category | 2215 - pagemap_page_category(p, vma, addr, ptep_get(pte)); 2213 + pagemap_page_category(p, vma, addr, ptent); 2216 2214 unsigned long next = addr + PAGE_SIZE; 2217 2215 2218 2216 if (!pagemap_scan_is_interesting_page(categories, p)) ··· 2228 2224 if (~categories & PAGE_IS_WRITTEN) 2229 2225 continue; 2230 2226 2231 - make_uffd_wp_pte(vma, addr, pte); 2227 + make_uffd_wp_pte(vma, addr, pte, ptent); 2232 2228 if (!flush_end) 2233 2229 start = addr; 2234 2230 flush_end = next;
+4
fs/userfaultfd.c
··· 895 895 prev = vma; 896 896 continue; 897 897 } 898 + /* Reset ptes for the whole vma range if wr-protected */ 899 + if (userfaultfd_wp(vma)) 900 + uffd_wp_range(vma, vma->vm_start, 901 + vma->vm_end - vma->vm_start, false); 898 902 new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS; 899 903 vma = vma_modify_flags_uffd(&vmi, prev, vma, vma->vm_start, 900 904 vma->vm_end, new_flags,
+11
include/linux/compiler_types.h
··· 278 278 # define __no_kcsan 279 279 #endif 280 280 281 + #ifdef __SANITIZE_MEMORY__ 282 + /* 283 + * Similarly to KASAN and KCSAN, KMSAN loses function attributes of inlined 284 + * functions, therefore disabling KMSAN checks also requires disabling inlining. 285 + * 286 + * __no_sanitize_or_inline effectively prevents KMSAN from reporting errors 287 + * within the function and marks all its outputs as initialized. 288 + */ 289 + # define __no_sanitize_or_inline __no_kmsan_checks notrace __maybe_unused 290 + #endif 291 + 281 292 #ifndef __no_sanitize_or_inline 282 293 #define __no_sanitize_or_inline __always_inline 283 294 #endif
+8 -8
lib/maple_tree.c
··· 5109 5109 if (size == 0 || max - min < size - 1) 5110 5110 return -EINVAL; 5111 5111 5112 - if (mas_is_start(mas)) { 5112 + if (mas_is_start(mas)) 5113 5113 mas_start(mas); 5114 - mas->offset = mas_data_end(mas); 5115 - } else if (mas->offset >= 2) { 5116 - mas->offset -= 2; 5117 - } else if (!mas_rewind_node(mas)) { 5114 + else if ((mas->offset < 2) && (!mas_rewind_node(mas))) 5118 5115 return -EBUSY; 5119 - } 5120 5116 5121 - /* Empty set. */ 5122 - if (mas_is_none(mas) || mas_is_ptr(mas)) 5117 + if (unlikely(mas_is_none(mas) || mas_is_ptr(mas))) 5123 5118 return mas_sparse_area(mas, min, max, size, false); 5119 + else if (mas->offset >= 2) 5120 + mas->offset -= 2; 5121 + else 5122 + mas->offset = mas_data_end(mas); 5123 + 5124 5124 5125 5125 /* The start of the window can only be within these values. */ 5126 5126 mas->index = min;
+22 -5
lib/test_xarray.c
··· 744 744 745 745 do { 746 746 xas_lock_irq(&xas); 747 - 748 747 xas_store(&xas, p); 749 - XA_BUG_ON(xa, xas_error(&xas)); 750 - XA_BUG_ON(xa, xa_load(xa, index) != p); 751 - 752 748 xas_unlock_irq(&xas); 749 + /* 750 + * In our selftest case the only failure we can expect is for 751 + * there not to be enough memory as we're not mimicking the 752 + * entire page cache, so verify that's the only error we can run 753 + * into here. The xas_nomem() which follows will ensure to fix 754 + * that condition for us so to chug on on the loop. 755 + */ 756 + XA_BUG_ON(xa, xas_error(&xas) && xas_error(&xas) != -ENOMEM); 753 757 } while (xas_nomem(&xas, GFP_KERNEL)); 754 758 755 759 XA_BUG_ON(xa, xas_error(&xas)); 760 + XA_BUG_ON(xa, xa_load(xa, index) != p); 756 761 } 757 762 758 763 /* mimics page_cache_delete() */ ··· 1788 1783 unsigned int order, unsigned int new_order) 1789 1784 { 1790 1785 XA_STATE_ORDER(xas, xa, index, new_order); 1791 - unsigned int i; 1786 + unsigned int i, found; 1787 + void *entry; 1792 1788 1793 1789 xa_store_order(xa, index, order, xa, GFP_KERNEL); 1790 + xa_set_mark(xa, index, XA_MARK_1); 1794 1791 1795 1792 xas_split_alloc(&xas, xa, order, GFP_KERNEL); 1796 1793 xas_lock(&xas); ··· 1808 1801 1809 1802 xa_set_mark(xa, index, XA_MARK_0); 1810 1803 XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0)); 1804 + 1805 + xas_set_order(&xas, index, 0); 1806 + found = 0; 1807 + rcu_read_lock(); 1808 + xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_1) { 1809 + found++; 1810 + XA_BUG_ON(xa, xa_is_internal(entry)); 1811 + } 1812 + rcu_read_unlock(); 1813 + XA_BUG_ON(xa, found != 1 << (order - new_order)); 1811 1814 1812 1815 xa_destroy(xa); 1813 1816 }
+19 -4
lib/xarray.c
··· 969 969 return marks; 970 970 } 971 971 972 + static inline void node_mark_slots(struct xa_node *node, unsigned int sibs, 973 + xa_mark_t mark) 974 + { 975 + int i; 976 + 977 + if (sibs == 0) 978 + node_mark_all(node, mark); 979 + else { 980 + for (i = 0; i < XA_CHUNK_SIZE; i += sibs + 1) 981 + node_set_mark(node, i, mark); 982 + } 983 + } 984 + 972 985 static void node_set_marks(struct xa_node *node, unsigned int offset, 973 - struct xa_node *child, unsigned int marks) 986 + struct xa_node *child, unsigned int sibs, 987 + unsigned int marks) 974 988 { 975 989 xa_mark_t mark = XA_MARK_0; 976 990 ··· 992 978 if (marks & (1 << (__force unsigned int)mark)) { 993 979 node_set_mark(node, offset, mark); 994 980 if (child) 995 - node_mark_all(child, mark); 981 + node_mark_slots(child, sibs, mark); 996 982 } 997 983 if (mark == XA_MARK_MAX) 998 984 break; ··· 1091 1077 child->nr_values = xa_is_value(entry) ? 1092 1078 XA_CHUNK_SIZE : 0; 1093 1079 RCU_INIT_POINTER(child->parent, node); 1094 - node_set_marks(node, offset, child, marks); 1080 + node_set_marks(node, offset, child, xas->xa_sibs, 1081 + marks); 1095 1082 rcu_assign_pointer(node->slots[offset], 1096 1083 xa_mk_node(child)); 1097 1084 if (xa_is_value(curr)) ··· 1101 1086 } else { 1102 1087 unsigned int canon = offset - xas->xa_sibs; 1103 1088 1104 - node_set_marks(node, canon, NULL, marks); 1089 + node_set_marks(node, canon, NULL, 0, marks); 1105 1090 rcu_assign_pointer(node->slots[canon], entry); 1106 1091 while (offset > canon) 1107 1092 rcu_assign_pointer(node->slots[offset--],
+2 -2
mm/page_owner.c
··· 170 170 171 171 /* Filter gfp_mask the same way stackdepot does, for consistency */ 172 172 gfp_mask &= ~GFP_ZONEMASK; 173 - gfp_mask &= (GFP_ATOMIC | GFP_KERNEL); 173 + gfp_mask &= (GFP_ATOMIC | GFP_KERNEL | __GFP_NOLOCKDEP); 174 174 gfp_mask |= __GFP_NOWARN; 175 175 176 176 set_current_in_page_owner(); ··· 328 328 if (unlikely(!page_ext)) 329 329 return; 330 330 __update_page_owner_handle(page_ext, handle, order, gfp_mask, -1, 331 - current->pid, current->tgid, ts_nsec, 331 + ts_nsec, current->pid, current->tgid, 332 332 current->comm); 333 333 page_ext_put(page_ext); 334 334 inc_stack_record_count(handle, gfp_mask, 1 << order);
+4
mm/readahead.c
··· 490 490 pgoff_t index = readahead_index(ractl); 491 491 pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT; 492 492 pgoff_t mark = index + ra->size - ra->async_size; 493 + unsigned int nofs; 493 494 int err = 0; 494 495 gfp_t gfp = readahead_gfp_mask(mapping); 495 496 ··· 505 504 new_order = min_t(unsigned int, new_order, ilog2(ra->size)); 506 505 } 507 506 507 + /* See comment in page_cache_ra_unbounded() */ 508 + nofs = memalloc_nofs_save(); 508 509 filemap_invalidate_lock_shared(mapping); 509 510 while (index <= limit) { 510 511 unsigned int order = new_order; ··· 530 527 531 528 read_pages(ractl); 532 529 filemap_invalidate_unlock_shared(mapping); 530 + memalloc_nofs_restore(nofs); 533 531 534 532 /* 535 533 * If there were already pages in the page cache, then we may have
+1 -1
mm/vmalloc.c
··· 2710 2710 * get_order(0) returns funny result. Just warn and terminate 2711 2711 * early. 2712 2712 */ 2713 - return NULL; 2713 + return ERR_PTR(-EINVAL); 2714 2714 } 2715 2715 order = get_order(size); 2716 2716
+2
tools/testing/radix-tree/linux/kernel.h
··· 18 18 #define pr_info printk 19 19 #define pr_debug printk 20 20 #define pr_cont printk 21 + #define schedule() 22 + #define PAGE_SHIFT 12 21 23 22 24 #define __acquires(x) 23 25 #define __releases(x)
+3 -3
tools/testing/selftests/mm/Makefile
··· 12 12 else 13 13 uname_M := $(shell echo $(CROSS_COMPILE) | grep -o '^[a-z0-9]\+') 14 14 endif 15 - ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/ppc64/') 15 + ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/powerpc/') 16 16 endif 17 17 18 18 # Without this, failed build products remain, with up-to-date timestamps, ··· 98 98 endif 99 99 else 100 100 101 - ifneq (,$(findstring $(ARCH),ppc64)) 101 + ifneq (,$(findstring $(ARCH),powerpc)) 102 102 TEST_GEN_FILES += protection_keys 103 103 endif 104 104 105 105 endif 106 106 107 - ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sparc64 x86_64)) 107 + ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64)) 108 108 TEST_GEN_FILES += va_high_addr_switch 109 109 TEST_GEN_FILES += virtual_address_range 110 110 TEST_GEN_FILES += write_to_hugetlbfs
+5 -1
tools/testing/selftests/vDSO/vdso_config.h
··· 53 53 #if __riscv_xlen == 32 54 54 #define VDSO_32BIT 1 55 55 #endif 56 + #elif defined(__loongarch__) 57 + #define VDSO_VERSION 6 58 + #define VDSO_NAMES 1 56 59 #endif 57 60 58 - static const char *versions[6] = { 61 + static const char *versions[7] = { 59 62 "LINUX_2.6", 60 63 "LINUX_2.6.15", 61 64 "LINUX_2.6.29", 62 65 "LINUX_2.6.39", 63 66 "LINUX_4", 64 67 "LINUX_4.15", 68 + "LINUX_5.10" 65 69 }; 66 70 67 71 static const char *names[2][6] = {
+6 -10
tools/testing/selftests/vDSO/vdso_test_getcpu.c
··· 13 13 14 14 #include "../kselftest.h" 15 15 #include "parse_vdso.h" 16 - 17 - #if defined(__riscv) 18 - const char *version = "LINUX_4.15"; 19 - #else 20 - const char *version = "LINUX_2.6"; 21 - #endif 22 - const char *name = "__vdso_getcpu"; 16 + #include "vdso_config.h" 23 17 24 18 struct getcpu_cache; 25 19 typedef long (*getcpu_t)(unsigned int *, unsigned int *, ··· 21 27 22 28 int main(int argc, char **argv) 23 29 { 30 + const char *version = versions[VDSO_VERSION]; 31 + const char **name = (const char **)&names[VDSO_NAMES]; 24 32 unsigned long sysinfo_ehdr; 25 33 unsigned int cpu, node; 26 34 getcpu_t get_cpu; ··· 36 40 37 41 vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR)); 38 42 39 - get_cpu = (getcpu_t)vdso_sym(version, name); 43 + get_cpu = (getcpu_t)vdso_sym(version, name[4]); 40 44 if (!get_cpu) { 41 - printf("Could not find %s\n", name); 45 + printf("Could not find %s\n", name[4]); 42 46 return KSFT_SKIP; 43 47 } 44 48 ··· 46 50 if (ret == 0) { 47 51 printf("Running on CPU %u node %u\n", cpu, node); 48 52 } else { 49 - printf("%s failed\n", name); 53 + printf("%s failed\n", name[4]); 50 54 return KSFT_FAIL; 51 55 } 52 56
+7 -19
tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
··· 18 18 19 19 #include "../kselftest.h" 20 20 #include "parse_vdso.h" 21 - 22 - /* 23 - * ARM64's vDSO exports its gettimeofday() implementation with a different 24 - * name and version from other architectures, so we need to handle it as 25 - * a special case. 26 - */ 27 - #if defined(__aarch64__) 28 - const char *version = "LINUX_2.6.39"; 29 - const char *name = "__kernel_gettimeofday"; 30 - #elif defined(__riscv) 31 - const char *version = "LINUX_4.15"; 32 - const char *name = "__vdso_gettimeofday"; 33 - #else 34 - const char *version = "LINUX_2.6"; 35 - const char *name = "__vdso_gettimeofday"; 36 - #endif 21 + #include "vdso_config.h" 37 22 38 23 int main(int argc, char **argv) 39 24 { 25 + const char *version = versions[VDSO_VERSION]; 26 + const char **name = (const char **)&names[VDSO_NAMES]; 27 + 40 28 unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); 41 29 if (!sysinfo_ehdr) { 42 30 printf("AT_SYSINFO_EHDR is not present!\n"); ··· 35 47 36 48 /* Find gettimeofday. */ 37 49 typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); 38 - gtod_t gtod = (gtod_t)vdso_sym(version, name); 50 + gtod_t gtod = (gtod_t)vdso_sym(version, name[0]); 39 51 40 52 if (!gtod) { 41 - printf("Could not find %s\n", name); 53 + printf("Could not find %s\n", name[0]); 42 54 return KSFT_SKIP; 43 55 } 44 56 ··· 49 61 printf("The time is %lld.%06lld\n", 50 62 (long long)tv.tv_sec, (long long)tv.tv_usec); 51 63 } else { 52 - printf("%s failed\n", name); 64 + printf("%s failed\n", name[0]); 53 65 return KSFT_FAIL; 54 66 } 55 67