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