ACPI: APEI: Fix integer overflow in ghes_estatus_pool_init()
[sfrench/cifs-2.6.git] / tools / testing / memblock / tests / basic_api.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #include <string.h>
3 #include <linux/memblock.h>
4 #include "basic_api.h"
5
6 #define EXPECTED_MEMBLOCK_REGIONS                       128
7 #define FUNC_ADD                                        "memblock_add"
8 #define FUNC_RESERVE                                    "memblock_reserve"
9 #define FUNC_REMOVE                                     "memblock_remove"
10 #define FUNC_FREE                                       "memblock_free"
11
12 static int memblock_initialization_check(void)
13 {
14         PREFIX_PUSH();
15
16         ASSERT_NE(memblock.memory.regions, NULL);
17         ASSERT_EQ(memblock.memory.cnt, 1);
18         ASSERT_EQ(memblock.memory.max, EXPECTED_MEMBLOCK_REGIONS);
19         ASSERT_EQ(strcmp(memblock.memory.name, "memory"), 0);
20
21         ASSERT_NE(memblock.reserved.regions, NULL);
22         ASSERT_EQ(memblock.reserved.cnt, 1);
23         ASSERT_EQ(memblock.memory.max, EXPECTED_MEMBLOCK_REGIONS);
24         ASSERT_EQ(strcmp(memblock.reserved.name, "reserved"), 0);
25
26         ASSERT_EQ(memblock.bottom_up, false);
27         ASSERT_EQ(memblock.current_limit, MEMBLOCK_ALLOC_ANYWHERE);
28
29         test_pass_pop();
30
31         return 0;
32 }
33
34 /*
35  * A simple test that adds a memory block of a specified base address
36  * and size to the collection of available memory regions (memblock.memory).
37  * Expect to create a new entry. The region counter and total memory get
38  * updated.
39  */
40 static int memblock_add_simple_check(void)
41 {
42         struct memblock_region *rgn;
43
44         rgn = &memblock.memory.regions[0];
45
46         struct region r = {
47                 .base = SZ_1G,
48                 .size = SZ_4M
49         };
50
51         PREFIX_PUSH();
52
53         reset_memblock_regions();
54         memblock_add(r.base, r.size);
55
56         ASSERT_EQ(rgn->base, r.base);
57         ASSERT_EQ(rgn->size, r.size);
58
59         ASSERT_EQ(memblock.memory.cnt, 1);
60         ASSERT_EQ(memblock.memory.total_size, r.size);
61
62         test_pass_pop();
63
64         return 0;
65 }
66
67 /*
68  * A simple test that adds a memory block of a specified base address, size,
69  * NUMA node and memory flags to the collection of available memory regions.
70  * Expect to create a new entry. The region counter and total memory get
71  * updated.
72  */
73 static int memblock_add_node_simple_check(void)
74 {
75         struct memblock_region *rgn;
76
77         rgn = &memblock.memory.regions[0];
78
79         struct region r = {
80                 .base = SZ_1M,
81                 .size = SZ_16M
82         };
83
84         PREFIX_PUSH();
85
86         reset_memblock_regions();
87         memblock_add_node(r.base, r.size, 1, MEMBLOCK_HOTPLUG);
88
89         ASSERT_EQ(rgn->base, r.base);
90         ASSERT_EQ(rgn->size, r.size);
91 #ifdef CONFIG_NUMA
92         ASSERT_EQ(rgn->nid, 1);
93 #endif
94         ASSERT_EQ(rgn->flags, MEMBLOCK_HOTPLUG);
95
96         ASSERT_EQ(memblock.memory.cnt, 1);
97         ASSERT_EQ(memblock.memory.total_size, r.size);
98
99         test_pass_pop();
100
101         return 0;
102 }
103
104 /*
105  * A test that tries to add two memory blocks that don't overlap with one
106  * another:
107  *
108  *  |        +--------+        +--------+  |
109  *  |        |   r1   |        |   r2   |  |
110  *  +--------+--------+--------+--------+--+
111  *
112  * Expect to add two correctly initialized entries to the collection of
113  * available memory regions (memblock.memory). The total size and
114  * region counter fields get updated.
115  */
116 static int memblock_add_disjoint_check(void)
117 {
118         struct memblock_region *rgn1, *rgn2;
119
120         rgn1 = &memblock.memory.regions[0];
121         rgn2 = &memblock.memory.regions[1];
122
123         struct region r1 = {
124                 .base = SZ_1G,
125                 .size = SZ_8K
126         };
127         struct region r2 = {
128                 .base = SZ_1G + SZ_16K,
129                 .size = SZ_8K
130         };
131
132         PREFIX_PUSH();
133
134         reset_memblock_regions();
135         memblock_add(r1.base, r1.size);
136         memblock_add(r2.base, r2.size);
137
138         ASSERT_EQ(rgn1->base, r1.base);
139         ASSERT_EQ(rgn1->size, r1.size);
140
141         ASSERT_EQ(rgn2->base, r2.base);
142         ASSERT_EQ(rgn2->size, r2.size);
143
144         ASSERT_EQ(memblock.memory.cnt, 2);
145         ASSERT_EQ(memblock.memory.total_size, r1.size + r2.size);
146
147         test_pass_pop();
148
149         return 0;
150 }
151
152 /*
153  * A test that tries to add two memory blocks r1 and r2, where r2 overlaps
154  * with the beginning of r1 (that is r1.base < r2.base + r2.size):
155  *
156  *  |    +----+----+------------+          |
157  *  |    |    |r2  |   r1       |          |
158  *  +----+----+----+------------+----------+
159  *       ^    ^
160  *       |    |
161  *       |    r1.base
162  *       |
163  *       r2.base
164  *
165  * Expect to merge the two entries into one region that starts at r2.base
166  * and has size of two regions minus their intersection. The total size of
167  * the available memory is updated, and the region counter stays the same.
168  */
169 static int memblock_add_overlap_top_check(void)
170 {
171         struct memblock_region *rgn;
172         phys_addr_t total_size;
173
174         rgn = &memblock.memory.regions[0];
175
176         struct region r1 = {
177                 .base = SZ_512M,
178                 .size = SZ_1G
179         };
180         struct region r2 = {
181                 .base = SZ_256M,
182                 .size = SZ_512M
183         };
184
185         PREFIX_PUSH();
186
187         total_size = (r1.base - r2.base) + r1.size;
188
189         reset_memblock_regions();
190         memblock_add(r1.base, r1.size);
191         memblock_add(r2.base, r2.size);
192
193         ASSERT_EQ(rgn->base, r2.base);
194         ASSERT_EQ(rgn->size, total_size);
195
196         ASSERT_EQ(memblock.memory.cnt, 1);
197         ASSERT_EQ(memblock.memory.total_size, total_size);
198
199         test_pass_pop();
200
201         return 0;
202 }
203
204 /*
205  * A test that tries to add two memory blocks r1 and r2, where r2 overlaps
206  * with the end of r1 (that is r2.base < r1.base + r1.size):
207  *
208  *  |  +--+------+----------+              |
209  *  |  |  | r1   | r2       |              |
210  *  +--+--+------+----------+--------------+
211  *     ^  ^
212  *     |  |
213  *     |  r2.base
214  *     |
215  *     r1.base
216  *
217  * Expect to merge the two entries into one region that starts at r1.base
218  * and has size of two regions minus their intersection. The total size of
219  * the available memory is updated, and the region counter stays the same.
220  */
221 static int memblock_add_overlap_bottom_check(void)
222 {
223         struct memblock_region *rgn;
224         phys_addr_t total_size;
225
226         rgn = &memblock.memory.regions[0];
227
228         struct region r1 = {
229                 .base = SZ_128M,
230                 .size = SZ_512M
231         };
232         struct region r2 = {
233                 .base = SZ_256M,
234                 .size = SZ_1G
235         };
236
237         PREFIX_PUSH();
238
239         total_size = (r2.base - r1.base) + r2.size;
240
241         reset_memblock_regions();
242         memblock_add(r1.base, r1.size);
243         memblock_add(r2.base, r2.size);
244
245         ASSERT_EQ(rgn->base, r1.base);
246         ASSERT_EQ(rgn->size, total_size);
247
248         ASSERT_EQ(memblock.memory.cnt, 1);
249         ASSERT_EQ(memblock.memory.total_size, total_size);
250
251         test_pass_pop();
252
253         return 0;
254 }
255
256 /*
257  * A test that tries to add two memory blocks r1 and r2, where r2 is
258  * within the range of r1 (that is r1.base < r2.base &&
259  * r2.base + r2.size < r1.base + r1.size):
260  *
261  *  |   +-------+--+-----------------------+
262  *  |   |       |r2|      r1               |
263  *  +---+-------+--+-----------------------+
264  *      ^
265  *      |
266  *      r1.base
267  *
268  * Expect to merge two entries into one region that stays the same.
269  * The counter and total size of available memory are not updated.
270  */
271 static int memblock_add_within_check(void)
272 {
273         struct memblock_region *rgn;
274
275         rgn = &memblock.memory.regions[0];
276
277         struct region r1 = {
278                 .base = SZ_8M,
279                 .size = SZ_32M
280         };
281         struct region r2 = {
282                 .base = SZ_16M,
283                 .size = SZ_1M
284         };
285
286         PREFIX_PUSH();
287
288         reset_memblock_regions();
289         memblock_add(r1.base, r1.size);
290         memblock_add(r2.base, r2.size);
291
292         ASSERT_EQ(rgn->base, r1.base);
293         ASSERT_EQ(rgn->size, r1.size);
294
295         ASSERT_EQ(memblock.memory.cnt, 1);
296         ASSERT_EQ(memblock.memory.total_size, r1.size);
297
298         test_pass_pop();
299
300         return 0;
301 }
302
303 /*
304  * A simple test that tries to add the same memory block twice. Expect
305  * the counter and total size of available memory to not be updated.
306  */
307 static int memblock_add_twice_check(void)
308 {
309         struct region r = {
310                 .base = SZ_16K,
311                 .size = SZ_2M
312         };
313
314         PREFIX_PUSH();
315
316         reset_memblock_regions();
317
318         memblock_add(r.base, r.size);
319         memblock_add(r.base, r.size);
320
321         ASSERT_EQ(memblock.memory.cnt, 1);
322         ASSERT_EQ(memblock.memory.total_size, r.size);
323
324         test_pass_pop();
325
326         return 0;
327 }
328
329 static int memblock_add_checks(void)
330 {
331         prefix_reset();
332         prefix_push(FUNC_ADD);
333         test_print("Running %s tests...\n", FUNC_ADD);
334
335         memblock_add_simple_check();
336         memblock_add_node_simple_check();
337         memblock_add_disjoint_check();
338         memblock_add_overlap_top_check();
339         memblock_add_overlap_bottom_check();
340         memblock_add_within_check();
341         memblock_add_twice_check();
342
343         prefix_pop();
344
345         return 0;
346 }
347
348 /*
349  * A simple test that marks a memory block of a specified base address
350  * and size as reserved and to the collection of reserved memory regions
351  * (memblock.reserved). Expect to create a new entry. The region counter
352  * and total memory size are updated.
353  */
354 static int memblock_reserve_simple_check(void)
355 {
356         struct memblock_region *rgn;
357
358         rgn =  &memblock.reserved.regions[0];
359
360         struct region r = {
361                 .base = SZ_2G,
362                 .size = SZ_128M
363         };
364
365         PREFIX_PUSH();
366
367         reset_memblock_regions();
368         memblock_reserve(r.base, r.size);
369
370         ASSERT_EQ(rgn->base, r.base);
371         ASSERT_EQ(rgn->size, r.size);
372
373         test_pass_pop();
374
375         return 0;
376 }
377
378 /*
379  * A test that tries to mark two memory blocks that don't overlap as reserved:
380  *
381  *  |        +--+      +----------------+  |
382  *  |        |r1|      |       r2       |  |
383  *  +--------+--+------+----------------+--+
384  *
385  * Expect to add two entries to the collection of reserved memory regions
386  * (memblock.reserved). The total size and region counter for
387  * memblock.reserved are updated.
388  */
389 static int memblock_reserve_disjoint_check(void)
390 {
391         struct memblock_region *rgn1, *rgn2;
392
393         rgn1 = &memblock.reserved.regions[0];
394         rgn2 = &memblock.reserved.regions[1];
395
396         struct region r1 = {
397                 .base = SZ_256M,
398                 .size = SZ_16M
399         };
400         struct region r2 = {
401                 .base = SZ_512M,
402                 .size = SZ_512M
403         };
404
405         PREFIX_PUSH();
406
407         reset_memblock_regions();
408         memblock_reserve(r1.base, r1.size);
409         memblock_reserve(r2.base, r2.size);
410
411         ASSERT_EQ(rgn1->base, r1.base);
412         ASSERT_EQ(rgn1->size, r1.size);
413
414         ASSERT_EQ(rgn2->base, r2.base);
415         ASSERT_EQ(rgn2->size, r2.size);
416
417         ASSERT_EQ(memblock.reserved.cnt, 2);
418         ASSERT_EQ(memblock.reserved.total_size, r1.size + r2.size);
419
420         test_pass_pop();
421
422         return 0;
423 }
424
425 /*
426  * A test that tries to mark two memory blocks r1 and r2 as reserved,
427  * where r2 overlaps with the beginning of r1 (that is
428  * r1.base < r2.base + r2.size):
429  *
430  *  |  +--------------+--+--------------+  |
431  *  |  |       r2     |  |     r1       |  |
432  *  +--+--------------+--+--------------+--+
433  *     ^              ^
434  *     |              |
435  *     |              r1.base
436  *     |
437  *     r2.base
438  *
439  * Expect to merge two entries into one region that starts at r2.base and
440  * has size of two regions minus their intersection. The total size of the
441  * reserved memory is updated, and the region counter is not updated.
442  */
443 static int memblock_reserve_overlap_top_check(void)
444 {
445         struct memblock_region *rgn;
446         phys_addr_t total_size;
447
448         rgn = &memblock.reserved.regions[0];
449
450         struct region r1 = {
451                 .base = SZ_1G,
452                 .size = SZ_1G
453         };
454         struct region r2 = {
455                 .base = SZ_128M,
456                 .size = SZ_1G
457         };
458
459         PREFIX_PUSH();
460
461         total_size = (r1.base - r2.base) + r1.size;
462
463         reset_memblock_regions();
464         memblock_reserve(r1.base, r1.size);
465         memblock_reserve(r2.base, r2.size);
466
467         ASSERT_EQ(rgn->base, r2.base);
468         ASSERT_EQ(rgn->size, total_size);
469
470         ASSERT_EQ(memblock.reserved.cnt, 1);
471         ASSERT_EQ(memblock.reserved.total_size, total_size);
472
473         test_pass_pop();
474
475         return 0;
476 }
477
478 /*
479  * A test that tries to mark two memory blocks r1 and r2 as reserved,
480  * where r2 overlaps with the end of r1 (that is
481  * r2.base < r1.base + r1.size):
482  *
483  *  |  +--------------+--+--------------+  |
484  *  |  |       r1     |  |     r2       |  |
485  *  +--+--------------+--+--------------+--+
486  *     ^              ^
487  *     |              |
488  *     |              r2.base
489  *     |
490  *     r1.base
491  *
492  * Expect to merge two entries into one region that starts at r1.base and
493  * has size of two regions minus their intersection. The total size of the
494  * reserved memory is updated, and the region counter is not updated.
495  */
496 static int memblock_reserve_overlap_bottom_check(void)
497 {
498         struct memblock_region *rgn;
499         phys_addr_t total_size;
500
501         rgn = &memblock.reserved.regions[0];
502
503         struct region r1 = {
504                 .base = SZ_2K,
505                 .size = SZ_128K
506         };
507         struct region r2 = {
508                 .base = SZ_128K,
509                 .size = SZ_128K
510         };
511
512         PREFIX_PUSH();
513
514         total_size = (r2.base - r1.base) + r2.size;
515
516         reset_memblock_regions();
517         memblock_reserve(r1.base, r1.size);
518         memblock_reserve(r2.base, r2.size);
519
520         ASSERT_EQ(rgn->base, r1.base);
521         ASSERT_EQ(rgn->size, total_size);
522
523         ASSERT_EQ(memblock.reserved.cnt, 1);
524         ASSERT_EQ(memblock.reserved.total_size, total_size);
525
526         test_pass_pop();
527
528         return 0;
529 }
530
531 /*
532  * A test that tries to mark two memory blocks r1 and r2 as reserved,
533  * where r2 is within the range of r1 (that is
534  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
535  *
536  *  | +-----+--+---------------------------|
537  *  | |     |r2|          r1               |
538  *  +-+-----+--+---------------------------+
539  *    ^     ^
540  *    |     |
541  *    |     r2.base
542  *    |
543  *    r1.base
544  *
545  * Expect to merge two entries into one region that stays the same. The
546  * counter and total size of available memory are not updated.
547  */
548 static int memblock_reserve_within_check(void)
549 {
550         struct memblock_region *rgn;
551
552         rgn = &memblock.reserved.regions[0];
553
554         struct region r1 = {
555                 .base = SZ_1M,
556                 .size = SZ_8M
557         };
558         struct region r2 = {
559                 .base = SZ_2M,
560                 .size = SZ_64K
561         };
562
563         PREFIX_PUSH();
564
565         reset_memblock_regions();
566         memblock_reserve(r1.base, r1.size);
567         memblock_reserve(r2.base, r2.size);
568
569         ASSERT_EQ(rgn->base, r1.base);
570         ASSERT_EQ(rgn->size, r1.size);
571
572         ASSERT_EQ(memblock.reserved.cnt, 1);
573         ASSERT_EQ(memblock.reserved.total_size, r1.size);
574
575         test_pass_pop();
576
577         return 0;
578 }
579
580 /*
581  * A simple test that tries to reserve the same memory block twice.
582  * Expect the region counter and total size of reserved memory to not
583  * be updated.
584  */
585 static int memblock_reserve_twice_check(void)
586 {
587         struct region r = {
588                 .base = SZ_16K,
589                 .size = SZ_2M
590         };
591
592         PREFIX_PUSH();
593
594         reset_memblock_regions();
595
596         memblock_reserve(r.base, r.size);
597         memblock_reserve(r.base, r.size);
598
599         ASSERT_EQ(memblock.reserved.cnt, 1);
600         ASSERT_EQ(memblock.reserved.total_size, r.size);
601
602         test_pass_pop();
603
604         return 0;
605 }
606
607 static int memblock_reserve_checks(void)
608 {
609         prefix_reset();
610         prefix_push(FUNC_RESERVE);
611         test_print("Running %s tests...\n", FUNC_RESERVE);
612
613         memblock_reserve_simple_check();
614         memblock_reserve_disjoint_check();
615         memblock_reserve_overlap_top_check();
616         memblock_reserve_overlap_bottom_check();
617         memblock_reserve_within_check();
618         memblock_reserve_twice_check();
619
620         prefix_pop();
621
622         return 0;
623 }
624
625 /*
626  * A simple test that tries to remove a region r1 from the array of
627  * available memory regions. By "removing" a region we mean overwriting it
628  * with the next region r2 in memblock.memory:
629  *
630  *  |  ......          +----------------+  |
631  *  |  : r1 :          |       r2       |  |
632  *  +--+----+----------+----------------+--+
633  *                     ^
634  *                     |
635  *                     rgn.base
636  *
637  * Expect to add two memory blocks r1 and r2 and then remove r1 so that
638  * r2 is the first available region. The region counter and total size
639  * are updated.
640  */
641 static int memblock_remove_simple_check(void)
642 {
643         struct memblock_region *rgn;
644
645         rgn = &memblock.memory.regions[0];
646
647         struct region r1 = {
648                 .base = SZ_2K,
649                 .size = SZ_4K
650         };
651         struct region r2 = {
652                 .base = SZ_128K,
653                 .size = SZ_4M
654         };
655
656         PREFIX_PUSH();
657
658         reset_memblock_regions();
659         memblock_add(r1.base, r1.size);
660         memblock_add(r2.base, r2.size);
661         memblock_remove(r1.base, r1.size);
662
663         ASSERT_EQ(rgn->base, r2.base);
664         ASSERT_EQ(rgn->size, r2.size);
665
666         ASSERT_EQ(memblock.memory.cnt, 1);
667         ASSERT_EQ(memblock.memory.total_size, r2.size);
668
669         test_pass_pop();
670
671         return 0;
672 }
673
674 /*
675  * A test that tries to remove a region r2 that was not registered as
676  * available memory (i.e. has no corresponding entry in memblock.memory):
677  *
678  *                     +----------------+
679  *                     |       r2       |
680  *                     +----------------+
681  *  |  +----+                              |
682  *  |  | r1 |                              |
683  *  +--+----+------------------------------+
684  *     ^
685  *     |
686  *     rgn.base
687  *
688  * Expect the array, regions counter and total size to not be modified.
689  */
690 static int memblock_remove_absent_check(void)
691 {
692         struct memblock_region *rgn;
693
694         rgn = &memblock.memory.regions[0];
695
696         struct region r1 = {
697                 .base = SZ_512K,
698                 .size = SZ_4M
699         };
700         struct region r2 = {
701                 .base = SZ_64M,
702                 .size = SZ_1G
703         };
704
705         PREFIX_PUSH();
706
707         reset_memblock_regions();
708         memblock_add(r1.base, r1.size);
709         memblock_remove(r2.base, r2.size);
710
711         ASSERT_EQ(rgn->base, r1.base);
712         ASSERT_EQ(rgn->size, r1.size);
713
714         ASSERT_EQ(memblock.memory.cnt, 1);
715         ASSERT_EQ(memblock.memory.total_size, r1.size);
716
717         test_pass_pop();
718
719         return 0;
720 }
721
722 /*
723  * A test that tries to remove a region r2 that overlaps with the
724  * beginning of the already existing entry r1
725  * (that is r1.base < r2.base + r2.size):
726  *
727  *           +-----------------+
728  *           |       r2        |
729  *           +-----------------+
730  *  |                 .........+--------+  |
731  *  |                 :     r1 |  rgn   |  |
732  *  +-----------------+--------+--------+--+
733  *                    ^        ^
734  *                    |        |
735  *                    |        rgn.base
736  *                    r1.base
737  *
738  * Expect that only the intersection of both regions is removed from the
739  * available memory pool. The regions counter and total size are updated.
740  */
741 static int memblock_remove_overlap_top_check(void)
742 {
743         struct memblock_region *rgn;
744         phys_addr_t r1_end, r2_end, total_size;
745
746         rgn = &memblock.memory.regions[0];
747
748         struct region r1 = {
749                 .base = SZ_32M,
750                 .size = SZ_32M
751         };
752         struct region r2 = {
753                 .base = SZ_16M,
754                 .size = SZ_32M
755         };
756
757         PREFIX_PUSH();
758
759         r1_end = r1.base + r1.size;
760         r2_end = r2.base + r2.size;
761         total_size = r1_end - r2_end;
762
763         reset_memblock_regions();
764         memblock_add(r1.base, r1.size);
765         memblock_remove(r2.base, r2.size);
766
767         ASSERT_EQ(rgn->base, r1.base + r2.base);
768         ASSERT_EQ(rgn->size, total_size);
769
770         ASSERT_EQ(memblock.memory.cnt, 1);
771         ASSERT_EQ(memblock.memory.total_size, total_size);
772
773         test_pass_pop();
774
775         return 0;
776 }
777
778 /*
779  * A test that tries to remove a region r2 that overlaps with the end of
780  * the already existing region r1 (that is r2.base < r1.base + r1.size):
781  *
782  *        +--------------------------------+
783  *        |               r2               |
784  *        +--------------------------------+
785  *  | +---+.....                           |
786  *  | |rgn| r1 :                           |
787  *  +-+---+----+---------------------------+
788  *    ^
789  *    |
790  *    r1.base
791  *
792  * Expect that only the intersection of both regions is removed from the
793  * available memory pool. The regions counter and total size are updated.
794  */
795 static int memblock_remove_overlap_bottom_check(void)
796 {
797         struct memblock_region *rgn;
798         phys_addr_t total_size;
799
800         rgn = &memblock.memory.regions[0];
801
802         struct region r1 = {
803                 .base = SZ_2M,
804                 .size = SZ_64M
805         };
806         struct region r2 = {
807                 .base = SZ_32M,
808                 .size = SZ_256M
809         };
810
811         PREFIX_PUSH();
812
813         total_size = r2.base - r1.base;
814
815         reset_memblock_regions();
816         memblock_add(r1.base, r1.size);
817         memblock_remove(r2.base, r2.size);
818
819         ASSERT_EQ(rgn->base, r1.base);
820         ASSERT_EQ(rgn->size, total_size);
821
822         ASSERT_EQ(memblock.memory.cnt, 1);
823         ASSERT_EQ(memblock.memory.total_size, total_size);
824
825         test_pass_pop();
826
827         return 0;
828 }
829
830 /*
831  * A test that tries to remove a region r2 that is within the range of
832  * the already existing entry r1 (that is
833  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
834  *
835  *                  +----+
836  *                  | r2 |
837  *                  +----+
838  *  | +-------------+....+---------------+ |
839  *  | |     rgn1    | r1 |     rgn2      | |
840  *  +-+-------------+----+---------------+-+
841  *    ^
842  *    |
843  *    r1.base
844  *
845  * Expect that the region is split into two - one that ends at r2.base and
846  * another that starts at r2.base + r2.size, with appropriate sizes. The
847  * region counter and total size are updated.
848  */
849 static int memblock_remove_within_check(void)
850 {
851         struct memblock_region *rgn1, *rgn2;
852         phys_addr_t r1_size, r2_size, total_size;
853
854         rgn1 = &memblock.memory.regions[0];
855         rgn2 = &memblock.memory.regions[1];
856
857         struct region r1 = {
858                 .base = SZ_1M,
859                 .size = SZ_32M
860         };
861         struct region r2 = {
862                 .base = SZ_16M,
863                 .size = SZ_1M
864         };
865
866         PREFIX_PUSH();
867
868         r1_size = r2.base - r1.base;
869         r2_size = (r1.base + r1.size) - (r2.base + r2.size);
870         total_size = r1_size + r2_size;
871
872         reset_memblock_regions();
873         memblock_add(r1.base, r1.size);
874         memblock_remove(r2.base, r2.size);
875
876         ASSERT_EQ(rgn1->base, r1.base);
877         ASSERT_EQ(rgn1->size, r1_size);
878
879         ASSERT_EQ(rgn2->base, r2.base + r2.size);
880         ASSERT_EQ(rgn2->size, r2_size);
881
882         ASSERT_EQ(memblock.memory.cnt, 2);
883         ASSERT_EQ(memblock.memory.total_size, total_size);
884
885         test_pass_pop();
886
887         return 0;
888 }
889
890 static int memblock_remove_checks(void)
891 {
892         prefix_reset();
893         prefix_push(FUNC_REMOVE);
894         test_print("Running %s tests...\n", FUNC_REMOVE);
895
896         memblock_remove_simple_check();
897         memblock_remove_absent_check();
898         memblock_remove_overlap_top_check();
899         memblock_remove_overlap_bottom_check();
900         memblock_remove_within_check();
901
902         prefix_pop();
903
904         return 0;
905 }
906
907 /*
908  * A simple test that tries to free a memory block r1 that was marked
909  * earlier as reserved. By "freeing" a region we mean overwriting it with
910  * the next entry r2 in memblock.reserved:
911  *
912  *  |              ......           +----+ |
913  *  |              : r1 :           | r2 | |
914  *  +--------------+----+-----------+----+-+
915  *                                  ^
916  *                                  |
917  *                                  rgn.base
918  *
919  * Expect to reserve two memory regions and then erase r1 region with the
920  * value of r2. The region counter and total size are updated.
921  */
922 static int memblock_free_simple_check(void)
923 {
924         struct memblock_region *rgn;
925
926         rgn = &memblock.reserved.regions[0];
927
928         struct region r1 = {
929                 .base = SZ_4M,
930                 .size = SZ_1M
931         };
932         struct region r2 = {
933                 .base = SZ_8M,
934                 .size = SZ_1M
935         };
936
937         PREFIX_PUSH();
938
939         reset_memblock_regions();
940         memblock_reserve(r1.base, r1.size);
941         memblock_reserve(r2.base, r2.size);
942         memblock_free((void *)r1.base, r1.size);
943
944         ASSERT_EQ(rgn->base, r2.base);
945         ASSERT_EQ(rgn->size, r2.size);
946
947         ASSERT_EQ(memblock.reserved.cnt, 1);
948         ASSERT_EQ(memblock.reserved.total_size, r2.size);
949
950         test_pass_pop();
951
952         return 0;
953 }
954
955 /*
956  * A test that tries to free a region r2 that was not marked as reserved
957  * (i.e. has no corresponding entry in memblock.reserved):
958  *
959  *                     +----------------+
960  *                     |       r2       |
961  *                     +----------------+
962  *  |  +----+                              |
963  *  |  | r1 |                              |
964  *  +--+----+------------------------------+
965  *     ^
966  *     |
967  *     rgn.base
968  *
969  * The array, regions counter and total size are not modified.
970  */
971 static int memblock_free_absent_check(void)
972 {
973         struct memblock_region *rgn;
974
975         rgn = &memblock.reserved.regions[0];
976
977         struct region r1 = {
978                 .base = SZ_2M,
979                 .size = SZ_8K
980         };
981         struct region r2 = {
982                 .base = SZ_16M,
983                 .size = SZ_128M
984         };
985
986         PREFIX_PUSH();
987
988         reset_memblock_regions();
989         memblock_reserve(r1.base, r1.size);
990         memblock_free((void *)r2.base, r2.size);
991
992         ASSERT_EQ(rgn->base, r1.base);
993         ASSERT_EQ(rgn->size, r1.size);
994
995         ASSERT_EQ(memblock.reserved.cnt, 1);
996         ASSERT_EQ(memblock.reserved.total_size, r1.size);
997
998         test_pass_pop();
999
1000         return 0;
1001 }
1002
1003 /*
1004  * A test that tries to free a region r2 that overlaps with the beginning
1005  * of the already existing entry r1 (that is r1.base < r2.base + r2.size):
1006  *
1007  *     +----+
1008  *     | r2 |
1009  *     +----+
1010  *  |    ...+--------------+               |
1011  *  |    :  |    r1        |               |
1012  *  +----+--+--------------+---------------+
1013  *       ^  ^
1014  *       |  |
1015  *       |  rgn.base
1016  *       |
1017  *       r1.base
1018  *
1019  * Expect that only the intersection of both regions is freed. The
1020  * regions counter and total size are updated.
1021  */
1022 static int memblock_free_overlap_top_check(void)
1023 {
1024         struct memblock_region *rgn;
1025         phys_addr_t total_size;
1026
1027         rgn = &memblock.reserved.regions[0];
1028
1029         struct region r1 = {
1030                 .base = SZ_8M,
1031                 .size = SZ_32M
1032         };
1033         struct region r2 = {
1034                 .base = SZ_1M,
1035                 .size = SZ_8M
1036         };
1037
1038         PREFIX_PUSH();
1039
1040         total_size = (r1.size + r1.base) - (r2.base + r2.size);
1041
1042         reset_memblock_regions();
1043         memblock_reserve(r1.base, r1.size);
1044         memblock_free((void *)r2.base, r2.size);
1045
1046         ASSERT_EQ(rgn->base, r2.base + r2.size);
1047         ASSERT_EQ(rgn->size, total_size);
1048
1049         ASSERT_EQ(memblock.reserved.cnt, 1);
1050         ASSERT_EQ(memblock.reserved.total_size, total_size);
1051
1052         test_pass_pop();
1053
1054         return 0;
1055 }
1056
1057 /*
1058  * A test that tries to free a region r2 that overlaps with the end of
1059  * the already existing entry r1 (that is r2.base < r1.base + r1.size):
1060  *
1061  *                   +----------------+
1062  *                   |       r2       |
1063  *                   +----------------+
1064  *  |    +-----------+.....                |
1065  *  |    |       r1  |    :                |
1066  *  +----+-----------+----+----------------+
1067  *
1068  * Expect that only the intersection of both regions is freed. The
1069  * regions counter and total size are updated.
1070  */
1071 static int memblock_free_overlap_bottom_check(void)
1072 {
1073         struct memblock_region *rgn;
1074         phys_addr_t total_size;
1075
1076         rgn = &memblock.reserved.regions[0];
1077
1078         struct region r1 = {
1079                 .base = SZ_8M,
1080                 .size = SZ_32M
1081         };
1082         struct region r2 = {
1083                 .base = SZ_32M,
1084                 .size = SZ_32M
1085         };
1086
1087         PREFIX_PUSH();
1088
1089         total_size = r2.base - r1.base;
1090
1091         reset_memblock_regions();
1092         memblock_reserve(r1.base, r1.size);
1093         memblock_free((void *)r2.base, r2.size);
1094
1095         ASSERT_EQ(rgn->base, r1.base);
1096         ASSERT_EQ(rgn->size, total_size);
1097
1098         ASSERT_EQ(memblock.reserved.cnt, 1);
1099         ASSERT_EQ(memblock.reserved.total_size, total_size);
1100
1101         test_pass_pop();
1102
1103         return 0;
1104 }
1105
1106 /*
1107  * A test that tries to free a region r2 that is within the range of the
1108  * already existing entry r1 (that is
1109  * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)):
1110  *
1111  *                    +----+
1112  *                    | r2 |
1113  *                    +----+
1114  *  |    +------------+....+---------------+
1115  *  |    |    rgn1    | r1 |     rgn2      |
1116  *  +----+------------+----+---------------+
1117  *       ^
1118  *       |
1119  *       r1.base
1120  *
1121  * Expect that the region is split into two - one that ends at r2.base and
1122  * another that starts at r2.base + r2.size, with appropriate sizes. The
1123  * region counter and total size fields are updated.
1124  */
1125 static int memblock_free_within_check(void)
1126 {
1127         struct memblock_region *rgn1, *rgn2;
1128         phys_addr_t r1_size, r2_size, total_size;
1129
1130         rgn1 = &memblock.reserved.regions[0];
1131         rgn2 = &memblock.reserved.regions[1];
1132
1133         struct region r1 = {
1134                 .base = SZ_1M,
1135                 .size = SZ_8M
1136         };
1137         struct region r2 = {
1138                 .base = SZ_4M,
1139                 .size = SZ_1M
1140         };
1141
1142         PREFIX_PUSH();
1143
1144         r1_size = r2.base - r1.base;
1145         r2_size = (r1.base + r1.size) - (r2.base + r2.size);
1146         total_size = r1_size + r2_size;
1147
1148         reset_memblock_regions();
1149         memblock_reserve(r1.base, r1.size);
1150         memblock_free((void *)r2.base, r2.size);
1151
1152         ASSERT_EQ(rgn1->base, r1.base);
1153         ASSERT_EQ(rgn1->size, r1_size);
1154
1155         ASSERT_EQ(rgn2->base, r2.base + r2.size);
1156         ASSERT_EQ(rgn2->size, r2_size);
1157
1158         ASSERT_EQ(memblock.reserved.cnt, 2);
1159         ASSERT_EQ(memblock.reserved.total_size, total_size);
1160
1161         test_pass_pop();
1162
1163         return 0;
1164 }
1165
1166 static int memblock_free_checks(void)
1167 {
1168         prefix_reset();
1169         prefix_push(FUNC_FREE);
1170         test_print("Running %s tests...\n", FUNC_FREE);
1171
1172         memblock_free_simple_check();
1173         memblock_free_absent_check();
1174         memblock_free_overlap_top_check();
1175         memblock_free_overlap_bottom_check();
1176         memblock_free_within_check();
1177
1178         prefix_pop();
1179
1180         return 0;
1181 }
1182
1183 int memblock_basic_checks(void)
1184 {
1185         memblock_initialization_check();
1186         memblock_add_checks();
1187         memblock_reserve_checks();
1188         memblock_remove_checks();
1189         memblock_free_checks();
1190
1191         return 0;
1192 }