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 }
1193