Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
8static int memblock_initialization_check(void)
9{
10 assert(memblock.memory.regions);
11 assert(memblock.memory.cnt == 1);
12 assert(memblock.memory.max == EXPECTED_MEMBLOCK_REGIONS);
13 assert(strcmp(memblock.memory.name, "memory") == 0);
14
15 assert(memblock.reserved.regions);
16 assert(memblock.reserved.cnt == 1);
17 assert(memblock.memory.max == EXPECTED_MEMBLOCK_REGIONS);
18 assert(strcmp(memblock.reserved.name, "reserved") == 0);
19
20 assert(!memblock.bottom_up);
21 assert(memblock.current_limit == MEMBLOCK_ALLOC_ANYWHERE);
22
23 return 0;
24}
25
26/*
27 * A simple test that adds a memory block of a specified base address
28 * and size to the collection of available memory regions (memblock.memory).
29 * It checks if a new entry was created and if region counter and total memory
30 * were correctly updated.
31 */
32static int memblock_add_simple_check(void)
33{
34 struct memblock_region *rgn;
35
36 rgn = &memblock.memory.regions[0];
37
38 struct region r = {
39 .base = SZ_1G,
40 .size = SZ_4M
41 };
42
43 reset_memblock_regions();
44 memblock_add(r.base, r.size);
45
46 assert(rgn->base == r.base);
47 assert(rgn->size == r.size);
48
49 assert(memblock.memory.cnt == 1);
50 assert(memblock.memory.total_size == r.size);
51
52 return 0;
53}
54
55/*
56 * A simple test that adds a memory block of a specified base address, size
57 * NUMA node and memory flags to the collection of available memory regions.
58 * It checks if the new entry, region counter and total memory size have
59 * expected values.
60 */
61static int memblock_add_node_simple_check(void)
62{
63 struct memblock_region *rgn;
64
65 rgn = &memblock.memory.regions[0];
66
67 struct region r = {
68 .base = SZ_1M,
69 .size = SZ_16M
70 };
71
72 reset_memblock_regions();
73 memblock_add_node(r.base, r.size, 1, MEMBLOCK_HOTPLUG);
74
75 assert(rgn->base == r.base);
76 assert(rgn->size == r.size);
77#ifdef CONFIG_NUMA
78 assert(rgn->nid == 1);
79#endif
80 assert(rgn->flags == MEMBLOCK_HOTPLUG);
81
82 assert(memblock.memory.cnt == 1);
83 assert(memblock.memory.total_size == r.size);
84
85 return 0;
86}
87
88/*
89 * A test that tries to add two memory blocks that don't overlap with one
90 * another. It checks if two correctly initialized entries were added to the
91 * collection of available memory regions (memblock.memory) and if this
92 * change was reflected in memblock.memory's total size and region counter.
93 */
94static int memblock_add_disjoint_check(void)
95{
96 struct memblock_region *rgn1, *rgn2;
97
98 rgn1 = &memblock.memory.regions[0];
99 rgn2 = &memblock.memory.regions[1];
100
101 struct region r1 = {
102 .base = SZ_1G,
103 .size = SZ_8K
104 };
105 struct region r2 = {
106 .base = SZ_1G + SZ_16K,
107 .size = SZ_8K
108 };
109
110 reset_memblock_regions();
111 memblock_add(r1.base, r1.size);
112 memblock_add(r2.base, r2.size);
113
114 assert(rgn1->base == r1.base);
115 assert(rgn1->size == r1.size);
116
117 assert(rgn2->base == r2.base);
118 assert(rgn2->size == r2.size);
119
120 assert(memblock.memory.cnt == 2);
121 assert(memblock.memory.total_size == r1.size + r2.size);
122
123 return 0;
124}
125
126/*
127 * A test that tries to add two memory blocks, where the second one overlaps
128 * with the beginning of the first entry (that is r1.base < r2.base + r2.size).
129 * After this, it checks if two entries are merged into one region that starts
130 * at r2.base and has size of two regions minus their intersection. It also
131 * verifies the reported total size of the available memory and region counter.
132 */
133static int memblock_add_overlap_top_check(void)
134{
135 struct memblock_region *rgn;
136 phys_addr_t total_size;
137
138 rgn = &memblock.memory.regions[0];
139
140 struct region r1 = {
141 .base = SZ_512M,
142 .size = SZ_1G
143 };
144 struct region r2 = {
145 .base = SZ_256M,
146 .size = SZ_512M
147 };
148
149 total_size = (r1.base - r2.base) + r1.size;
150
151 reset_memblock_regions();
152 memblock_add(r1.base, r1.size);
153 memblock_add(r2.base, r2.size);
154
155 assert(rgn->base == r2.base);
156 assert(rgn->size == total_size);
157
158 assert(memblock.memory.cnt == 1);
159 assert(memblock.memory.total_size == total_size);
160
161 return 0;
162}
163
164/*
165 * A test that tries to add two memory blocks, where the second one overlaps
166 * with the end of the first entry (that is r2.base < r1.base + r1.size).
167 * After this, it checks if two entries are merged into one region that starts
168 * at r1.base and has size of two regions minus their intersection. It verifies
169 * that memblock can still see only one entry and has a correct total size of
170 * the available memory.
171 */
172static int memblock_add_overlap_bottom_check(void)
173{
174 struct memblock_region *rgn;
175 phys_addr_t total_size;
176
177 rgn = &memblock.memory.regions[0];
178
179 struct region r1 = {
180 .base = SZ_128M,
181 .size = SZ_512M
182 };
183 struct region r2 = {
184 .base = SZ_256M,
185 .size = SZ_1G
186 };
187
188 total_size = (r2.base - r1.base) + r2.size;
189
190 reset_memblock_regions();
191 memblock_add(r1.base, r1.size);
192 memblock_add(r2.base, r2.size);
193
194 assert(rgn->base == r1.base);
195 assert(rgn->size == total_size);
196
197 assert(memblock.memory.cnt == 1);
198 assert(memblock.memory.total_size == total_size);
199
200 return 0;
201}
202
203/*
204 * A test that tries to add two memory blocks, where the second one is
205 * within the range of the first entry (that is r1.base < r2.base &&
206 * r2.base + r2.size < r1.base + r1.size). It checks if two entries are merged
207 * into one region that stays the same. The counter and total size of available
208 * memory are expected to not be updated.
209 */
210static int memblock_add_within_check(void)
211{
212 struct memblock_region *rgn;
213
214 rgn = &memblock.memory.regions[0];
215
216 struct region r1 = {
217 .base = SZ_8M,
218 .size = SZ_32M
219 };
220 struct region r2 = {
221 .base = SZ_16M,
222 .size = SZ_1M
223 };
224
225 reset_memblock_regions();
226 memblock_add(r1.base, r1.size);
227 memblock_add(r2.base, r2.size);
228
229 assert(rgn->base == r1.base);
230 assert(rgn->size == r1.size);
231
232 assert(memblock.memory.cnt == 1);
233 assert(memblock.memory.total_size == r1.size);
234
235 return 0;
236}
237
238/*
239 * A simple test that tries to add the same memory block twice. The counter
240 * and total size of available memory are expected to not be updated.
241 */
242static int memblock_add_twice_check(void)
243{
244 struct region r = {
245 .base = SZ_16K,
246 .size = SZ_2M
247 };
248
249 reset_memblock_regions();
250
251 memblock_add(r.base, r.size);
252 memblock_add(r.base, r.size);
253
254 assert(memblock.memory.cnt == 1);
255 assert(memblock.memory.total_size == r.size);
256
257 return 0;
258}
259
260static int memblock_add_checks(void)
261{
262 memblock_add_simple_check();
263 memblock_add_node_simple_check();
264 memblock_add_disjoint_check();
265 memblock_add_overlap_top_check();
266 memblock_add_overlap_bottom_check();
267 memblock_add_within_check();
268 memblock_add_twice_check();
269
270 return 0;
271}
272
273 /*
274 * A simple test that marks a memory block of a specified base address
275 * and size as reserved and to the collection of reserved memory regions
276 * (memblock.reserved). It checks if a new entry was created and if region
277 * counter and total memory size were correctly updated.
278 */
279static int memblock_reserve_simple_check(void)
280{
281 struct memblock_region *rgn;
282
283 rgn = &memblock.reserved.regions[0];
284
285 struct region r = {
286 .base = SZ_2G,
287 .size = SZ_128M
288 };
289
290 reset_memblock_regions();
291 memblock_reserve(r.base, r.size);
292
293 assert(rgn->base == r.base);
294 assert(rgn->size == r.size);
295
296 return 0;
297}
298
299/*
300 * A test that tries to mark two memory blocks that don't overlap as reserved
301 * and checks if two entries were correctly added to the collection of reserved
302 * memory regions (memblock.reserved) and if this change was reflected in
303 * memblock.reserved's total size and region counter.
304 */
305static int memblock_reserve_disjoint_check(void)
306{
307 struct memblock_region *rgn1, *rgn2;
308
309 rgn1 = &memblock.reserved.regions[0];
310 rgn2 = &memblock.reserved.regions[1];
311
312 struct region r1 = {
313 .base = SZ_256M,
314 .size = SZ_16M
315 };
316 struct region r2 = {
317 .base = SZ_512M,
318 .size = SZ_512M
319 };
320
321 reset_memblock_regions();
322 memblock_reserve(r1.base, r1.size);
323 memblock_reserve(r2.base, r2.size);
324
325 assert(rgn1->base == r1.base);
326 assert(rgn1->size == r1.size);
327
328 assert(rgn2->base == r2.base);
329 assert(rgn2->size == r2.size);
330
331 assert(memblock.reserved.cnt == 2);
332 assert(memblock.reserved.total_size == r1.size + r2.size);
333
334 return 0;
335}
336
337/*
338 * A test that tries to mark two memory blocks as reserved, where the
339 * second one overlaps with the beginning of the first (that is
340 * r1.base < r2.base + r2.size).
341 * It checks if two entries are merged into one region that starts at r2.base
342 * and has size of two regions minus their intersection. The test also verifies
343 * that memblock can still see only one entry and has a correct total size of
344 * the reserved memory.
345 */
346static int memblock_reserve_overlap_top_check(void)
347{
348 struct memblock_region *rgn;
349 phys_addr_t total_size;
350
351 rgn = &memblock.reserved.regions[0];
352
353 struct region r1 = {
354 .base = SZ_1G,
355 .size = SZ_1G
356 };
357 struct region r2 = {
358 .base = SZ_128M,
359 .size = SZ_1G
360 };
361
362 total_size = (r1.base - r2.base) + r1.size;
363
364 reset_memblock_regions();
365 memblock_reserve(r1.base, r1.size);
366 memblock_reserve(r2.base, r2.size);
367
368 assert(rgn->base == r2.base);
369 assert(rgn->size == total_size);
370
371 assert(memblock.reserved.cnt == 1);
372 assert(memblock.reserved.total_size == total_size);
373
374 return 0;
375}
376
377/*
378 * A test that tries to mark two memory blocks as reserved, where the
379 * second one overlaps with the end of the first entry (that is
380 * r2.base < r1.base + r1.size).
381 * It checks if two entries are merged into one region that starts at r1.base
382 * and has size of two regions minus their intersection. It verifies that
383 * memblock can still see only one entry and has a correct total size of the
384 * reserved memory.
385 */
386static int memblock_reserve_overlap_bottom_check(void)
387{
388 struct memblock_region *rgn;
389 phys_addr_t total_size;
390
391 rgn = &memblock.reserved.regions[0];
392
393 struct region r1 = {
394 .base = SZ_2K,
395 .size = SZ_128K
396 };
397 struct region r2 = {
398 .base = SZ_128K,
399 .size = SZ_128K
400 };
401
402 total_size = (r2.base - r1.base) + r2.size;
403
404 reset_memblock_regions();
405 memblock_reserve(r1.base, r1.size);
406 memblock_reserve(r2.base, r2.size);
407
408 assert(rgn->base == r1.base);
409 assert(rgn->size == total_size);
410
411 assert(memblock.reserved.cnt == 1);
412 assert(memblock.reserved.total_size == total_size);
413
414 return 0;
415}
416
417/*
418 * A test that tries to mark two memory blocks as reserved, where the second
419 * one is within the range of the first entry (that is
420 * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
421 * It checks if two entries are merged into one region that stays the
422 * same. The counter and total size of available memory are expected to not be
423 * updated.
424 */
425static int memblock_reserve_within_check(void)
426{
427 struct memblock_region *rgn;
428
429 rgn = &memblock.reserved.regions[0];
430
431 struct region r1 = {
432 .base = SZ_1M,
433 .size = SZ_8M
434 };
435 struct region r2 = {
436 .base = SZ_2M,
437 .size = SZ_64K
438 };
439
440 reset_memblock_regions();
441 memblock_reserve(r1.base, r1.size);
442 memblock_reserve(r2.base, r2.size);
443
444 assert(rgn->base == r1.base);
445 assert(rgn->size == r1.size);
446
447 assert(memblock.reserved.cnt == 1);
448 assert(memblock.reserved.total_size == r1.size);
449
450 return 0;
451}
452
453/*
454 * A simple test that tries to reserve the same memory block twice.
455 * The region counter and total size of reserved memory are expected to not
456 * be updated.
457 */
458static int memblock_reserve_twice_check(void)
459{
460 struct region r = {
461 .base = SZ_16K,
462 .size = SZ_2M
463 };
464
465 reset_memblock_regions();
466
467 memblock_reserve(r.base, r.size);
468 memblock_reserve(r.base, r.size);
469
470 assert(memblock.reserved.cnt == 1);
471 assert(memblock.reserved.total_size == r.size);
472
473 return 0;
474}
475
476static int memblock_reserve_checks(void)
477{
478 memblock_reserve_simple_check();
479 memblock_reserve_disjoint_check();
480 memblock_reserve_overlap_top_check();
481 memblock_reserve_overlap_bottom_check();
482 memblock_reserve_within_check();
483 memblock_reserve_twice_check();
484
485 return 0;
486}
487
488 /*
489 * A simple test that tries to remove the first entry of the array of
490 * available memory regions. By "removing" a region we mean overwriting it
491 * with the next region in memblock.memory. To check this is the case, the
492 * test adds two memory blocks and verifies that the value of the latter
493 * was used to erase r1 region. It also checks if the region counter and
494 * total size were updated to expected values.
495 */
496static int memblock_remove_simple_check(void)
497{
498 struct memblock_region *rgn;
499
500 rgn = &memblock.memory.regions[0];
501
502 struct region r1 = {
503 .base = SZ_2K,
504 .size = SZ_4K
505 };
506 struct region r2 = {
507 .base = SZ_128K,
508 .size = SZ_4M
509 };
510
511 reset_memblock_regions();
512 memblock_add(r1.base, r1.size);
513 memblock_add(r2.base, r2.size);
514 memblock_remove(r1.base, r1.size);
515
516 assert(rgn->base == r2.base);
517 assert(rgn->size == r2.size);
518
519 assert(memblock.memory.cnt == 1);
520 assert(memblock.memory.total_size == r2.size);
521
522 return 0;
523}
524
525 /*
526 * A test that tries to remove a region that was not registered as available
527 * memory (i.e. has no corresponding entry in memblock.memory). It verifies
528 * that array, regions counter and total size were not modified.
529 */
530static int memblock_remove_absent_check(void)
531{
532 struct memblock_region *rgn;
533
534 rgn = &memblock.memory.regions[0];
535
536 struct region r1 = {
537 .base = SZ_512K,
538 .size = SZ_4M
539 };
540 struct region r2 = {
541 .base = SZ_64M,
542 .size = SZ_1G
543 };
544
545 reset_memblock_regions();
546 memblock_add(r1.base, r1.size);
547 memblock_remove(r2.base, r2.size);
548
549 assert(rgn->base == r1.base);
550 assert(rgn->size == r1.size);
551
552 assert(memblock.memory.cnt == 1);
553 assert(memblock.memory.total_size == r1.size);
554
555 return 0;
556}
557
558/*
559 * A test that tries to remove a region which overlaps with the beginning of
560 * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
561 * checks if only the intersection of both regions is removed from the available
562 * memory pool. The test also checks if the regions counter and total size are
563 * updated to expected values.
564 */
565static int memblock_remove_overlap_top_check(void)
566{
567 struct memblock_region *rgn;
568 phys_addr_t r1_end, r2_end, total_size;
569
570 rgn = &memblock.memory.regions[0];
571
572 struct region r1 = {
573 .base = SZ_32M,
574 .size = SZ_32M
575 };
576 struct region r2 = {
577 .base = SZ_16M,
578 .size = SZ_32M
579 };
580
581 r1_end = r1.base + r1.size;
582 r2_end = r2.base + r2.size;
583 total_size = r1_end - r2_end;
584
585 reset_memblock_regions();
586 memblock_add(r1.base, r1.size);
587 memblock_remove(r2.base, r2.size);
588
589 assert(rgn->base == r1.base + r2.base);
590 assert(rgn->size == total_size);
591
592 assert(memblock.memory.cnt == 1);
593 assert(memblock.memory.total_size == total_size);
594
595 return 0;
596}
597
598/*
599 * A test that tries to remove a region which overlaps with the end of the
600 * first entry (that is r2.base < r1.base + r1.size). It checks if only the
601 * intersection of both regions is removed from the available memory pool.
602 * The test also checks if the regions counter and total size are updated to
603 * expected values.
604 */
605static int memblock_remove_overlap_bottom_check(void)
606{
607 struct memblock_region *rgn;
608 phys_addr_t total_size;
609
610 rgn = &memblock.memory.regions[0];
611
612 struct region r1 = {
613 .base = SZ_2M,
614 .size = SZ_64M
615 };
616 struct region r2 = {
617 .base = SZ_32M,
618 .size = SZ_256M
619 };
620
621 total_size = r2.base - r1.base;
622
623 reset_memblock_regions();
624 memblock_add(r1.base, r1.size);
625 memblock_remove(r2.base, r2.size);
626
627 assert(rgn->base == r1.base);
628 assert(rgn->size == total_size);
629
630 assert(memblock.memory.cnt == 1);
631 assert(memblock.memory.total_size == total_size);
632 return 0;
633}
634
635/*
636 * A test that tries to remove a region which is within the range of the
637 * already existing entry (that is
638 * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
639 * It checks if the region is split into two - one that ends at r2.base and
640 * second that starts at r2.base + size, with appropriate sizes. The test
641 * also checks if the region counter and total size were updated to
642 * expected values.
643 */
644static int memblock_remove_within_check(void)
645{
646 struct memblock_region *rgn1, *rgn2;
647 phys_addr_t r1_size, r2_size, total_size;
648
649 rgn1 = &memblock.memory.regions[0];
650 rgn2 = &memblock.memory.regions[1];
651
652 struct region r1 = {
653 .base = SZ_1M,
654 .size = SZ_32M
655 };
656 struct region r2 = {
657 .base = SZ_16M,
658 .size = SZ_1M
659 };
660
661 r1_size = r2.base - r1.base;
662 r2_size = (r1.base + r1.size) - (r2.base + r2.size);
663 total_size = r1_size + r2_size;
664
665 reset_memblock_regions();
666 memblock_add(r1.base, r1.size);
667 memblock_remove(r2.base, r2.size);
668
669 assert(rgn1->base == r1.base);
670 assert(rgn1->size == r1_size);
671
672 assert(rgn2->base == r2.base + r2.size);
673 assert(rgn2->size == r2_size);
674
675 assert(memblock.memory.cnt == 2);
676 assert(memblock.memory.total_size == total_size);
677
678 return 0;
679}
680
681static int memblock_remove_checks(void)
682{
683 memblock_remove_simple_check();
684 memblock_remove_absent_check();
685 memblock_remove_overlap_top_check();
686 memblock_remove_overlap_bottom_check();
687 memblock_remove_within_check();
688
689 return 0;
690}
691
692/*
693 * A simple test that tries to free a memory block that was marked earlier
694 * as reserved. By "freeing" a region we mean overwriting it with the next
695 * entry in memblock.reserved. To check this is the case, the test reserves
696 * two memory regions and verifies that the value of the latter was used to
697 * erase r1 region.
698 * The test also checks if the region counter and total size were updated.
699 */
700static int memblock_free_simple_check(void)
701{
702 struct memblock_region *rgn;
703
704 rgn = &memblock.reserved.regions[0];
705
706 struct region r1 = {
707 .base = SZ_4M,
708 .size = SZ_1M
709 };
710 struct region r2 = {
711 .base = SZ_8M,
712 .size = SZ_1M
713 };
714
715 reset_memblock_regions();
716 memblock_reserve(r1.base, r1.size);
717 memblock_reserve(r2.base, r2.size);
718 memblock_free((void *)r1.base, r1.size);
719
720 assert(rgn->base == r2.base);
721 assert(rgn->size == r2.size);
722
723 assert(memblock.reserved.cnt == 1);
724 assert(memblock.reserved.total_size == r2.size);
725
726 return 0;
727}
728
729 /*
730 * A test that tries to free a region that was not marked as reserved
731 * (i.e. has no corresponding entry in memblock.reserved). It verifies
732 * that array, regions counter and total size were not modified.
733 */
734static int memblock_free_absent_check(void)
735{
736 struct memblock_region *rgn;
737
738 rgn = &memblock.reserved.regions[0];
739
740 struct region r1 = {
741 .base = SZ_2M,
742 .size = SZ_8K
743 };
744 struct region r2 = {
745 .base = SZ_16M,
746 .size = SZ_128M
747 };
748
749 reset_memblock_regions();
750 memblock_reserve(r1.base, r1.size);
751 memblock_free((void *)r2.base, r2.size);
752
753 assert(rgn->base == r1.base);
754 assert(rgn->size == r1.size);
755
756 assert(memblock.reserved.cnt == 1);
757 assert(memblock.reserved.total_size == r1.size);
758
759 return 0;
760}
761
762/*
763 * A test that tries to free a region which overlaps with the beginning of
764 * the already existing entry r1 (that is r1.base < r2.base + r2.size). It
765 * checks if only the intersection of both regions is freed. The test also
766 * checks if the regions counter and total size are updated to expected
767 * values.
768 */
769static int memblock_free_overlap_top_check(void)
770{
771 struct memblock_region *rgn;
772 phys_addr_t total_size;
773
774 rgn = &memblock.reserved.regions[0];
775
776 struct region r1 = {
777 .base = SZ_8M,
778 .size = SZ_32M
779 };
780 struct region r2 = {
781 .base = SZ_1M,
782 .size = SZ_8M
783 };
784
785 total_size = (r1.size + r1.base) - (r2.base + r2.size);
786
787 reset_memblock_regions();
788 memblock_reserve(r1.base, r1.size);
789 memblock_free((void *)r2.base, r2.size);
790
791 assert(rgn->base == r2.base + r2.size);
792 assert(rgn->size == total_size);
793
794 assert(memblock.reserved.cnt == 1);
795 assert(memblock.reserved.total_size == total_size);
796
797 return 0;
798}
799
800/*
801 * A test that tries to free a region which overlaps with the end of the
802 * first entry (that is r2.base < r1.base + r1.size). It checks if only the
803 * intersection of both regions is freed. The test also checks if the
804 * regions counter and total size are updated to expected values.
805 */
806static int memblock_free_overlap_bottom_check(void)
807{
808 struct memblock_region *rgn;
809 phys_addr_t total_size;
810
811 rgn = &memblock.reserved.regions[0];
812
813 struct region r1 = {
814 .base = SZ_8M,
815 .size = SZ_32M
816 };
817 struct region r2 = {
818 .base = SZ_32M,
819 .size = SZ_32M
820 };
821
822 total_size = r2.base - r1.base;
823
824 reset_memblock_regions();
825 memblock_reserve(r1.base, r1.size);
826 memblock_free((void *)r2.base, r2.size);
827
828 assert(rgn->base == r1.base);
829 assert(rgn->size == total_size);
830
831 assert(memblock.reserved.cnt == 1);
832 assert(memblock.reserved.total_size == total_size);
833
834 return 0;
835}
836
837/*
838 * A test that tries to free a region which is within the range of the
839 * already existing entry (that is
840 * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)).
841 * It checks if the region is split into two - one that ends at r2.base and
842 * second that starts at r2.base + size, with appropriate sizes. It is
843 * expected that the region counter and total size fields were updated t
844 * reflect that change.
845 */
846static int memblock_free_within_check(void)
847{
848 struct memblock_region *rgn1, *rgn2;
849 phys_addr_t r1_size, r2_size, total_size;
850
851 rgn1 = &memblock.reserved.regions[0];
852 rgn2 = &memblock.reserved.regions[1];
853
854 struct region r1 = {
855 .base = SZ_1M,
856 .size = SZ_8M
857 };
858 struct region r2 = {
859 .base = SZ_4M,
860 .size = SZ_1M
861 };
862
863 r1_size = r2.base - r1.base;
864 r2_size = (r1.base + r1.size) - (r2.base + r2.size);
865 total_size = r1_size + r2_size;
866
867 reset_memblock_regions();
868 memblock_reserve(r1.base, r1.size);
869 memblock_free((void *)r2.base, r2.size);
870
871 assert(rgn1->base == r1.base);
872 assert(rgn1->size == r1_size);
873
874 assert(rgn2->base == r2.base + r2.size);
875 assert(rgn2->size == r2_size);
876
877 assert(memblock.reserved.cnt == 2);
878 assert(memblock.reserved.total_size == total_size);
879
880 return 0;
881}
882
883static int memblock_free_checks(void)
884{
885 memblock_free_simple_check();
886 memblock_free_absent_check();
887 memblock_free_overlap_top_check();
888 memblock_free_overlap_bottom_check();
889 memblock_free_within_check();
890
891 return 0;
892}
893
894int memblock_basic_checks(void)
895{
896 memblock_initialization_check();
897 memblock_add_checks();
898 memblock_reserve_checks();
899 memblock_remove_checks();
900 memblock_free_checks();
901
902 return 0;
903}