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). Expect to create a new entry. The region counter 310 * and total memory size are 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 * 335 * | +--+ +----------------+ | 336 * | |r1| | r2 | | 337 * +--------+--+------+----------------+--+ 338 * 339 * Expect to add two entries to the collection of reserved memory regions 340 * (memblock.reserved). The total size and region counter for 341 * memblock.reserved are updated. 342 */ 343 static int memblock_reserve_disjoint_check(void) 344 { 345 struct memblock_region *rgn1, *rgn2; 346 347 rgn1 = &memblock.reserved.regions[0]; 348 rgn2 = &memblock.reserved.regions[1]; 349 350 struct region r1 = { 351 .base = SZ_256M, 352 .size = SZ_16M 353 }; 354 struct region r2 = { 355 .base = SZ_512M, 356 .size = SZ_512M 357 }; 358 359 reset_memblock_regions(); 360 memblock_reserve(r1.base, r1.size); 361 memblock_reserve(r2.base, r2.size); 362 363 assert(rgn1->base == r1.base); 364 assert(rgn1->size == r1.size); 365 366 assert(rgn2->base == r2.base); 367 assert(rgn2->size == r2.size); 368 369 assert(memblock.reserved.cnt == 2); 370 assert(memblock.reserved.total_size == r1.size + r2.size); 371 372 return 0; 373 } 374 375 /* 376 * A test that tries to mark two memory blocks r1 and r2 as reserved, 377 * where r2 overlaps with the beginning of r1 (that is 378 * r1.base < r2.base + r2.size): 379 * 380 * | +--------------+--+--------------+ | 381 * | | r2 | | r1 | | 382 * +--+--------------+--+--------------+--+ 383 * ^ ^ 384 * | | 385 * | r1.base 386 * | 387 * r2.base 388 * 389 * Expect to merge two entries into one region that starts at r2.base and 390 * has size of two regions minus their intersection. The total size of the 391 * reserved memory is updated, and the region counter is not updated. 392 */ 393 static int memblock_reserve_overlap_top_check(void) 394 { 395 struct memblock_region *rgn; 396 phys_addr_t total_size; 397 398 rgn = &memblock.reserved.regions[0]; 399 400 struct region r1 = { 401 .base = SZ_1G, 402 .size = SZ_1G 403 }; 404 struct region r2 = { 405 .base = SZ_128M, 406 .size = SZ_1G 407 }; 408 409 total_size = (r1.base - r2.base) + r1.size; 410 411 reset_memblock_regions(); 412 memblock_reserve(r1.base, r1.size); 413 memblock_reserve(r2.base, r2.size); 414 415 assert(rgn->base == r2.base); 416 assert(rgn->size == total_size); 417 418 assert(memblock.reserved.cnt == 1); 419 assert(memblock.reserved.total_size == total_size); 420 421 return 0; 422 } 423 424 /* 425 * A test that tries to mark two memory blocks r1 and r2 as reserved, 426 * where r2 overlaps with the end of r1 (that is 427 * r2.base < r1.base + r1.size): 428 * 429 * | +--------------+--+--------------+ | 430 * | | r1 | | r2 | | 431 * +--+--------------+--+--------------+--+ 432 * ^ ^ 433 * | | 434 * | r2.base 435 * | 436 * r1.base 437 * 438 * Expect to merge two entries into one region that starts at r1.base and 439 * has size of two regions minus their intersection. The total size of the 440 * reserved memory is updated, and the region counter is not updated. 441 */ 442 static int memblock_reserve_overlap_bottom_check(void) 443 { 444 struct memblock_region *rgn; 445 phys_addr_t total_size; 446 447 rgn = &memblock.reserved.regions[0]; 448 449 struct region r1 = { 450 .base = SZ_2K, 451 .size = SZ_128K 452 }; 453 struct region r2 = { 454 .base = SZ_128K, 455 .size = SZ_128K 456 }; 457 458 total_size = (r2.base - r1.base) + r2.size; 459 460 reset_memblock_regions(); 461 memblock_reserve(r1.base, r1.size); 462 memblock_reserve(r2.base, r2.size); 463 464 assert(rgn->base == r1.base); 465 assert(rgn->size == total_size); 466 467 assert(memblock.reserved.cnt == 1); 468 assert(memblock.reserved.total_size == total_size); 469 470 return 0; 471 } 472 473 /* 474 * A test that tries to mark two memory blocks r1 and r2 as reserved, 475 * where r2 is within the range of r1 (that is 476 * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)): 477 * 478 * | +-----+--+---------------------------| 479 * | | |r2| r1 | 480 * +-+-----+--+---------------------------+ 481 * ^ ^ 482 * | | 483 * | r2.base 484 * | 485 * r1.base 486 * 487 * Expect to merge two entries into one region that stays the same. The 488 * counter and total size of available memory are not updated. 489 */ 490 static int memblock_reserve_within_check(void) 491 { 492 struct memblock_region *rgn; 493 494 rgn = &memblock.reserved.regions[0]; 495 496 struct region r1 = { 497 .base = SZ_1M, 498 .size = SZ_8M 499 }; 500 struct region r2 = { 501 .base = SZ_2M, 502 .size = SZ_64K 503 }; 504 505 reset_memblock_regions(); 506 memblock_reserve(r1.base, r1.size); 507 memblock_reserve(r2.base, r2.size); 508 509 assert(rgn->base == r1.base); 510 assert(rgn->size == r1.size); 511 512 assert(memblock.reserved.cnt == 1); 513 assert(memblock.reserved.total_size == r1.size); 514 515 return 0; 516 } 517 518 /* 519 * A simple test that tries to reserve the same memory block twice. 520 * Expect the region counter and total size of reserved memory to not 521 * be updated. 522 */ 523 static int memblock_reserve_twice_check(void) 524 { 525 struct region r = { 526 .base = SZ_16K, 527 .size = SZ_2M 528 }; 529 530 reset_memblock_regions(); 531 532 memblock_reserve(r.base, r.size); 533 memblock_reserve(r.base, r.size); 534 535 assert(memblock.reserved.cnt == 1); 536 assert(memblock.reserved.total_size == r.size); 537 538 return 0; 539 } 540 541 static int memblock_reserve_checks(void) 542 { 543 memblock_reserve_simple_check(); 544 memblock_reserve_disjoint_check(); 545 memblock_reserve_overlap_top_check(); 546 memblock_reserve_overlap_bottom_check(); 547 memblock_reserve_within_check(); 548 memblock_reserve_twice_check(); 549 550 return 0; 551 } 552 553 /* 554 * A simple test that tries to remove the first entry of the array of 555 * available memory regions. By "removing" a region we mean overwriting it 556 * with the next region in memblock.memory. To check this is the case, the 557 * test adds two memory blocks and verifies that the value of the latter 558 * was used to erase r1 region. It also checks if the region counter and 559 * total size were updated to expected values. 560 */ 561 static int memblock_remove_simple_check(void) 562 { 563 struct memblock_region *rgn; 564 565 rgn = &memblock.memory.regions[0]; 566 567 struct region r1 = { 568 .base = SZ_2K, 569 .size = SZ_4K 570 }; 571 struct region r2 = { 572 .base = SZ_128K, 573 .size = SZ_4M 574 }; 575 576 reset_memblock_regions(); 577 memblock_add(r1.base, r1.size); 578 memblock_add(r2.base, r2.size); 579 memblock_remove(r1.base, r1.size); 580 581 assert(rgn->base == r2.base); 582 assert(rgn->size == r2.size); 583 584 assert(memblock.memory.cnt == 1); 585 assert(memblock.memory.total_size == r2.size); 586 587 return 0; 588 } 589 590 /* 591 * A test that tries to remove a region that was not registered as available 592 * memory (i.e. has no corresponding entry in memblock.memory). It verifies 593 * that array, regions counter and total size were not modified. 594 */ 595 static int memblock_remove_absent_check(void) 596 { 597 struct memblock_region *rgn; 598 599 rgn = &memblock.memory.regions[0]; 600 601 struct region r1 = { 602 .base = SZ_512K, 603 .size = SZ_4M 604 }; 605 struct region r2 = { 606 .base = SZ_64M, 607 .size = SZ_1G 608 }; 609 610 reset_memblock_regions(); 611 memblock_add(r1.base, r1.size); 612 memblock_remove(r2.base, r2.size); 613 614 assert(rgn->base == r1.base); 615 assert(rgn->size == r1.size); 616 617 assert(memblock.memory.cnt == 1); 618 assert(memblock.memory.total_size == r1.size); 619 620 return 0; 621 } 622 623 /* 624 * A test that tries to remove a region which overlaps with the beginning of 625 * the already existing entry r1 (that is r1.base < r2.base + r2.size). It 626 * checks if only the intersection of both regions is removed from the available 627 * memory pool. The test also checks if the regions counter and total size are 628 * updated to expected values. 629 */ 630 static int memblock_remove_overlap_top_check(void) 631 { 632 struct memblock_region *rgn; 633 phys_addr_t r1_end, r2_end, total_size; 634 635 rgn = &memblock.memory.regions[0]; 636 637 struct region r1 = { 638 .base = SZ_32M, 639 .size = SZ_32M 640 }; 641 struct region r2 = { 642 .base = SZ_16M, 643 .size = SZ_32M 644 }; 645 646 r1_end = r1.base + r1.size; 647 r2_end = r2.base + r2.size; 648 total_size = r1_end - r2_end; 649 650 reset_memblock_regions(); 651 memblock_add(r1.base, r1.size); 652 memblock_remove(r2.base, r2.size); 653 654 assert(rgn->base == r1.base + r2.base); 655 assert(rgn->size == total_size); 656 657 assert(memblock.memory.cnt == 1); 658 assert(memblock.memory.total_size == total_size); 659 660 return 0; 661 } 662 663 /* 664 * A test that tries to remove a region which overlaps with the end of the 665 * first entry (that is r2.base < r1.base + r1.size). It checks if only the 666 * intersection of both regions is removed from the available memory pool. 667 * The test also checks if the regions counter and total size are updated to 668 * expected values. 669 */ 670 static int memblock_remove_overlap_bottom_check(void) 671 { 672 struct memblock_region *rgn; 673 phys_addr_t total_size; 674 675 rgn = &memblock.memory.regions[0]; 676 677 struct region r1 = { 678 .base = SZ_2M, 679 .size = SZ_64M 680 }; 681 struct region r2 = { 682 .base = SZ_32M, 683 .size = SZ_256M 684 }; 685 686 total_size = r2.base - r1.base; 687 688 reset_memblock_regions(); 689 memblock_add(r1.base, r1.size); 690 memblock_remove(r2.base, r2.size); 691 692 assert(rgn->base == r1.base); 693 assert(rgn->size == total_size); 694 695 assert(memblock.memory.cnt == 1); 696 assert(memblock.memory.total_size == total_size); 697 return 0; 698 } 699 700 /* 701 * A test that tries to remove a region which is within the range of the 702 * already existing entry (that is 703 * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)). 704 * It checks if the region is split into two - one that ends at r2.base and 705 * second that starts at r2.base + size, with appropriate sizes. The test 706 * also checks if the region counter and total size were updated to 707 * expected values. 708 */ 709 static int memblock_remove_within_check(void) 710 { 711 struct memblock_region *rgn1, *rgn2; 712 phys_addr_t r1_size, r2_size, total_size; 713 714 rgn1 = &memblock.memory.regions[0]; 715 rgn2 = &memblock.memory.regions[1]; 716 717 struct region r1 = { 718 .base = SZ_1M, 719 .size = SZ_32M 720 }; 721 struct region r2 = { 722 .base = SZ_16M, 723 .size = SZ_1M 724 }; 725 726 r1_size = r2.base - r1.base; 727 r2_size = (r1.base + r1.size) - (r2.base + r2.size); 728 total_size = r1_size + r2_size; 729 730 reset_memblock_regions(); 731 memblock_add(r1.base, r1.size); 732 memblock_remove(r2.base, r2.size); 733 734 assert(rgn1->base == r1.base); 735 assert(rgn1->size == r1_size); 736 737 assert(rgn2->base == r2.base + r2.size); 738 assert(rgn2->size == r2_size); 739 740 assert(memblock.memory.cnt == 2); 741 assert(memblock.memory.total_size == total_size); 742 743 return 0; 744 } 745 746 static int memblock_remove_checks(void) 747 { 748 memblock_remove_simple_check(); 749 memblock_remove_absent_check(); 750 memblock_remove_overlap_top_check(); 751 memblock_remove_overlap_bottom_check(); 752 memblock_remove_within_check(); 753 754 return 0; 755 } 756 757 /* 758 * A simple test that tries to free a memory block that was marked earlier 759 * as reserved. By "freeing" a region we mean overwriting it with the next 760 * entry in memblock.reserved. To check this is the case, the test reserves 761 * two memory regions and verifies that the value of the latter was used to 762 * erase r1 region. 763 * The test also checks if the region counter and total size were updated. 764 */ 765 static int memblock_free_simple_check(void) 766 { 767 struct memblock_region *rgn; 768 769 rgn = &memblock.reserved.regions[0]; 770 771 struct region r1 = { 772 .base = SZ_4M, 773 .size = SZ_1M 774 }; 775 struct region r2 = { 776 .base = SZ_8M, 777 .size = SZ_1M 778 }; 779 780 reset_memblock_regions(); 781 memblock_reserve(r1.base, r1.size); 782 memblock_reserve(r2.base, r2.size); 783 memblock_free((void *)r1.base, r1.size); 784 785 assert(rgn->base == r2.base); 786 assert(rgn->size == r2.size); 787 788 assert(memblock.reserved.cnt == 1); 789 assert(memblock.reserved.total_size == r2.size); 790 791 return 0; 792 } 793 794 /* 795 * A test that tries to free a region that was not marked as reserved 796 * (i.e. has no corresponding entry in memblock.reserved). It verifies 797 * that array, regions counter and total size were not modified. 798 */ 799 static int memblock_free_absent_check(void) 800 { 801 struct memblock_region *rgn; 802 803 rgn = &memblock.reserved.regions[0]; 804 805 struct region r1 = { 806 .base = SZ_2M, 807 .size = SZ_8K 808 }; 809 struct region r2 = { 810 .base = SZ_16M, 811 .size = SZ_128M 812 }; 813 814 reset_memblock_regions(); 815 memblock_reserve(r1.base, r1.size); 816 memblock_free((void *)r2.base, r2.size); 817 818 assert(rgn->base == r1.base); 819 assert(rgn->size == r1.size); 820 821 assert(memblock.reserved.cnt == 1); 822 assert(memblock.reserved.total_size == r1.size); 823 824 return 0; 825 } 826 827 /* 828 * A test that tries to free a region which overlaps with the beginning of 829 * the already existing entry r1 (that is r1.base < r2.base + r2.size). It 830 * checks if only the intersection of both regions is freed. The test also 831 * checks if the regions counter and total size are updated to expected 832 * values. 833 */ 834 static int memblock_free_overlap_top_check(void) 835 { 836 struct memblock_region *rgn; 837 phys_addr_t total_size; 838 839 rgn = &memblock.reserved.regions[0]; 840 841 struct region r1 = { 842 .base = SZ_8M, 843 .size = SZ_32M 844 }; 845 struct region r2 = { 846 .base = SZ_1M, 847 .size = SZ_8M 848 }; 849 850 total_size = (r1.size + r1.base) - (r2.base + r2.size); 851 852 reset_memblock_regions(); 853 memblock_reserve(r1.base, r1.size); 854 memblock_free((void *)r2.base, r2.size); 855 856 assert(rgn->base == r2.base + r2.size); 857 assert(rgn->size == total_size); 858 859 assert(memblock.reserved.cnt == 1); 860 assert(memblock.reserved.total_size == total_size); 861 862 return 0; 863 } 864 865 /* 866 * A test that tries to free a region which overlaps with the end of the 867 * first entry (that is r2.base < r1.base + r1.size). It checks if only the 868 * intersection of both regions is freed. The test also checks if the 869 * regions counter and total size are updated to expected values. 870 */ 871 static int memblock_free_overlap_bottom_check(void) 872 { 873 struct memblock_region *rgn; 874 phys_addr_t total_size; 875 876 rgn = &memblock.reserved.regions[0]; 877 878 struct region r1 = { 879 .base = SZ_8M, 880 .size = SZ_32M 881 }; 882 struct region r2 = { 883 .base = SZ_32M, 884 .size = SZ_32M 885 }; 886 887 total_size = r2.base - r1.base; 888 889 reset_memblock_regions(); 890 memblock_reserve(r1.base, r1.size); 891 memblock_free((void *)r2.base, r2.size); 892 893 assert(rgn->base == r1.base); 894 assert(rgn->size == total_size); 895 896 assert(memblock.reserved.cnt == 1); 897 assert(memblock.reserved.total_size == total_size); 898 899 return 0; 900 } 901 902 /* 903 * A test that tries to free a region which is within the range of the 904 * already existing entry (that is 905 * (r1.base < r2.base) && (r2.base + r2.size < r1.base + r1.size)). 906 * It checks if the region is split into two - one that ends at r2.base and 907 * second that starts at r2.base + size, with appropriate sizes. It is 908 * expected that the region counter and total size fields were updated t 909 * reflect that change. 910 */ 911 static int memblock_free_within_check(void) 912 { 913 struct memblock_region *rgn1, *rgn2; 914 phys_addr_t r1_size, r2_size, total_size; 915 916 rgn1 = &memblock.reserved.regions[0]; 917 rgn2 = &memblock.reserved.regions[1]; 918 919 struct region r1 = { 920 .base = SZ_1M, 921 .size = SZ_8M 922 }; 923 struct region r2 = { 924 .base = SZ_4M, 925 .size = SZ_1M 926 }; 927 928 r1_size = r2.base - r1.base; 929 r2_size = (r1.base + r1.size) - (r2.base + r2.size); 930 total_size = r1_size + r2_size; 931 932 reset_memblock_regions(); 933 memblock_reserve(r1.base, r1.size); 934 memblock_free((void *)r2.base, r2.size); 935 936 assert(rgn1->base == r1.base); 937 assert(rgn1->size == r1_size); 938 939 assert(rgn2->base == r2.base + r2.size); 940 assert(rgn2->size == r2_size); 941 942 assert(memblock.reserved.cnt == 2); 943 assert(memblock.reserved.total_size == total_size); 944 945 return 0; 946 } 947 948 static int memblock_free_checks(void) 949 { 950 memblock_free_simple_check(); 951 memblock_free_absent_check(); 952 memblock_free_overlap_top_check(); 953 memblock_free_overlap_bottom_check(); 954 memblock_free_within_check(); 955 956 return 0; 957 } 958 959 int memblock_basic_checks(void) 960 { 961 memblock_initialization_check(); 962 memblock_add_checks(); 963 memblock_reserve_checks(); 964 memblock_remove_checks(); 965 memblock_free_checks(); 966 967 return 0; 968 } 969