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