xref: /linux/tools/testing/vma/shared.c (revision 6aacab308a5dfd222b2d23662bbae60c11007cfb)
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