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