1*6aacab30SLorenzo Stoakes // SPDX-License-Identifier: GPL-2.0-or-later 2*6aacab30SLorenzo Stoakes 3*6aacab30SLorenzo Stoakes #include "shared.h" 4*6aacab30SLorenzo Stoakes 5*6aacab30SLorenzo Stoakes 6*6aacab30SLorenzo Stoakes bool fail_prealloc; 7*6aacab30SLorenzo Stoakes unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 8*6aacab30SLorenzo Stoakes unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 9*6aacab30SLorenzo Stoakes unsigned long stack_guard_gap = 256UL<<PAGE_SHIFT; 10*6aacab30SLorenzo Stoakes 11*6aacab30SLorenzo Stoakes const struct vm_operations_struct vma_dummy_vm_ops; 12*6aacab30SLorenzo Stoakes struct anon_vma dummy_anon_vma; 13*6aacab30SLorenzo Stoakes struct task_struct __current; 14*6aacab30SLorenzo Stoakes 15*6aacab30SLorenzo Stoakes struct vm_area_struct *alloc_vma(struct mm_struct *mm, 16*6aacab30SLorenzo Stoakes unsigned long start, unsigned long end, 17*6aacab30SLorenzo Stoakes pgoff_t pgoff, vm_flags_t vm_flags) 18*6aacab30SLorenzo Stoakes { 19*6aacab30SLorenzo Stoakes struct vm_area_struct *vma = vm_area_alloc(mm); 20*6aacab30SLorenzo Stoakes 21*6aacab30SLorenzo Stoakes if (vma == NULL) 22*6aacab30SLorenzo Stoakes return NULL; 23*6aacab30SLorenzo Stoakes 24*6aacab30SLorenzo Stoakes vma->vm_start = start; 25*6aacab30SLorenzo Stoakes vma->vm_end = end; 26*6aacab30SLorenzo Stoakes vma->vm_pgoff = pgoff; 27*6aacab30SLorenzo Stoakes vm_flags_reset(vma, vm_flags); 28*6aacab30SLorenzo Stoakes vma_assert_detached(vma); 29*6aacab30SLorenzo Stoakes 30*6aacab30SLorenzo Stoakes return vma; 31*6aacab30SLorenzo Stoakes } 32*6aacab30SLorenzo Stoakes 33*6aacab30SLorenzo Stoakes void detach_free_vma(struct vm_area_struct *vma) 34*6aacab30SLorenzo Stoakes { 35*6aacab30SLorenzo Stoakes vma_mark_detached(vma); 36*6aacab30SLorenzo Stoakes vm_area_free(vma); 37*6aacab30SLorenzo Stoakes } 38*6aacab30SLorenzo Stoakes 39*6aacab30SLorenzo Stoakes struct vm_area_struct *alloc_and_link_vma(struct mm_struct *mm, 40*6aacab30SLorenzo Stoakes unsigned long start, unsigned long end, 41*6aacab30SLorenzo Stoakes pgoff_t pgoff, vm_flags_t vm_flags) 42*6aacab30SLorenzo Stoakes { 43*6aacab30SLorenzo Stoakes struct vm_area_struct *vma = alloc_vma(mm, start, end, pgoff, vm_flags); 44*6aacab30SLorenzo Stoakes 45*6aacab30SLorenzo Stoakes if (vma == NULL) 46*6aacab30SLorenzo Stoakes return NULL; 47*6aacab30SLorenzo Stoakes 48*6aacab30SLorenzo Stoakes if (attach_vma(mm, vma)) { 49*6aacab30SLorenzo Stoakes detach_free_vma(vma); 50*6aacab30SLorenzo Stoakes return NULL; 51*6aacab30SLorenzo Stoakes } 52*6aacab30SLorenzo Stoakes 53*6aacab30SLorenzo Stoakes /* 54*6aacab30SLorenzo Stoakes * Reset this counter which we use to track whether writes have 55*6aacab30SLorenzo Stoakes * begun. Linking to the tree will have caused this to be incremented, 56*6aacab30SLorenzo Stoakes * which means we will get a false positive otherwise. 57*6aacab30SLorenzo Stoakes */ 58*6aacab30SLorenzo Stoakes vma->vm_lock_seq = UINT_MAX; 59*6aacab30SLorenzo Stoakes 60*6aacab30SLorenzo Stoakes return vma; 61*6aacab30SLorenzo Stoakes } 62*6aacab30SLorenzo Stoakes 63*6aacab30SLorenzo Stoakes void reset_dummy_anon_vma(void) 64*6aacab30SLorenzo Stoakes { 65*6aacab30SLorenzo Stoakes dummy_anon_vma.was_cloned = false; 66*6aacab30SLorenzo Stoakes dummy_anon_vma.was_unlinked = false; 67*6aacab30SLorenzo Stoakes } 68*6aacab30SLorenzo Stoakes 69*6aacab30SLorenzo Stoakes int cleanup_mm(struct mm_struct *mm, struct vma_iterator *vmi) 70*6aacab30SLorenzo Stoakes { 71*6aacab30SLorenzo Stoakes struct vm_area_struct *vma; 72*6aacab30SLorenzo Stoakes int count = 0; 73*6aacab30SLorenzo Stoakes 74*6aacab30SLorenzo Stoakes fail_prealloc = false; 75*6aacab30SLorenzo Stoakes reset_dummy_anon_vma(); 76*6aacab30SLorenzo Stoakes 77*6aacab30SLorenzo Stoakes vma_iter_set(vmi, 0); 78*6aacab30SLorenzo Stoakes for_each_vma(*vmi, vma) { 79*6aacab30SLorenzo Stoakes detach_free_vma(vma); 80*6aacab30SLorenzo Stoakes count++; 81*6aacab30SLorenzo Stoakes } 82*6aacab30SLorenzo Stoakes 83*6aacab30SLorenzo Stoakes mtree_destroy(&mm->mm_mt); 84*6aacab30SLorenzo Stoakes mm->map_count = 0; 85*6aacab30SLorenzo Stoakes return count; 86*6aacab30SLorenzo Stoakes } 87*6aacab30SLorenzo Stoakes 88*6aacab30SLorenzo Stoakes bool vma_write_started(struct vm_area_struct *vma) 89*6aacab30SLorenzo Stoakes { 90*6aacab30SLorenzo Stoakes int seq = vma->vm_lock_seq; 91*6aacab30SLorenzo Stoakes 92*6aacab30SLorenzo Stoakes /* We reset after each check. */ 93*6aacab30SLorenzo Stoakes vma->vm_lock_seq = UINT_MAX; 94*6aacab30SLorenzo Stoakes 95*6aacab30SLorenzo Stoakes /* The vma_start_write() stub simply increments this value. */ 96*6aacab30SLorenzo Stoakes return seq > -1; 97*6aacab30SLorenzo Stoakes } 98*6aacab30SLorenzo Stoakes 99*6aacab30SLorenzo Stoakes void __vma_set_dummy_anon_vma(struct vm_area_struct *vma, 100*6aacab30SLorenzo Stoakes struct anon_vma_chain *avc, struct anon_vma *anon_vma) 101*6aacab30SLorenzo Stoakes { 102*6aacab30SLorenzo Stoakes vma->anon_vma = anon_vma; 103*6aacab30SLorenzo Stoakes INIT_LIST_HEAD(&vma->anon_vma_chain); 104*6aacab30SLorenzo Stoakes list_add(&avc->same_vma, &vma->anon_vma_chain); 105*6aacab30SLorenzo Stoakes avc->anon_vma = vma->anon_vma; 106*6aacab30SLorenzo Stoakes } 107*6aacab30SLorenzo Stoakes 108*6aacab30SLorenzo Stoakes void vma_set_dummy_anon_vma(struct vm_area_struct *vma, 109*6aacab30SLorenzo Stoakes struct anon_vma_chain *avc) 110*6aacab30SLorenzo Stoakes { 111*6aacab30SLorenzo Stoakes __vma_set_dummy_anon_vma(vma, avc, &dummy_anon_vma); 112*6aacab30SLorenzo Stoakes } 113*6aacab30SLorenzo Stoakes 114*6aacab30SLorenzo Stoakes struct task_struct *get_current(void) 115*6aacab30SLorenzo Stoakes { 116*6aacab30SLorenzo Stoakes return &__current; 117*6aacab30SLorenzo Stoakes } 118*6aacab30SLorenzo Stoakes 119*6aacab30SLorenzo Stoakes unsigned long rlimit(unsigned int limit) 120*6aacab30SLorenzo Stoakes { 121*6aacab30SLorenzo Stoakes return (unsigned long)-1; 122*6aacab30SLorenzo Stoakes } 123*6aacab30SLorenzo Stoakes 124*6aacab30SLorenzo Stoakes void vma_set_range(struct vm_area_struct *vma, 125*6aacab30SLorenzo Stoakes unsigned long start, unsigned long end, 126*6aacab30SLorenzo Stoakes pgoff_t pgoff) 127*6aacab30SLorenzo Stoakes { 128*6aacab30SLorenzo Stoakes vma->vm_start = start; 129*6aacab30SLorenzo Stoakes vma->vm_end = end; 130*6aacab30SLorenzo Stoakes vma->vm_pgoff = pgoff; 131*6aacab30SLorenzo Stoakes } 132