···9797static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma);9898static void hugetlb_unshare_pmds(struct vm_area_struct *vma,9999 unsigned long start, unsigned long end);100100+static struct resv_map *vma_resv_map(struct vm_area_struct *vma);100101101102static inline bool subpool_is_free(struct hugepage_subpool *spool)102103{···268267 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;269268270269 down_read(&vma_lock->rw_sema);270270+ } else if (__vma_private_lock(vma)) {271271+ struct resv_map *resv_map = vma_resv_map(vma);272272+273273+ down_read(&resv_map->rw_sema);271274 }272275}273276···281276 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;282277283278 up_read(&vma_lock->rw_sema);279279+ } else if (__vma_private_lock(vma)) {280280+ struct resv_map *resv_map = vma_resv_map(vma);281281+282282+ up_read(&resv_map->rw_sema);284283 }285284}286285···294285 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;295286296287 down_write(&vma_lock->rw_sema);288288+ } else if (__vma_private_lock(vma)) {289289+ struct resv_map *resv_map = vma_resv_map(vma);290290+291291+ down_write(&resv_map->rw_sema);297292 }298293}299294···307294 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;308295309296 up_write(&vma_lock->rw_sema);297297+ } else if (__vma_private_lock(vma)) {298298+ struct resv_map *resv_map = vma_resv_map(vma);299299+300300+ up_write(&resv_map->rw_sema);310301 }311302}312303313304int hugetlb_vma_trylock_write(struct vm_area_struct *vma)314305{315315- struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;316306317317- if (!__vma_shareable_lock(vma))318318- return 1;307307+ if (__vma_shareable_lock(vma)) {308308+ struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;319309320320- return down_write_trylock(&vma_lock->rw_sema);310310+ return down_write_trylock(&vma_lock->rw_sema);311311+ } else if (__vma_private_lock(vma)) {312312+ struct resv_map *resv_map = vma_resv_map(vma);313313+314314+ return down_write_trylock(&resv_map->rw_sema);315315+ }316316+317317+ return 1;321318}322319323320void hugetlb_vma_assert_locked(struct vm_area_struct *vma)···336313 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;337314338315 lockdep_assert_held(&vma_lock->rw_sema);316316+ } else if (__vma_private_lock(vma)) {317317+ struct resv_map *resv_map = vma_resv_map(vma);318318+319319+ lockdep_assert_held(&resv_map->rw_sema);339320 }340321}341322···372345 struct hugetlb_vma_lock *vma_lock = vma->vm_private_data;373346374347 __hugetlb_vma_unlock_write_put(vma_lock);348348+ } else if (__vma_private_lock(vma)) {349349+ struct resv_map *resv_map = vma_resv_map(vma);350350+351351+ /* no free for anon vmas, but still need to unlock */352352+ up_write(&resv_map->rw_sema);375353 }376354}377355···10931061 kref_init(&resv_map->refs);10941062 spin_lock_init(&resv_map->lock);10951063 INIT_LIST_HEAD(&resv_map->regions);10641064+ init_rwsem(&resv_map->rw_sema);1096106510971066 resv_map->adds_in_progress = 0;10981067 /*···11641131 VM_BUG_ON_VMA(!is_vm_hugetlb_page(vma), vma);11651132 VM_BUG_ON_VMA(vma->vm_flags & VM_MAYSHARE, vma);1166113311671167- set_vma_private_data(vma, (get_vma_private_data(vma) &11681168- HPAGE_RESV_MASK) | (unsigned long)map);11341134+ set_vma_private_data(vma, (unsigned long)map);11691135}1170113611711137static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags)···53475315 return len + old_addr - old_end;53485316}5349531753505350-static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,53515351- unsigned long start, unsigned long end,53525352- struct page *ref_page, zap_flags_t zap_flags)53185318+void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,53195319+ unsigned long start, unsigned long end,53205320+ struct page *ref_page, zap_flags_t zap_flags)53535321{53545322 struct mm_struct *mm = vma->vm_mm;53555323 unsigned long address;···54785446 tlb_flush_mmu_tlbonly(tlb);54795447}5480544854815481-void __unmap_hugepage_range_final(struct mmu_gather *tlb,54825482- struct vm_area_struct *vma, unsigned long start,54835483- unsigned long end, struct page *ref_page,54845484- zap_flags_t zap_flags)54495449+void __hugetlb_zap_begin(struct vm_area_struct *vma,54505450+ unsigned long *start, unsigned long *end)54855451{54865486- hugetlb_vma_lock_write(vma);54875487- i_mmap_lock_write(vma->vm_file->f_mapping);54525452+ if (!vma->vm_file) /* hugetlbfs_file_mmap error */54535453+ return;5488545454895489- /* mmu notification performed in caller */54905490- __unmap_hugepage_range(tlb, vma, start, end, ref_page, zap_flags);54555455+ adjust_range_if_pmd_sharing_possible(vma, start, end);54565456+ hugetlb_vma_lock_write(vma);54575457+ if (vma->vm_file)54585458+ i_mmap_lock_write(vma->vm_file->f_mapping);54595459+}54605460+54615461+void __hugetlb_zap_end(struct vm_area_struct *vma,54625462+ struct zap_details *details)54635463+{54645464+ zap_flags_t zap_flags = details ? details->zap_flags : 0;54655465+54665466+ if (!vma->vm_file) /* hugetlbfs_file_mmap error */54675467+ return;5491546854925469 if (zap_flags & ZAP_FLAG_UNMAP) { /* final unmap */54935470 /*···55095468 * someone else.55105469 */55115470 __hugetlb_vma_unlock_write_free(vma);55125512- i_mmap_unlock_write(vma->vm_file->f_mapping);55135471 } else {55145514- i_mmap_unlock_write(vma->vm_file->f_mapping);55155472 hugetlb_vma_unlock_write(vma);55165473 }54745474+54755475+ if (vma->vm_file)54765476+ i_mmap_unlock_write(vma->vm_file->f_mapping);55175477}5518547855195479void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,···68956853 */68966854 if (chg >= 0 && add < 0)68976855 region_abort(resv_map, from, to, regions_needed);68986898- if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER))68566856+ if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) {68996857 kref_put(&resv_map->refs, resv_map_release);68586858+ set_vma_resv_map(vma, NULL);68596859+ }69006860 return false;69016861}69026862
+1-1
mm/kasan/report.c
···621621}622622#endif /* CONFIG_KASAN_HW_TAGS */623623624624-#ifdef CONFIG_KASAN_INLINE624624+#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)625625/*626626 * With CONFIG_KASAN_INLINE, accesses to bogus pointers (outside the high627627 * canonical half of the address space) cause out-of-bounds shadow memory reads
···15431543 * the home node for vmas we already updated before.15441544 */15451545 old = vma_policy(vma);15461546- if (!old)15461546+ if (!old) {15471547+ prev = vma;15471548 continue;15491549+ }15481550 if (old->mode != MPOL_BIND && old->mode != MPOL_PREFERRED_MANY) {15491551 err = -EOPNOTSUPP;15501552 break;
+12-2
mm/migrate.c
···21552155 const int __user *nodes,21562156 int __user *status, int flags)21572157{21582158+ compat_uptr_t __user *compat_pages = (void __user *)pages;21582159 int current_node = NUMA_NO_NODE;21592160 LIST_HEAD(pagelist);21602161 int start, i;···21682167 int node;2169216821702169 err = -EFAULT;21712171- if (get_user(p, pages + i))21722172- goto out_flush;21702170+ if (in_compat_syscall()) {21712171+ compat_uptr_t cp;21722172+21732173+ if (get_user(cp, compat_pages + i))21742174+ goto out_flush;21752175+21762176+ p = compat_ptr(cp);21772177+ } else {21782178+ if (get_user(p, pages + i))21792179+ goto out_flush;21802180+ }21732181 if (get_user(node, nodes + i))21742182 goto out_flush;21752183
+33-13
mm/mmap.c
···583583 * dup_anon_vma() - Helper function to duplicate anon_vma584584 * @dst: The destination VMA585585 * @src: The source VMA586586+ * @dup: Pointer to the destination VMA when successful.586587 *587588 * Returns: 0 on success.588589 */589590static inline int dup_anon_vma(struct vm_area_struct *dst,590590- struct vm_area_struct *src)591591+ struct vm_area_struct *src, struct vm_area_struct **dup)591592{592593 /*593594 * Easily overlooked: when mprotect shifts the boundary, make sure the···596595 * anon pages imported.597596 */598597 if (src->anon_vma && !dst->anon_vma) {598598+ int ret;599599+599600 vma_assert_write_locked(dst);600601 dst->anon_vma = src->anon_vma;601601- return anon_vma_clone(dst, src);602602+ ret = anon_vma_clone(dst, src);603603+ if (ret)604604+ return ret;605605+606606+ *dup = dst;602607 }603608604609 return 0;···631624 unsigned long start, unsigned long end, pgoff_t pgoff,632625 struct vm_area_struct *next)633626{627627+ struct vm_area_struct *anon_dup = NULL;634628 bool remove_next = false;635629 struct vma_prepare vp;636630···641633642634 remove_next = true;643635 vma_start_write(next);644644- ret = dup_anon_vma(vma, next);636636+ ret = dup_anon_vma(vma, next, &anon_dup);645637 if (ret)646638 return ret;647639 }···669661 return 0;670662671663nomem:664664+ if (anon_dup)665665+ unlink_anon_vmas(anon_dup);672666 return -ENOMEM;673667}674668···870860{871861 struct vm_area_struct *curr, *next, *res;872862 struct vm_area_struct *vma, *adjust, *remove, *remove2;863863+ struct vm_area_struct *anon_dup = NULL;873864 struct vma_prepare vp;874865 pgoff_t vma_pgoff;875866 int err = 0;···938927 vma_start_write(next);939928 remove = next; /* case 1 */940929 vma_end = next->vm_end;941941- err = dup_anon_vma(prev, next);930930+ err = dup_anon_vma(prev, next, &anon_dup);942931 if (curr) { /* case 6 */943932 vma_start_write(curr);944933 remove = curr;945934 remove2 = next;946935 if (!next->anon_vma)947947- err = dup_anon_vma(prev, curr);936936+ err = dup_anon_vma(prev, curr, &anon_dup);948937 }949938 } else if (merge_prev) { /* case 2 */950939 if (curr) {951940 vma_start_write(curr);952952- err = dup_anon_vma(prev, curr);941941+ err = dup_anon_vma(prev, curr, &anon_dup);953942 if (end == curr->vm_end) { /* case 7 */954943 remove = curr;955944 } else { /* case 5 */···965954 vma_end = addr;966955 adjust = next;967956 adj_start = -(prev->vm_end - addr);968968- err = dup_anon_vma(next, prev);957957+ err = dup_anon_vma(next, prev, &anon_dup);969958 } else {970959 /*971960 * Note that cases 3 and 8 are the ONLY ones where prev···979968 vma_pgoff = curr->vm_pgoff;980969 vma_start_write(curr);981970 remove = curr;982982- err = dup_anon_vma(next, curr);971971+ err = dup_anon_vma(next, curr, &anon_dup);983972 }984973 }985974 }986975987976 /* Error in anon_vma clone. */988977 if (err)989989- return NULL;978978+ goto anon_vma_fail;990979991980 if (vma_start < vma->vm_start || vma_end > vma->vm_end)992981 vma_expanded = true;···999988 }10009891001990 if (vma_iter_prealloc(vmi, vma))10021002- return NULL;991991+ goto prealloc_fail;10039921004993 init_multi_vma_prep(&vp, vma, adjust, remove, remove2);1005994 VM_WARN_ON(vp.anon_vma && adjust && adjust->anon_vma &&···10271016 vma_complete(&vp, vmi, mm);10281017 khugepaged_enter_vma(res, vm_flags);10291018 return res;10191019+10201020+prealloc_fail:10211021+ if (anon_dup)10221022+ unlink_anon_vmas(anon_dup);10231023+10241024+anon_vma_fail:10251025+ vma_iter_set(vmi, addr);10261026+ vma_iter_load(vmi);10271027+ return NULL;10301028}1031102910321030/*···31613141 if (!len)31623142 return 0;3163314331643164- if (mmap_write_lock_killable(mm))31653165- return -EINTR;31663166-31673144 /* Until we need other flags, refuse anything except VM_EXEC. */31683145 if ((flags & (~VM_EXEC)) != 0)31693146 return -EINVAL;31473147+31483148+ if (mmap_write_lock_killable(mm))31493149+ return -EINTR;3170315031713151 ret = check_brk_limits(addr, len);31723152 if (ret)
···1383138313841384shrink:13851385 pool = zswap_pool_last_get();13861386- if (pool)13871387- queue_work(shrink_wq, &pool->shrink_work);13861386+ if (pool && !queue_work(shrink_wq, &pool->shrink_work))13871387+ zswap_pool_put(pool);13881388 goto reject;13891389}13901390
+40
tools/include/linux/rwsem.h
···11+/* SPDX-License-Identifier: GPL-2.0+ */22+#ifndef _TOOLS__RWSEM_H33+#define _TOOLS__RWSEM_H44+55+#include <pthread.h>66+77+struct rw_semaphore {88+ pthread_rwlock_t lock;99+};1010+1111+static inline int init_rwsem(struct rw_semaphore *sem)1212+{1313+ return pthread_rwlock_init(&sem->lock, NULL);1414+}1515+1616+static inline int exit_rwsem(struct rw_semaphore *sem)1717+{1818+ return pthread_rwlock_destroy(&sem->lock);1919+}2020+2121+static inline int down_read(struct rw_semaphore *sem)2222+{2323+ return pthread_rwlock_rdlock(&sem->lock);2424+}2525+2626+static inline int up_read(struct rw_semaphore *sem)2727+{2828+ return pthread_rwlock_unlock(&sem->lock);2929+}3030+3131+static inline int down_write(struct rw_semaphore *sem)3232+{3333+ return pthread_rwlock_wrlock(&sem->lock);3434+}3535+3636+static inline int up_write(struct rw_semaphore *sem)3737+{3838+ return pthread_rwlock_unlock(&sem->lock);3939+}4040+#endif /* _TOOLS_RWSEM_H */
+6-1
tools/testing/selftests/clone3/clone3.c
···196196 CLONE3_ARGS_NO_TEST);197197198198 /* Do a clone3() in a new time namespace */199199- test_clone3(CLONE_NEWTIME, 0, 0, CLONE3_ARGS_NO_TEST);199199+ if (access("/proc/self/ns/time", F_OK) == 0) {200200+ test_clone3(CLONE_NEWTIME, 0, 0, CLONE3_ARGS_NO_TEST);201201+ } else {202202+ ksft_print_msg("Time namespaces are not supported\n");203203+ ksft_test_result_skip("Skipping clone3() with CLONE_NEWTIME\n");204204+ }200205201206 /* Do a clone3() with exit signal (SIGCHLD) in flags */202207 test_clone3(SIGCHLD, 0, -EINVAL, CLONE3_ARGS_NO_TEST);