~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/vma/vma.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 
  3 #include <stdbool.h>
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 
  7 #include "maple-shared.h"
  8 #include "vma_internal.h"
  9 
 10 /* Include so header guard set. */
 11 #include "../../../mm/vma.h"
 12 
 13 static bool fail_prealloc;
 14 
 15 /* Then override vma_iter_prealloc() so we can choose to fail it. */
 16 #define vma_iter_prealloc(vmi, vma)                                     \
 17         (fail_prealloc ? -ENOMEM : mas_preallocate(&(vmi)->mas, (vma), GFP_KERNEL))
 18 
 19 /*
 20  * Directly import the VMA implementation here. Our vma_internal.h wrapper
 21  * provides userland-equivalent functionality for everything vma.c uses.
 22  */
 23 #include "../../../mm/vma.c"
 24 
 25 const struct vm_operations_struct vma_dummy_vm_ops;
 26 static struct anon_vma dummy_anon_vma;
 27 
 28 #define ASSERT_TRUE(_expr)                                              \
 29         do {                                                            \
 30                 if (!(_expr)) {                                         \
 31                         fprintf(stderr,                                 \
 32                                 "Assert FAILED at %s:%d:%s(): %s is FALSE.\n", \
 33                                 __FILE__, __LINE__, __FUNCTION__, #_expr); \
 34                         return false;                                   \
 35                 }                                                       \
 36         } while (0)
 37 #define ASSERT_FALSE(_expr) ASSERT_TRUE(!(_expr))
 38 #define ASSERT_EQ(_val1, _val2) ASSERT_TRUE((_val1) == (_val2))
 39 #define ASSERT_NE(_val1, _val2) ASSERT_TRUE((_val1) != (_val2))
 40 
 41 static struct task_struct __current;
 42 
 43 struct task_struct *get_current(void)
 44 {
 45         return &__current;
 46 }
 47 
 48 /* Helper function to simply allocate a VMA. */
 49 static struct vm_area_struct *alloc_vma(struct mm_struct *mm,
 50                                         unsigned long start,
 51                                         unsigned long end,
 52                                         pgoff_t pgoff,
 53                                         vm_flags_t flags)
 54 {
 55         struct vm_area_struct *ret = vm_area_alloc(mm);
 56 
 57         if (ret == NULL)
 58                 return NULL;
 59 
 60         ret->vm_start = start;
 61         ret->vm_end = end;
 62         ret->vm_pgoff = pgoff;
 63         ret->__vm_flags = flags;
 64 
 65         return ret;
 66 }
 67 
 68 /* Helper function to allocate a VMA and link it to the tree. */
 69 static struct vm_area_struct *alloc_and_link_vma(struct mm_struct *mm,
 70                                                  unsigned long start,
 71                                                  unsigned long end,
 72                                                  pgoff_t pgoff,
 73                                                  vm_flags_t flags)
 74 {
 75         struct vm_area_struct *vma = alloc_vma(mm, start, end, pgoff, flags);
 76 
 77         if (vma == NULL)
 78                 return NULL;
 79 
 80         if (vma_link(mm, vma)) {
 81                 vm_area_free(vma);
 82                 return NULL;
 83         }
 84 
 85         /*
 86          * Reset this counter which we use to track whether writes have
 87          * begun. Linking to the tree will have caused this to be incremented,
 88          * which means we will get a false positive otherwise.
 89          */
 90         vma->vm_lock_seq = -1;
 91 
 92         return vma;
 93 }
 94 
 95 /* Helper function which provides a wrapper around a merge new VMA operation. */
 96 static struct vm_area_struct *merge_new(struct vma_merge_struct *vmg)
 97 {
 98         /*
 99          * For convenience, get prev and next VMAs. Which the new VMA operation
100          * requires.
101          */
102         vmg->next = vma_next(vmg->vmi);
103         vmg->prev = vma_prev(vmg->vmi);
104         vma_iter_next_range(vmg->vmi);
105 
106         return vma_merge_new_range(vmg);
107 }
108 
109 /*
110  * Helper function which provides a wrapper around a merge existing VMA
111  * operation.
112  */
113 static struct vm_area_struct *merge_existing(struct vma_merge_struct *vmg)
114 {
115         return vma_merge_existing_range(vmg);
116 }
117 
118 /*
119  * Helper function which provides a wrapper around the expansion of an existing
120  * VMA.
121  */
122 static int expand_existing(struct vma_merge_struct *vmg)
123 {
124         return vma_expand(vmg);
125 }
126 
127 /*
128  * Helper function to reset merge state the associated VMA iterator to a
129  * specified new range.
130  */
131 static void vmg_set_range(struct vma_merge_struct *vmg, unsigned long start,
132                           unsigned long end, pgoff_t pgoff, vm_flags_t flags)
133 {
134         vma_iter_set(vmg->vmi, start);
135 
136         vmg->prev = NULL;
137         vmg->next = NULL;
138         vmg->vma = NULL;
139 
140         vmg->start = start;
141         vmg->end = end;
142         vmg->pgoff = pgoff;
143         vmg->flags = flags;
144 }
145 
146 /*
147  * Helper function to try to merge a new VMA.
148  *
149  * Update vmg and the iterator for it and try to merge, otherwise allocate a new
150  * VMA, link it to the maple tree and return it.
151  */
152 static struct vm_area_struct *try_merge_new_vma(struct mm_struct *mm,
153                                                 struct vma_merge_struct *vmg,
154                                                 unsigned long start, unsigned long end,
155                                                 pgoff_t pgoff, vm_flags_t flags,
156                                                 bool *was_merged)
157 {
158         struct vm_area_struct *merged;
159 
160         vmg_set_range(vmg, start, end, pgoff, flags);
161 
162         merged = merge_new(vmg);
163         if (merged) {
164                 *was_merged = true;
165                 ASSERT_EQ(vmg->state, VMA_MERGE_SUCCESS);
166                 return merged;
167         }
168 
169         *was_merged = false;
170 
171         ASSERT_EQ(vmg->state, VMA_MERGE_NOMERGE);
172 
173         return alloc_and_link_vma(mm, start, end, pgoff, flags);
174 }
175 
176 /*
177  * Helper function to reset the dummy anon_vma to indicate it has not been
178  * duplicated.
179  */
180 static void reset_dummy_anon_vma(void)
181 {
182         dummy_anon_vma.was_cloned = false;
183         dummy_anon_vma.was_unlinked = false;
184 }
185 
186 /*
187  * Helper function to remove all VMAs and destroy the maple tree associated with
188  * a virtual address space. Returns a count of VMAs in the tree.
189  */
190 static int cleanup_mm(struct mm_struct *mm, struct vma_iterator *vmi)
191 {
192         struct vm_area_struct *vma;
193         int count = 0;
194 
195         fail_prealloc = false;
196         reset_dummy_anon_vma();
197 
198         vma_iter_set(vmi, 0);
199         for_each_vma(*vmi, vma) {
200                 vm_area_free(vma);
201                 count++;
202         }
203 
204         mtree_destroy(&mm->mm_mt);
205         mm->map_count = 0;
206         return count;
207 }
208 
209 /* Helper function to determine if VMA has had vma_start_write() performed. */
210 static bool vma_write_started(struct vm_area_struct *vma)
211 {
212         int seq = vma->vm_lock_seq;
213 
214         /* We reset after each check. */
215         vma->vm_lock_seq = -1;
216 
217         /* The vma_start_write() stub simply increments this value. */
218         return seq > -1;
219 }
220 
221 /* Helper function providing a dummy vm_ops->close() method.*/
222 static void dummy_close(struct vm_area_struct *)
223 {
224 }
225 
226 static bool test_simple_merge(void)
227 {
228         struct vm_area_struct *vma;
229         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
230         struct mm_struct mm = {};
231         struct vm_area_struct *vma_left = alloc_vma(&mm, 0, 0x1000, 0, flags);
232         struct vm_area_struct *vma_right = alloc_vma(&mm, 0x2000, 0x3000, 2, flags);
233         VMA_ITERATOR(vmi, &mm, 0x1000);
234         struct vma_merge_struct vmg = {
235                 .mm = &mm,
236                 .vmi = &vmi,
237                 .start = 0x1000,
238                 .end = 0x2000,
239                 .flags = flags,
240                 .pgoff = 1,
241         };
242 
243         ASSERT_FALSE(vma_link(&mm, vma_left));
244         ASSERT_FALSE(vma_link(&mm, vma_right));
245 
246         vma = merge_new(&vmg);
247         ASSERT_NE(vma, NULL);
248 
249         ASSERT_EQ(vma->vm_start, 0);
250         ASSERT_EQ(vma->vm_end, 0x3000);
251         ASSERT_EQ(vma->vm_pgoff, 0);
252         ASSERT_EQ(vma->vm_flags, flags);
253 
254         vm_area_free(vma);
255         mtree_destroy(&mm.mm_mt);
256 
257         return true;
258 }
259 
260 static bool test_simple_modify(void)
261 {
262         struct vm_area_struct *vma;
263         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
264         struct mm_struct mm = {};
265         struct vm_area_struct *init_vma = alloc_vma(&mm, 0, 0x3000, 0, flags);
266         VMA_ITERATOR(vmi, &mm, 0x1000);
267 
268         ASSERT_FALSE(vma_link(&mm, init_vma));
269 
270         /*
271          * The flags will not be changed, the vma_modify_flags() function
272          * performs the merge/split only.
273          */
274         vma = vma_modify_flags(&vmi, init_vma, init_vma,
275                                0x1000, 0x2000, VM_READ | VM_MAYREAD);
276         ASSERT_NE(vma, NULL);
277         /* We modify the provided VMA, and on split allocate new VMAs. */
278         ASSERT_EQ(vma, init_vma);
279 
280         ASSERT_EQ(vma->vm_start, 0x1000);
281         ASSERT_EQ(vma->vm_end, 0x2000);
282         ASSERT_EQ(vma->vm_pgoff, 1);
283 
284         /*
285          * Now walk through the three split VMAs and make sure they are as
286          * expected.
287          */
288 
289         vma_iter_set(&vmi, 0);
290         vma = vma_iter_load(&vmi);
291 
292         ASSERT_EQ(vma->vm_start, 0);
293         ASSERT_EQ(vma->vm_end, 0x1000);
294         ASSERT_EQ(vma->vm_pgoff, 0);
295 
296         vm_area_free(vma);
297         vma_iter_clear(&vmi);
298 
299         vma = vma_next(&vmi);
300 
301         ASSERT_EQ(vma->vm_start, 0x1000);
302         ASSERT_EQ(vma->vm_end, 0x2000);
303         ASSERT_EQ(vma->vm_pgoff, 1);
304 
305         vm_area_free(vma);
306         vma_iter_clear(&vmi);
307 
308         vma = vma_next(&vmi);
309 
310         ASSERT_EQ(vma->vm_start, 0x2000);
311         ASSERT_EQ(vma->vm_end, 0x3000);
312         ASSERT_EQ(vma->vm_pgoff, 2);
313 
314         vm_area_free(vma);
315         mtree_destroy(&mm.mm_mt);
316 
317         return true;
318 }
319 
320 static bool test_simple_expand(void)
321 {
322         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
323         struct mm_struct mm = {};
324         struct vm_area_struct *vma = alloc_vma(&mm, 0, 0x1000, 0, flags);
325         VMA_ITERATOR(vmi, &mm, 0);
326         struct vma_merge_struct vmg = {
327                 .vmi = &vmi,
328                 .vma = vma,
329                 .start = 0,
330                 .end = 0x3000,
331                 .pgoff = 0,
332         };
333 
334         ASSERT_FALSE(vma_link(&mm, vma));
335 
336         ASSERT_FALSE(expand_existing(&vmg));
337 
338         ASSERT_EQ(vma->vm_start, 0);
339         ASSERT_EQ(vma->vm_end, 0x3000);
340         ASSERT_EQ(vma->vm_pgoff, 0);
341 
342         vm_area_free(vma);
343         mtree_destroy(&mm.mm_mt);
344 
345         return true;
346 }
347 
348 static bool test_simple_shrink(void)
349 {
350         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
351         struct mm_struct mm = {};
352         struct vm_area_struct *vma = alloc_vma(&mm, 0, 0x3000, 0, flags);
353         VMA_ITERATOR(vmi, &mm, 0);
354 
355         ASSERT_FALSE(vma_link(&mm, vma));
356 
357         ASSERT_FALSE(vma_shrink(&vmi, vma, 0, 0x1000, 0));
358 
359         ASSERT_EQ(vma->vm_start, 0);
360         ASSERT_EQ(vma->vm_end, 0x1000);
361         ASSERT_EQ(vma->vm_pgoff, 0);
362 
363         vm_area_free(vma);
364         mtree_destroy(&mm.mm_mt);
365 
366         return true;
367 }
368 
369 static bool test_merge_new(void)
370 {
371         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
372         struct mm_struct mm = {};
373         VMA_ITERATOR(vmi, &mm, 0);
374         struct vma_merge_struct vmg = {
375                 .mm = &mm,
376                 .vmi = &vmi,
377         };
378         struct anon_vma_chain dummy_anon_vma_chain_a = {
379                 .anon_vma = &dummy_anon_vma,
380         };
381         struct anon_vma_chain dummy_anon_vma_chain_b = {
382                 .anon_vma = &dummy_anon_vma,
383         };
384         struct anon_vma_chain dummy_anon_vma_chain_c = {
385                 .anon_vma = &dummy_anon_vma,
386         };
387         struct anon_vma_chain dummy_anon_vma_chain_d = {
388                 .anon_vma = &dummy_anon_vma,
389         };
390         const struct vm_operations_struct vm_ops = {
391                 .close = dummy_close,
392         };
393         int count;
394         struct vm_area_struct *vma, *vma_a, *vma_b, *vma_c, *vma_d;
395         bool merged;
396 
397         /*
398          * 0123456789abc
399          * AA B       CC
400          */
401         vma_a = alloc_and_link_vma(&mm, 0, 0x2000, 0, flags);
402         ASSERT_NE(vma_a, NULL);
403         /* We give each VMA a single avc so we can test anon_vma duplication. */
404         INIT_LIST_HEAD(&vma_a->anon_vma_chain);
405         list_add(&dummy_anon_vma_chain_a.same_vma, &vma_a->anon_vma_chain);
406 
407         vma_b = alloc_and_link_vma(&mm, 0x3000, 0x4000, 3, flags);
408         ASSERT_NE(vma_b, NULL);
409         INIT_LIST_HEAD(&vma_b->anon_vma_chain);
410         list_add(&dummy_anon_vma_chain_b.same_vma, &vma_b->anon_vma_chain);
411 
412         vma_c = alloc_and_link_vma(&mm, 0xb000, 0xc000, 0xb, flags);
413         ASSERT_NE(vma_c, NULL);
414         INIT_LIST_HEAD(&vma_c->anon_vma_chain);
415         list_add(&dummy_anon_vma_chain_c.same_vma, &vma_c->anon_vma_chain);
416 
417         /*
418          * NO merge.
419          *
420          * 0123456789abc
421          * AA B   **  CC
422          */
423         vma_d = try_merge_new_vma(&mm, &vmg, 0x7000, 0x9000, 7, flags, &merged);
424         ASSERT_NE(vma_d, NULL);
425         INIT_LIST_HEAD(&vma_d->anon_vma_chain);
426         list_add(&dummy_anon_vma_chain_d.same_vma, &vma_d->anon_vma_chain);
427         ASSERT_FALSE(merged);
428         ASSERT_EQ(mm.map_count, 4);
429 
430         /*
431          * Merge BOTH sides.
432          *
433          * 0123456789abc
434          * AA*B   DD  CC
435          */
436         vma_a->vm_ops = &vm_ops; /* This should have no impact. */
437         vma_b->anon_vma = &dummy_anon_vma;
438         vma = try_merge_new_vma(&mm, &vmg, 0x2000, 0x3000, 2, flags, &merged);
439         ASSERT_EQ(vma, vma_a);
440         /* Merge with A, delete B. */
441         ASSERT_TRUE(merged);
442         ASSERT_EQ(vma->vm_start, 0);
443         ASSERT_EQ(vma->vm_end, 0x4000);
444         ASSERT_EQ(vma->vm_pgoff, 0);
445         ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
446         ASSERT_TRUE(vma_write_started(vma));
447         ASSERT_EQ(mm.map_count, 3);
448 
449         /*
450          * Merge to PREVIOUS VMA.
451          *
452          * 0123456789abc
453          * AAAA*  DD  CC
454          */
455         vma = try_merge_new_vma(&mm, &vmg, 0x4000, 0x5000, 4, flags, &merged);
456         ASSERT_EQ(vma, vma_a);
457         /* Extend A. */
458         ASSERT_TRUE(merged);
459         ASSERT_EQ(vma->vm_start, 0);
460         ASSERT_EQ(vma->vm_end, 0x5000);
461         ASSERT_EQ(vma->vm_pgoff, 0);
462         ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
463         ASSERT_TRUE(vma_write_started(vma));
464         ASSERT_EQ(mm.map_count, 3);
465 
466         /*
467          * Merge to NEXT VMA.
468          *
469          * 0123456789abc
470          * AAAAA *DD  CC
471          */
472         vma_d->anon_vma = &dummy_anon_vma;
473         vma_d->vm_ops = &vm_ops; /* This should have no impact. */
474         vma = try_merge_new_vma(&mm, &vmg, 0x6000, 0x7000, 6, flags, &merged);
475         ASSERT_EQ(vma, vma_d);
476         /* Prepend. */
477         ASSERT_TRUE(merged);
478         ASSERT_EQ(vma->vm_start, 0x6000);
479         ASSERT_EQ(vma->vm_end, 0x9000);
480         ASSERT_EQ(vma->vm_pgoff, 6);
481         ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
482         ASSERT_TRUE(vma_write_started(vma));
483         ASSERT_EQ(mm.map_count, 3);
484 
485         /*
486          * Merge BOTH sides.
487          *
488          * 0123456789abc
489          * AAAAA*DDD  CC
490          */
491         vma_d->vm_ops = NULL; /* This would otherwise degrade the merge. */
492         vma = try_merge_new_vma(&mm, &vmg, 0x5000, 0x6000, 5, flags, &merged);
493         ASSERT_EQ(vma, vma_a);
494         /* Merge with A, delete D. */
495         ASSERT_TRUE(merged);
496         ASSERT_EQ(vma->vm_start, 0);
497         ASSERT_EQ(vma->vm_end, 0x9000);
498         ASSERT_EQ(vma->vm_pgoff, 0);
499         ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
500         ASSERT_TRUE(vma_write_started(vma));
501         ASSERT_EQ(mm.map_count, 2);
502 
503         /*
504          * Merge to NEXT VMA.
505          *
506          * 0123456789abc
507          * AAAAAAAAA *CC
508          */
509         vma_c->anon_vma = &dummy_anon_vma;
510         vma = try_merge_new_vma(&mm, &vmg, 0xa000, 0xb000, 0xa, flags, &merged);
511         ASSERT_EQ(vma, vma_c);
512         /* Prepend C. */
513         ASSERT_TRUE(merged);
514         ASSERT_EQ(vma->vm_start, 0xa000);
515         ASSERT_EQ(vma->vm_end, 0xc000);
516         ASSERT_EQ(vma->vm_pgoff, 0xa);
517         ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
518         ASSERT_TRUE(vma_write_started(vma));
519         ASSERT_EQ(mm.map_count, 2);
520 
521         /*
522          * Merge BOTH sides.
523          *
524          * 0123456789abc
525          * AAAAAAAAA*CCC
526          */
527         vma = try_merge_new_vma(&mm, &vmg, 0x9000, 0xa000, 0x9, flags, &merged);
528         ASSERT_EQ(vma, vma_a);
529         /* Extend A and delete C. */
530         ASSERT_TRUE(merged);
531         ASSERT_EQ(vma->vm_start, 0);
532         ASSERT_EQ(vma->vm_end, 0xc000);
533         ASSERT_EQ(vma->vm_pgoff, 0);
534         ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
535         ASSERT_TRUE(vma_write_started(vma));
536         ASSERT_EQ(mm.map_count, 1);
537 
538         /*
539          * Final state.
540          *
541          * 0123456789abc
542          * AAAAAAAAAAAAA
543          */
544 
545         count = 0;
546         vma_iter_set(&vmi, 0);
547         for_each_vma(vmi, vma) {
548                 ASSERT_NE(vma, NULL);
549                 ASSERT_EQ(vma->vm_start, 0);
550                 ASSERT_EQ(vma->vm_end, 0xc000);
551                 ASSERT_EQ(vma->vm_pgoff, 0);
552                 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
553 
554                 vm_area_free(vma);
555                 count++;
556         }
557 
558         /* Should only have one VMA left (though freed) after all is done.*/
559         ASSERT_EQ(count, 1);
560 
561         mtree_destroy(&mm.mm_mt);
562         return true;
563 }
564 
565 static bool test_vma_merge_special_flags(void)
566 {
567         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
568         struct mm_struct mm = {};
569         VMA_ITERATOR(vmi, &mm, 0);
570         struct vma_merge_struct vmg = {
571                 .mm = &mm,
572                 .vmi = &vmi,
573         };
574         vm_flags_t special_flags[] = { VM_IO, VM_DONTEXPAND, VM_PFNMAP, VM_MIXEDMAP };
575         vm_flags_t all_special_flags = 0;
576         int i;
577         struct vm_area_struct *vma_left, *vma;
578 
579         /* Make sure there aren't new VM_SPECIAL flags. */
580         for (i = 0; i < ARRAY_SIZE(special_flags); i++) {
581                 all_special_flags |= special_flags[i];
582         }
583         ASSERT_EQ(all_special_flags, VM_SPECIAL);
584 
585         /*
586          * 01234
587          * AAA
588          */
589         vma_left = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
590         ASSERT_NE(vma_left, NULL);
591 
592         /* 1. Set up new VMA with special flag that would otherwise merge. */
593 
594         /*
595          * 01234
596          * AAA*
597          *
598          * This should merge if not for the VM_SPECIAL flag.
599          */
600         vmg_set_range(&vmg, 0x3000, 0x4000, 3, flags);
601         for (i = 0; i < ARRAY_SIZE(special_flags); i++) {
602                 vm_flags_t special_flag = special_flags[i];
603 
604                 vma_left->__vm_flags = flags | special_flag;
605                 vmg.flags = flags | special_flag;
606                 vma = merge_new(&vmg);
607                 ASSERT_EQ(vma, NULL);
608                 ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
609         }
610 
611         /* 2. Modify VMA with special flag that would otherwise merge. */
612 
613         /*
614          * 01234
615          * AAAB
616          *
617          * Create a VMA to modify.
618          */
619         vma = alloc_and_link_vma(&mm, 0x3000, 0x4000, 3, flags);
620         ASSERT_NE(vma, NULL);
621         vmg.vma = vma;
622 
623         for (i = 0; i < ARRAY_SIZE(special_flags); i++) {
624                 vm_flags_t special_flag = special_flags[i];
625 
626                 vma_left->__vm_flags = flags | special_flag;
627                 vmg.flags = flags | special_flag;
628                 vma = merge_existing(&vmg);
629                 ASSERT_EQ(vma, NULL);
630                 ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
631         }
632 
633         cleanup_mm(&mm, &vmi);
634         return true;
635 }
636 
637 static bool test_vma_merge_with_close(void)
638 {
639         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
640         struct mm_struct mm = {};
641         VMA_ITERATOR(vmi, &mm, 0);
642         struct vma_merge_struct vmg = {
643                 .mm = &mm,
644                 .vmi = &vmi,
645         };
646         const struct vm_operations_struct vm_ops = {
647                 .close = dummy_close,
648         };
649         struct vm_area_struct *vma_prev, *vma_next, *vma;
650 
651         /*
652          * When merging VMAs we are not permitted to remove any VMA that has a
653          * vm_ops->close() hook.
654          *
655          * Considering the two possible adjacent VMAs to which a VMA can be
656          * merged:
657          *
658          * [ prev ][ vma ][ next ]
659          *
660          * In no case will we need to delete prev. If the operation is
661          * mergeable, then prev will be extended with one or both of vma and
662          * next deleted.
663          *
664          * As a result, during initial mergeability checks, only
665          * can_vma_merge_before() (which implies the VMA being merged with is
666          * 'next' as shown above) bothers to check to see whether the next VMA
667          * has a vm_ops->close() callback that will need to be called when
668          * removed.
669          *
670          * If it does, then we cannot merge as the resources that the close()
671          * operation potentially clears down are tied only to the existing VMA
672          * range and we have no way of extending those to the nearly merged one.
673          *
674          * We must consider two scenarios:
675          *
676          * A.
677          *
678          * vm_ops->close:     -       -    !NULL
679          *                 [ prev ][ vma ][ next ]
680          *
681          * Where prev may or may not be present/mergeable.
682          *
683          * This is picked up by a specific check in can_vma_merge_before().
684          *
685          * B.
686          *
687          * vm_ops->close:     -     !NULL
688          *                 [ prev ][ vma ]
689          *
690          * Where prev and vma are present and mergeable.
691          *
692          * This is picked up by a specific check in the modified VMA merge.
693          *
694          * IMPORTANT NOTE: We make the assumption that the following case:
695          *
696          *    -     !NULL   NULL
697          * [ prev ][ vma ][ next ]
698          *
699          * Cannot occur, because vma->vm_ops being the same implies the same
700          * vma->vm_file, and therefore this would mean that next->vm_ops->close
701          * would be set too, and thus scenario A would pick this up.
702          */
703 
704         /*
705          * The only case of a new VMA merge that results in a VMA being deleted
706          * is one where both the previous and next VMAs are merged - in this
707          * instance the next VMA is deleted, and the previous VMA is extended.
708          *
709          * If we are unable to do so, we reduce the operation to simply
710          * extending the prev VMA and not merging next.
711          *
712          * 0123456789
713          * PPP**NNNN
714          *             ->
715          * 0123456789
716          * PPPPPPNNN
717          */
718 
719         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
720         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x9000, 5, flags);
721         vma_next->vm_ops = &vm_ops;
722 
723         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
724         ASSERT_EQ(merge_new(&vmg), vma_prev);
725         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
726         ASSERT_EQ(vma_prev->vm_start, 0);
727         ASSERT_EQ(vma_prev->vm_end, 0x5000);
728         ASSERT_EQ(vma_prev->vm_pgoff, 0);
729 
730         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
731 
732         /*
733          * When modifying an existing VMA there are further cases where we
734          * delete VMAs.
735          *
736          *    <>
737          * 0123456789
738          * PPPVV
739          *
740          * In this instance, if vma has a close hook, the merge simply cannot
741          * proceed.
742          */
743 
744         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
745         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
746         vma->vm_ops = &vm_ops;
747 
748         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
749         vmg.prev = vma_prev;
750         vmg.vma = vma;
751 
752         /*
753          * The VMA being modified in a way that would otherwise merge should
754          * also fail.
755          */
756         ASSERT_EQ(merge_existing(&vmg), NULL);
757         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
758 
759         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
760 
761         /*
762          * This case is mirrored if merging with next.
763          *
764          *    <>
765          * 0123456789
766          *    VVNNNN
767          *
768          * In this instance, if vma has a close hook, the merge simply cannot
769          * proceed.
770          */
771 
772         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
773         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x9000, 5, flags);
774         vma->vm_ops = &vm_ops;
775 
776         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
777         vmg.vma = vma;
778         ASSERT_EQ(merge_existing(&vmg), NULL);
779         /*
780          * Initially this is misapprehended as an out of memory report, as the
781          * close() check is handled in the same way as anon_vma duplication
782          * failures, however a subsequent patch resolves this.
783          */
784         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
785 
786         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
787 
788         /*
789          * Finally, we consider two variants of the case where we modify a VMA
790          * to merge with both the previous and next VMAs.
791          *
792          * The first variant is where vma has a close hook. In this instance, no
793          * merge can proceed.
794          *
795          *    <>
796          * 0123456789
797          * PPPVVNNNN
798          */
799 
800         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
801         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
802         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x9000, 5, flags);
803         vma->vm_ops = &vm_ops;
804 
805         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
806         vmg.prev = vma_prev;
807         vmg.vma = vma;
808 
809         ASSERT_EQ(merge_existing(&vmg), NULL);
810         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
811 
812         ASSERT_EQ(cleanup_mm(&mm, &vmi), 3);
813 
814         /*
815          * The second variant is where next has a close hook. In this instance,
816          * we reduce the operation to a merge between prev and vma.
817          *
818          *    <>
819          * 0123456789
820          * PPPVVNNNN
821          *            ->
822          * 0123456789
823          * PPPPPNNNN
824          */
825 
826         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
827         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
828         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x9000, 5, flags);
829         vma_next->vm_ops = &vm_ops;
830 
831         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
832         vmg.prev = vma_prev;
833         vmg.vma = vma;
834 
835         ASSERT_EQ(merge_existing(&vmg), vma_prev);
836         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
837         ASSERT_EQ(vma_prev->vm_start, 0);
838         ASSERT_EQ(vma_prev->vm_end, 0x5000);
839         ASSERT_EQ(vma_prev->vm_pgoff, 0);
840 
841         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
842 
843         return true;
844 }
845 
846 static bool test_vma_merge_new_with_close(void)
847 {
848         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
849         struct mm_struct mm = {};
850         VMA_ITERATOR(vmi, &mm, 0);
851         struct vma_merge_struct vmg = {
852                 .mm = &mm,
853                 .vmi = &vmi,
854         };
855         struct vm_area_struct *vma_prev = alloc_and_link_vma(&mm, 0, 0x2000, 0, flags);
856         struct vm_area_struct *vma_next = alloc_and_link_vma(&mm, 0x5000, 0x7000, 5, flags);
857         const struct vm_operations_struct vm_ops = {
858                 .close = dummy_close,
859         };
860         struct vm_area_struct *vma;
861 
862         /*
863          * We should allow the partial merge of a proposed new VMA if the
864          * surrounding VMAs have vm_ops->close() hooks (but are otherwise
865          * compatible), e.g.:
866          *
867          *        New VMA
868          *    A  v-------v  B
869          * |-----|       |-----|
870          *  close         close
871          *
872          * Since the rule is to not DELETE a VMA with a close operation, this
873          * should be permitted, only rather than expanding A and deleting B, we
874          * should simply expand A and leave B intact, e.g.:
875          *
876          *        New VMA
877          *       A          B
878          * |------------||-----|
879          *  close         close
880          */
881 
882         /* Have prev and next have a vm_ops->close() hook. */
883         vma_prev->vm_ops = &vm_ops;
884         vma_next->vm_ops = &vm_ops;
885 
886         vmg_set_range(&vmg, 0x2000, 0x5000, 2, flags);
887         vma = merge_new(&vmg);
888         ASSERT_NE(vma, NULL);
889         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
890         ASSERT_EQ(vma->vm_start, 0);
891         ASSERT_EQ(vma->vm_end, 0x5000);
892         ASSERT_EQ(vma->vm_pgoff, 0);
893         ASSERT_EQ(vma->vm_ops, &vm_ops);
894         ASSERT_TRUE(vma_write_started(vma));
895         ASSERT_EQ(mm.map_count, 2);
896 
897         cleanup_mm(&mm, &vmi);
898         return true;
899 }
900 
901 static bool test_merge_existing(void)
902 {
903         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
904         struct mm_struct mm = {};
905         VMA_ITERATOR(vmi, &mm, 0);
906         struct vm_area_struct *vma, *vma_prev, *vma_next;
907         struct vma_merge_struct vmg = {
908                 .mm = &mm,
909                 .vmi = &vmi,
910         };
911         const struct vm_operations_struct vm_ops = {
912                 .close = dummy_close,
913         };
914 
915         /*
916          * Merge right case - partial span.
917          *
918          *    <->
919          * 0123456789
920          *   VVVVNNN
921          *            ->
922          * 0123456789
923          *   VNNNNNN
924          */
925         vma = alloc_and_link_vma(&mm, 0x2000, 0x6000, 2, flags);
926         vma->vm_ops = &vm_ops; /* This should have no impact. */
927         vma_next = alloc_and_link_vma(&mm, 0x6000, 0x9000, 6, flags);
928         vma_next->vm_ops = &vm_ops; /* This should have no impact. */
929         vmg_set_range(&vmg, 0x3000, 0x6000, 3, flags);
930         vmg.vma = vma;
931         vmg.prev = vma;
932         vma->anon_vma = &dummy_anon_vma;
933         ASSERT_EQ(merge_existing(&vmg), vma_next);
934         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
935         ASSERT_EQ(vma_next->vm_start, 0x3000);
936         ASSERT_EQ(vma_next->vm_end, 0x9000);
937         ASSERT_EQ(vma_next->vm_pgoff, 3);
938         ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);
939         ASSERT_EQ(vma->vm_start, 0x2000);
940         ASSERT_EQ(vma->vm_end, 0x3000);
941         ASSERT_EQ(vma->vm_pgoff, 2);
942         ASSERT_TRUE(vma_write_started(vma));
943         ASSERT_TRUE(vma_write_started(vma_next));
944         ASSERT_EQ(mm.map_count, 2);
945 
946         /* Clear down and reset. */
947         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
948 
949         /*
950          * Merge right case - full span.
951          *
952          *   <-->
953          * 0123456789
954          *   VVVVNNN
955          *            ->
956          * 0123456789
957          *   NNNNNNN
958          */
959         vma = alloc_and_link_vma(&mm, 0x2000, 0x6000, 2, flags);
960         vma_next = alloc_and_link_vma(&mm, 0x6000, 0x9000, 6, flags);
961         vma_next->vm_ops = &vm_ops; /* This should have no impact. */
962         vmg_set_range(&vmg, 0x2000, 0x6000, 2, flags);
963         vmg.vma = vma;
964         vma->anon_vma = &dummy_anon_vma;
965         ASSERT_EQ(merge_existing(&vmg), vma_next);
966         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
967         ASSERT_EQ(vma_next->vm_start, 0x2000);
968         ASSERT_EQ(vma_next->vm_end, 0x9000);
969         ASSERT_EQ(vma_next->vm_pgoff, 2);
970         ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);
971         ASSERT_TRUE(vma_write_started(vma_next));
972         ASSERT_EQ(mm.map_count, 1);
973 
974         /* Clear down and reset. We should have deleted vma. */
975         ASSERT_EQ(cleanup_mm(&mm, &vmi), 1);
976 
977         /*
978          * Merge left case - partial span.
979          *
980          *    <->
981          * 0123456789
982          * PPPVVVV
983          *            ->
984          * 0123456789
985          * PPPPPPV
986          */
987         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
988         vma_prev->vm_ops = &vm_ops; /* This should have no impact. */
989         vma = alloc_and_link_vma(&mm, 0x3000, 0x7000, 3, flags);
990         vma->vm_ops = &vm_ops; /* This should have no impact. */
991         vmg_set_range(&vmg, 0x3000, 0x6000, 3, flags);
992         vmg.prev = vma_prev;
993         vmg.vma = vma;
994         vma->anon_vma = &dummy_anon_vma;
995 
996         ASSERT_EQ(merge_existing(&vmg), vma_prev);
997         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
998         ASSERT_EQ(vma_prev->vm_start, 0);
999         ASSERT_EQ(vma_prev->vm_end, 0x6000);
1000         ASSERT_EQ(vma_prev->vm_pgoff, 0);
1001         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1002         ASSERT_EQ(vma->vm_start, 0x6000);
1003         ASSERT_EQ(vma->vm_end, 0x7000);
1004         ASSERT_EQ(vma->vm_pgoff, 6);
1005         ASSERT_TRUE(vma_write_started(vma_prev));
1006         ASSERT_TRUE(vma_write_started(vma));
1007         ASSERT_EQ(mm.map_count, 2);
1008 
1009         /* Clear down and reset. */
1010         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
1011 
1012         /*
1013          * Merge left case - full span.
1014          *
1015          *    <-->
1016          * 0123456789
1017          * PPPVVVV
1018          *            ->
1019          * 0123456789
1020          * PPPPPPP
1021          */
1022         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1023         vma_prev->vm_ops = &vm_ops; /* This should have no impact. */
1024         vma = alloc_and_link_vma(&mm, 0x3000, 0x7000, 3, flags);
1025         vmg_set_range(&vmg, 0x3000, 0x7000, 3, flags);
1026         vmg.prev = vma_prev;
1027         vmg.vma = vma;
1028         vma->anon_vma = &dummy_anon_vma;
1029         ASSERT_EQ(merge_existing(&vmg), vma_prev);
1030         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1031         ASSERT_EQ(vma_prev->vm_start, 0);
1032         ASSERT_EQ(vma_prev->vm_end, 0x7000);
1033         ASSERT_EQ(vma_prev->vm_pgoff, 0);
1034         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1035         ASSERT_TRUE(vma_write_started(vma_prev));
1036         ASSERT_EQ(mm.map_count, 1);
1037 
1038         /* Clear down and reset. We should have deleted vma. */
1039         ASSERT_EQ(cleanup_mm(&mm, &vmi), 1);
1040 
1041         /*
1042          * Merge both case.
1043          *
1044          *    <-->
1045          * 0123456789
1046          * PPPVVVVNNN
1047          *             ->
1048          * 0123456789
1049          * PPPPPPPPPP
1050          */
1051         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1052         vma_prev->vm_ops = &vm_ops; /* This should have no impact. */
1053         vma = alloc_and_link_vma(&mm, 0x3000, 0x7000, 3, flags);
1054         vma_next = alloc_and_link_vma(&mm, 0x7000, 0x9000, 7, flags);
1055         vmg_set_range(&vmg, 0x3000, 0x7000, 3, flags);
1056         vmg.prev = vma_prev;
1057         vmg.vma = vma;
1058         vma->anon_vma = &dummy_anon_vma;
1059         ASSERT_EQ(merge_existing(&vmg), vma_prev);
1060         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1061         ASSERT_EQ(vma_prev->vm_start, 0);
1062         ASSERT_EQ(vma_prev->vm_end, 0x9000);
1063         ASSERT_EQ(vma_prev->vm_pgoff, 0);
1064         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1065         ASSERT_TRUE(vma_write_started(vma_prev));
1066         ASSERT_EQ(mm.map_count, 1);
1067 
1068         /* Clear down and reset. We should have deleted prev and next. */
1069         ASSERT_EQ(cleanup_mm(&mm, &vmi), 1);
1070 
1071         /*
1072          * Non-merge ranges. the modified VMA merge operation assumes that the
1073          * caller always specifies ranges within the input VMA so we need only
1074          * examine these cases.
1075          *
1076          *     -
1077          *      -
1078          *       -
1079          *     <->
1080          *     <>
1081          *      <>
1082          * 0123456789a
1083          * PPPVVVVVNNN
1084          */
1085 
1086         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1087         vma = alloc_and_link_vma(&mm, 0x3000, 0x8000, 3, flags);
1088         vma_next = alloc_and_link_vma(&mm, 0x8000, 0xa000, 8, flags);
1089 
1090         vmg_set_range(&vmg, 0x4000, 0x5000, 4, flags);
1091         vmg.prev = vma;
1092         vmg.vma = vma;
1093         ASSERT_EQ(merge_existing(&vmg), NULL);
1094         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
1095 
1096         vmg_set_range(&vmg, 0x5000, 0x6000, 5, flags);
1097         vmg.prev = vma;
1098         vmg.vma = vma;
1099         ASSERT_EQ(merge_existing(&vmg), NULL);
1100         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
1101 
1102         vmg_set_range(&vmg, 0x6000, 0x7000, 6, flags);
1103         vmg.prev = vma;
1104         vmg.vma = vma;
1105         ASSERT_EQ(merge_existing(&vmg), NULL);
1106         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
1107 
1108         vmg_set_range(&vmg, 0x4000, 0x7000, 4, flags);
1109         vmg.prev = vma;
1110         vmg.vma = vma;
1111         ASSERT_EQ(merge_existing(&vmg), NULL);
1112         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
1113 
1114         vmg_set_range(&vmg, 0x4000, 0x6000, 4, flags);
1115         vmg.prev = vma;
1116         vmg.vma = vma;
1117         ASSERT_EQ(merge_existing(&vmg), NULL);
1118         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
1119 
1120         vmg_set_range(&vmg, 0x5000, 0x6000, 5, flags);
1121         vmg.prev = vma;
1122         vmg.vma = vma;
1123         ASSERT_EQ(merge_existing(&vmg), NULL);
1124         ASSERT_EQ(vmg.state, VMA_MERGE_NOMERGE);
1125 
1126         ASSERT_EQ(cleanup_mm(&mm, &vmi), 3);
1127 
1128         return true;
1129 }
1130 
1131 static bool test_anon_vma_non_mergeable(void)
1132 {
1133         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
1134         struct mm_struct mm = {};
1135         VMA_ITERATOR(vmi, &mm, 0);
1136         struct vm_area_struct *vma, *vma_prev, *vma_next;
1137         struct vma_merge_struct vmg = {
1138                 .mm = &mm,
1139                 .vmi = &vmi,
1140         };
1141         struct anon_vma_chain dummy_anon_vma_chain1 = {
1142                 .anon_vma = &dummy_anon_vma,
1143         };
1144         struct anon_vma_chain dummy_anon_vma_chain2 = {
1145                 .anon_vma = &dummy_anon_vma,
1146         };
1147 
1148         /*
1149          * In the case of modified VMA merge, merging both left and right VMAs
1150          * but where prev and next have incompatible anon_vma objects, we revert
1151          * to a merge of prev and VMA:
1152          *
1153          *    <-->
1154          * 0123456789
1155          * PPPVVVVNNN
1156          *            ->
1157          * 0123456789
1158          * PPPPPPPNNN
1159          */
1160         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1161         vma = alloc_and_link_vma(&mm, 0x3000, 0x7000, 3, flags);
1162         vma_next = alloc_and_link_vma(&mm, 0x7000, 0x9000, 7, flags);
1163 
1164         /*
1165          * Give both prev and next single anon_vma_chain fields, so they will
1166          * merge with the NULL vmg->anon_vma.
1167          *
1168          * However, when prev is compared to next, the merge should fail.
1169          */
1170 
1171         INIT_LIST_HEAD(&vma_prev->anon_vma_chain);
1172         list_add(&dummy_anon_vma_chain1.same_vma, &vma_prev->anon_vma_chain);
1173         ASSERT_TRUE(list_is_singular(&vma_prev->anon_vma_chain));
1174         vma_prev->anon_vma = &dummy_anon_vma;
1175         ASSERT_TRUE(is_mergeable_anon_vma(NULL, vma_prev->anon_vma, vma_prev));
1176 
1177         INIT_LIST_HEAD(&vma_next->anon_vma_chain);
1178         list_add(&dummy_anon_vma_chain2.same_vma, &vma_next->anon_vma_chain);
1179         ASSERT_TRUE(list_is_singular(&vma_next->anon_vma_chain));
1180         vma_next->anon_vma = (struct anon_vma *)2;
1181         ASSERT_TRUE(is_mergeable_anon_vma(NULL, vma_next->anon_vma, vma_next));
1182 
1183         ASSERT_FALSE(is_mergeable_anon_vma(vma_prev->anon_vma, vma_next->anon_vma, NULL));
1184 
1185         vmg_set_range(&vmg, 0x3000, 0x7000, 3, flags);
1186         vmg.prev = vma_prev;
1187         vmg.vma = vma;
1188 
1189         ASSERT_EQ(merge_existing(&vmg), vma_prev);
1190         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1191         ASSERT_EQ(vma_prev->vm_start, 0);
1192         ASSERT_EQ(vma_prev->vm_end, 0x7000);
1193         ASSERT_EQ(vma_prev->vm_pgoff, 0);
1194         ASSERT_TRUE(vma_write_started(vma_prev));
1195         ASSERT_FALSE(vma_write_started(vma_next));
1196 
1197         /* Clear down and reset. */
1198         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
1199 
1200         /*
1201          * Now consider the new VMA case. This is equivalent, only adding a new
1202          * VMA in a gap between prev and next.
1203          *
1204          *    <-->
1205          * 0123456789
1206          * PPP****NNN
1207          *            ->
1208          * 0123456789
1209          * PPPPPPPNNN
1210          */
1211         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1212         vma_next = alloc_and_link_vma(&mm, 0x7000, 0x9000, 7, flags);
1213 
1214         INIT_LIST_HEAD(&vma_prev->anon_vma_chain);
1215         list_add(&dummy_anon_vma_chain1.same_vma, &vma_prev->anon_vma_chain);
1216         vma_prev->anon_vma = (struct anon_vma *)1;
1217 
1218         INIT_LIST_HEAD(&vma_next->anon_vma_chain);
1219         list_add(&dummy_anon_vma_chain2.same_vma, &vma_next->anon_vma_chain);
1220         vma_next->anon_vma = (struct anon_vma *)2;
1221 
1222         vmg_set_range(&vmg, 0x3000, 0x7000, 3, flags);
1223         vmg.prev = vma_prev;
1224 
1225         ASSERT_EQ(merge_new(&vmg), vma_prev);
1226         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1227         ASSERT_EQ(vma_prev->vm_start, 0);
1228         ASSERT_EQ(vma_prev->vm_end, 0x7000);
1229         ASSERT_EQ(vma_prev->vm_pgoff, 0);
1230         ASSERT_TRUE(vma_write_started(vma_prev));
1231         ASSERT_FALSE(vma_write_started(vma_next));
1232 
1233         /* Final cleanup. */
1234         ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
1235 
1236         return true;
1237 }
1238 
1239 static bool test_dup_anon_vma(void)
1240 {
1241         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
1242         struct mm_struct mm = {};
1243         VMA_ITERATOR(vmi, &mm, 0);
1244         struct vma_merge_struct vmg = {
1245                 .mm = &mm,
1246                 .vmi = &vmi,
1247         };
1248         struct anon_vma_chain dummy_anon_vma_chain = {
1249                 .anon_vma = &dummy_anon_vma,
1250         };
1251         struct vm_area_struct *vma_prev, *vma_next, *vma;
1252 
1253         reset_dummy_anon_vma();
1254 
1255         /*
1256          * Expanding a VMA delete the next one duplicates next's anon_vma and
1257          * assigns it to the expanded VMA.
1258          *
1259          * This covers new VMA merging, as these operations amount to a VMA
1260          * expand.
1261          */
1262         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1263         vma_next = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1264         vma_next->anon_vma = &dummy_anon_vma;
1265 
1266         vmg_set_range(&vmg, 0, 0x5000, 0, flags);
1267         vmg.vma = vma_prev;
1268         vmg.next = vma_next;
1269 
1270         ASSERT_EQ(expand_existing(&vmg), 0);
1271 
1272         /* Will have been cloned. */
1273         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1274         ASSERT_TRUE(vma_prev->anon_vma->was_cloned);
1275 
1276         /* Cleanup ready for next run. */
1277         cleanup_mm(&mm, &vmi);
1278 
1279         /*
1280          * next has anon_vma, we assign to prev.
1281          *
1282          *         |<----->|
1283          * |-------*********-------|
1284          *   prev     vma     next
1285          *  extend   delete  delete
1286          */
1287 
1288         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1289         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1290         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x8000, 5, flags);
1291 
1292         /* Initialise avc so mergeability check passes. */
1293         INIT_LIST_HEAD(&vma_next->anon_vma_chain);
1294         list_add(&dummy_anon_vma_chain.same_vma, &vma_next->anon_vma_chain);
1295 
1296         vma_next->anon_vma = &dummy_anon_vma;
1297         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
1298         vmg.prev = vma_prev;
1299         vmg.vma = vma;
1300 
1301         ASSERT_EQ(merge_existing(&vmg), vma_prev);
1302         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1303 
1304         ASSERT_EQ(vma_prev->vm_start, 0);
1305         ASSERT_EQ(vma_prev->vm_end, 0x8000);
1306 
1307         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1308         ASSERT_TRUE(vma_prev->anon_vma->was_cloned);
1309 
1310         cleanup_mm(&mm, &vmi);
1311 
1312         /*
1313          * vma has anon_vma, we assign to prev.
1314          *
1315          *         |<----->|
1316          * |-------*********-------|
1317          *   prev     vma     next
1318          *  extend   delete  delete
1319          */
1320 
1321         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1322         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1323         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x8000, 5, flags);
1324 
1325         vma->anon_vma = &dummy_anon_vma;
1326         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
1327         vmg.prev = vma_prev;
1328         vmg.vma = vma;
1329 
1330         ASSERT_EQ(merge_existing(&vmg), vma_prev);
1331         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1332 
1333         ASSERT_EQ(vma_prev->vm_start, 0);
1334         ASSERT_EQ(vma_prev->vm_end, 0x8000);
1335 
1336         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1337         ASSERT_TRUE(vma_prev->anon_vma->was_cloned);
1338 
1339         cleanup_mm(&mm, &vmi);
1340 
1341         /*
1342          * vma has anon_vma, we assign to prev.
1343          *
1344          *         |<----->|
1345          * |-------*************
1346          *   prev       vma
1347          *  extend shrink/delete
1348          */
1349 
1350         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1351         vma = alloc_and_link_vma(&mm, 0x3000, 0x8000, 3, flags);
1352 
1353         vma->anon_vma = &dummy_anon_vma;
1354         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
1355         vmg.prev = vma_prev;
1356         vmg.vma = vma;
1357 
1358         ASSERT_EQ(merge_existing(&vmg), vma_prev);
1359         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1360 
1361         ASSERT_EQ(vma_prev->vm_start, 0);
1362         ASSERT_EQ(vma_prev->vm_end, 0x5000);
1363 
1364         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1365         ASSERT_TRUE(vma_prev->anon_vma->was_cloned);
1366 
1367         cleanup_mm(&mm, &vmi);
1368 
1369         /*
1370          * vma has anon_vma, we assign to next.
1371          *
1372          *     |<----->|
1373          * *************-------|
1374          *      vma       next
1375          * shrink/delete extend
1376          */
1377 
1378         vma = alloc_and_link_vma(&mm, 0, 0x5000, 0, flags);
1379         vma_next = alloc_and_link_vma(&mm, 0x5000, 0x8000, 5, flags);
1380 
1381         vma->anon_vma = &dummy_anon_vma;
1382         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
1383         vmg.prev = vma;
1384         vmg.vma = vma;
1385 
1386         ASSERT_EQ(merge_existing(&vmg), vma_next);
1387         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1388 
1389         ASSERT_EQ(vma_next->vm_start, 0x3000);
1390         ASSERT_EQ(vma_next->vm_end, 0x8000);
1391 
1392         ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);
1393         ASSERT_TRUE(vma_next->anon_vma->was_cloned);
1394 
1395         cleanup_mm(&mm, &vmi);
1396         return true;
1397 }
1398 
1399 static bool test_vmi_prealloc_fail(void)
1400 {
1401         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
1402         struct mm_struct mm = {};
1403         VMA_ITERATOR(vmi, &mm, 0);
1404         struct vma_merge_struct vmg = {
1405                 .mm = &mm,
1406                 .vmi = &vmi,
1407         };
1408         struct vm_area_struct *vma_prev, *vma;
1409 
1410         /*
1411          * We are merging vma into prev, with vma possessing an anon_vma, which
1412          * will be duplicated. We cause the vmi preallocation to fail and assert
1413          * the duplicated anon_vma is unlinked.
1414          */
1415 
1416         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1417         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1418         vma->anon_vma = &dummy_anon_vma;
1419 
1420         vmg_set_range(&vmg, 0x3000, 0x5000, 3, flags);
1421         vmg.prev = vma_prev;
1422         vmg.vma = vma;
1423 
1424         fail_prealloc = true;
1425 
1426         /* This will cause the merge to fail. */
1427         ASSERT_EQ(merge_existing(&vmg), NULL);
1428         ASSERT_EQ(vmg.state, VMA_MERGE_ERROR_NOMEM);
1429         /* We will already have assigned the anon_vma. */
1430         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1431         /* And it was both cloned and unlinked. */
1432         ASSERT_TRUE(dummy_anon_vma.was_cloned);
1433         ASSERT_TRUE(dummy_anon_vma.was_unlinked);
1434 
1435         cleanup_mm(&mm, &vmi); /* Resets fail_prealloc too. */
1436 
1437         /*
1438          * We repeat the same operation for expanding a VMA, which is what new
1439          * VMA merging ultimately uses too. This asserts that unlinking is
1440          * performed in this case too.
1441          */
1442 
1443         vma_prev = alloc_and_link_vma(&mm, 0, 0x3000, 0, flags);
1444         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1445         vma->anon_vma = &dummy_anon_vma;
1446 
1447         vmg_set_range(&vmg, 0, 0x5000, 3, flags);
1448         vmg.vma = vma_prev;
1449         vmg.next = vma;
1450 
1451         fail_prealloc = true;
1452         ASSERT_EQ(expand_existing(&vmg), -ENOMEM);
1453         ASSERT_EQ(vmg.state, VMA_MERGE_ERROR_NOMEM);
1454 
1455         ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
1456         ASSERT_TRUE(dummy_anon_vma.was_cloned);
1457         ASSERT_TRUE(dummy_anon_vma.was_unlinked);
1458 
1459         cleanup_mm(&mm, &vmi);
1460         return true;
1461 }
1462 
1463 static bool test_merge_extend(void)
1464 {
1465         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
1466         struct mm_struct mm = {};
1467         VMA_ITERATOR(vmi, &mm, 0x1000);
1468         struct vm_area_struct *vma;
1469 
1470         vma = alloc_and_link_vma(&mm, 0, 0x1000, 0, flags);
1471         alloc_and_link_vma(&mm, 0x3000, 0x4000, 3, flags);
1472 
1473         /*
1474          * Extend a VMA into the gap between itself and the following VMA.
1475          * This should result in a merge.
1476          *
1477          * <->
1478          * *  *
1479          *
1480          */
1481 
1482         ASSERT_EQ(vma_merge_extend(&vmi, vma, 0x2000), vma);
1483         ASSERT_EQ(vma->vm_start, 0);
1484         ASSERT_EQ(vma->vm_end, 0x4000);
1485         ASSERT_EQ(vma->vm_pgoff, 0);
1486         ASSERT_TRUE(vma_write_started(vma));
1487         ASSERT_EQ(mm.map_count, 1);
1488 
1489         cleanup_mm(&mm, &vmi);
1490         return true;
1491 }
1492 
1493 static bool test_copy_vma(void)
1494 {
1495         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
1496         struct mm_struct mm = {};
1497         bool need_locks = false;
1498         VMA_ITERATOR(vmi, &mm, 0);
1499         struct vm_area_struct *vma, *vma_new, *vma_next;
1500 
1501         /* Move backwards and do not merge. */
1502 
1503         vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1504         vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks);
1505 
1506         ASSERT_NE(vma_new, vma);
1507         ASSERT_EQ(vma_new->vm_start, 0);
1508         ASSERT_EQ(vma_new->vm_end, 0x2000);
1509         ASSERT_EQ(vma_new->vm_pgoff, 0);
1510 
1511         cleanup_mm(&mm, &vmi);
1512 
1513         /* Move a VMA into position next to another and merge the two. */
1514 
1515         vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, flags);
1516         vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, flags);
1517         vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks);
1518 
1519         ASSERT_EQ(vma_new, vma_next);
1520 
1521         cleanup_mm(&mm, &vmi);
1522         return true;
1523 }
1524 
1525 static bool test_expand_only_mode(void)
1526 {
1527         unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
1528         struct mm_struct mm = {};
1529         VMA_ITERATOR(vmi, &mm, 0);
1530         struct vm_area_struct *vma_prev, *vma;
1531         VMG_STATE(vmg, &mm, &vmi, 0x5000, 0x9000, flags, 5);
1532 
1533         /*
1534          * Place a VMA prior to the one we're expanding so we assert that we do
1535          * not erroneously try to traverse to the previous VMA even though we
1536          * have, through the use of VMG_FLAG_JUST_EXPAND, indicated we do not
1537          * need to do so.
1538          */
1539         alloc_and_link_vma(&mm, 0, 0x2000, 0, flags);
1540 
1541         /*
1542          * We will be positioned at the prev VMA, but looking to expand to
1543          * 0x9000.
1544          */
1545         vma_iter_set(&vmi, 0x3000);
1546         vma_prev = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
1547         vmg.prev = vma_prev;
1548         vmg.merge_flags = VMG_FLAG_JUST_EXPAND;
1549 
1550         vma = vma_merge_new_range(&vmg);
1551         ASSERT_NE(vma, NULL);
1552         ASSERT_EQ(vma, vma_prev);
1553         ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1554         ASSERT_EQ(vma->vm_start, 0x3000);
1555         ASSERT_EQ(vma->vm_end, 0x9000);
1556         ASSERT_EQ(vma->vm_pgoff, 3);
1557         ASSERT_TRUE(vma_write_started(vma));
1558         ASSERT_EQ(vma_iter_addr(&vmi), 0x3000);
1559 
1560         cleanup_mm(&mm, &vmi);
1561         return true;
1562 }
1563 
1564 int main(void)
1565 {
1566         int num_tests = 0, num_fail = 0;
1567 
1568         maple_tree_init();
1569 
1570 #define TEST(name)                                                      \
1571         do {                                                            \
1572                 num_tests++;                                            \
1573                 if (!test_##name()) {                                   \
1574                         num_fail++;                                     \
1575                         fprintf(stderr, "Test " #name " FAILED\n");     \
1576                 }                                                       \
1577         } while (0)
1578 
1579         /* Very simple tests to kick the tyres. */
1580         TEST(simple_merge);
1581         TEST(simple_modify);
1582         TEST(simple_expand);
1583         TEST(simple_shrink);
1584 
1585         TEST(merge_new);
1586         TEST(vma_merge_special_flags);
1587         TEST(vma_merge_with_close);
1588         TEST(vma_merge_new_with_close);
1589         TEST(merge_existing);
1590         TEST(anon_vma_non_mergeable);
1591         TEST(dup_anon_vma);
1592         TEST(vmi_prealloc_fail);
1593         TEST(merge_extend);
1594         TEST(copy_vma);
1595         TEST(expand_only_mode);
1596 
1597 #undef TEST
1598 
1599         printf("%d tests run, %d passed, %d failed.\n",
1600                num_tests, num_tests - num_fail, num_fail);
1601 
1602         return num_fail == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
1603 }
1604 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php