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 * It checks if a new entry was created and if region counter and total memory 30 * were correctly 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 * It checks if the new entry, region counter and total memory size have 59 * expected values. 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. 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 */ 94 static 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 */ 133 static 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 */ 172 static 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 */ 210 static 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 */ 242 static 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 260 static 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 */ 279 static 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 */ 305 static 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 */ 346 static 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 */ 386 static 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 */ 425 static 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 */ 458 static 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 476 static 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 */ 496 static 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 */ 530 static 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 */ 565 static 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 */ 605 static 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 */ 644 static 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 681 static 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 */ 700 static 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 */ 734 static 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 */ 769 static 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 */ 806 static 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 */ 846 static 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 883 static 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 894 int 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 } 904