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
alloc_vma(struct mm_struct * mm,unsigned long start,unsigned long end,pgoff_t pgoff,vm_flags_t vm_flags)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
detach_free_vma(struct vm_area_struct * vma)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
alloc_and_link_vma(struct mm_struct * mm,unsigned long start,unsigned long end,pgoff_t pgoff,vm_flags_t vm_flags)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
reset_dummy_anon_vma(void)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
cleanup_mm(struct mm_struct * mm,struct vma_iterator * vmi)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
vma_write_started(struct vm_area_struct * vma)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
__vma_set_dummy_anon_vma(struct vm_area_struct * vma,struct anon_vma_chain * avc,struct anon_vma * anon_vma)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
vma_set_dummy_anon_vma(struct vm_area_struct * vma,struct anon_vma_chain * avc)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
get_current(void)114*6aacab30SLorenzo Stoakes struct task_struct *get_current(void)
115*6aacab30SLorenzo Stoakes {
116*6aacab30SLorenzo Stoakes return &__current;
117*6aacab30SLorenzo Stoakes }
118*6aacab30SLorenzo Stoakes
rlimit(unsigned int limit)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
vma_set_range(struct vm_area_struct * vma,unsigned long start,unsigned long end,pgoff_t pgoff)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