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