1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2026 Google LLC 4 * Author: Vincent Donnefort <vdonnefort@google.com> 5 * 6 * This heap allocator manages a reserved VA space range, dynamically mapping 7 * and unmapping physical pages on-demand to minimise the pKVM hypervisor 8 * footprint. As memory is reclaimed and relinquished to the host, unmapped 9 * holes are introduced within the VA space. To prevent orphans mapped regions, 10 * neighboring unused chunks cannot be merged if they are separated by an 11 * unmapped region. 12 * 13 */ 14 15 #include <nvhe/alloc.h> 16 #include <nvhe/mem_protect.h> 17 #include <nvhe/mm.h> 18 #include <nvhe/spinlock.h> 19 20 #include <linux/build_bug.h> 21 #include <linux/hash.h> 22 23 /* 24 * A minimum of 16 bytes allows us to comply with the alignment requirement for 25 * FPSIMD registers that are part of struct pkvm_hyp_vcpu. 26 * 27 * It also must be a power of two. 28 */ 29 #define MIN_ALLOC_SIZE 16UL 30 31 /** 32 * struct chunk_hdr - Chunk header 33 * @next: offset from this chunk header to the next one. 34 * @prev: offset from this chunk header to the previous one. 35 * @__unmapped: Internal field containing the offset to the unmapped page 36 * boundary, multiplexed with the allocation state flag. 37 * @hash: Hash computed over the chunk header. 38 */ 39 struct chunk_hdr { 40 u32 next; 41 u32 prev; 42 #define USED_BIT_MASK 1U 43 u32 __unmapped; 44 u32 hash; 45 char data[]; 46 } __aligned(MIN_ALLOC_SIZE); 47 48 /** 49 * struct hyp_allocator - Heap allocator 50 * @start: Start in the allocator's reserved virtual address range. 51 * @end: End in the allocator's reserved virtual address range. 52 * @last_used: Pointer to the end of the last used chunk. This is 53 * necessary for the last chunk in the list as the 54 * allocated size of a chunk is derived from the next one. 55 * @first_unmapped: Pointer to the first unmapped page in the 56 * allocator's range. This is only necessary and 57 * updated when no chunk is in the list. 58 * @head: Head of the chunk list. 59 * @tail: Tail of the chunk list. 60 * @mc: Memcache containing pre-allocated pages for mapping. 61 * @lock: Spinlock protecting the allocator state. 62 * @errno: Per-CPU error code for allocation failures. 63 * @topup_needed: Per-CPU page counter needed to top-up the memcache. 64 */ 65 struct hyp_allocator { 66 void *start; 67 void *end; 68 void *last_used; 69 void *first_unmapped; 70 struct chunk_hdr *head; 71 struct chunk_hdr *tail; 72 struct kvm_hyp_memcache mc; 73 hyp_spinlock_t lock; 74 int __percpu *errno; 75 u32 __percpu *topup_needed; 76 }; 77 78 static u32 chunk_hash_compute(const struct chunk_hdr *chunk) 79 { 80 u32 hash = 0; 81 82 BUILD_BUG_ON(sizeof(*chunk) != 16); 83 84 hash ^= hash_64(*(const u64 *)chunk, 32); 85 hash ^= hash_32(chunk->__unmapped, 32); 86 return hash; 87 } 88 89 static void chunk_set_hash(struct chunk_hdr *chunk) 90 { 91 if (chunk) 92 chunk->hash = chunk_hash_compute(chunk); 93 } 94 95 static void chunk_check_hash(const struct chunk_hdr *chunk) 96 { 97 if (chunk) 98 WARN_ON(chunk->hash != chunk_hash_compute(chunk)); 99 } 100 101 static bool chunk_is_used(const struct chunk_hdr *chunk) 102 { 103 return !!(chunk->__unmapped & USED_BIT_MASK); 104 } 105 106 static void chunk_set_used(struct chunk_hdr *chunk) 107 { 108 chunk->__unmapped |= USED_BIT_MASK; 109 } 110 111 static void chunk_set_unused(struct chunk_hdr *chunk) 112 { 113 chunk->__unmapped &= ~USED_BIT_MASK; 114 } 115 116 static void *chunk_unmapped(const struct chunk_hdr *chunk) 117 { 118 u32 offset = chunk->__unmapped & ~USED_BIT_MASK; 119 120 if (!offset) 121 return NULL; 122 123 return (void *)chunk + offset; 124 } 125 126 static void __chunk_set_unmapped(struct chunk_hdr *chunk, u32 unmapped) 127 { 128 chunk->__unmapped = unmapped | (chunk_is_used(chunk) ? USED_BIT_MASK : 0); 129 } 130 131 static void chunk_set_unmapped(struct chunk_hdr *chunk, void *unmapped) 132 { 133 WARN_ON(!PAGE_ALIGNED(unmapped)); 134 135 if (unmapped) { 136 WARN_ON((void *)chunk > unmapped); 137 __chunk_set_unmapped(chunk, unmapped - (void *)chunk); 138 } else { 139 __chunk_set_unmapped(chunk, 0); 140 } 141 } 142 143 static void *chunk_data(const struct chunk_hdr *chunk) 144 { 145 return (void *)&chunk->data; 146 } 147 148 static struct chunk_hdr *__chunk_next(const struct chunk_hdr *chunk) 149 { 150 if (!chunk->next) 151 return NULL; 152 153 return (struct chunk_hdr *)((void *)chunk + chunk->next); 154 } 155 156 static struct chunk_hdr *__chunk_prev(const struct chunk_hdr *chunk) 157 { 158 if (!chunk->prev) 159 return NULL; 160 161 return (struct chunk_hdr *)((void *)chunk - chunk->prev); 162 } 163 164 static void chunk_set_next(struct chunk_hdr *chunk, struct chunk_hdr *next) 165 { 166 if (!chunk) 167 return; 168 169 if (next) { 170 WARN_ON(chunk > next); 171 chunk->next = (void *)next - (void *)chunk; 172 } else { 173 chunk->next = 0; 174 } 175 } 176 177 static void chunk_set_prev(struct chunk_hdr *chunk, struct chunk_hdr *prev) 178 { 179 if (!chunk) 180 return; 181 182 if (prev) { 183 WARN_ON(chunk < prev); 184 chunk->prev = (void *)chunk - (void *)prev; 185 } else { 186 chunk->prev = 0; 187 } 188 } 189 190 static struct chunk_hdr *chunk_get_next(const struct chunk_hdr *chunk) 191 { 192 struct chunk_hdr *next = __chunk_next(chunk); 193 194 chunk_check_hash(next); 195 return next; 196 } 197 198 static struct chunk_hdr *chunk_get_prev(const struct chunk_hdr *chunk) 199 { 200 struct chunk_hdr *prev = __chunk_prev(chunk); 201 202 chunk_check_hash(prev); 203 return prev; 204 } 205 206 static struct chunk_hdr *chunk_get(struct chunk_hdr *chunk) 207 { 208 chunk_check_hash(chunk); 209 return chunk; 210 } 211 212 #define chunk_hdr_size() \ 213 offsetof(struct chunk_hdr, data) 214 215 #define chunk_min_size() \ 216 (chunk_hdr_size() + MIN_ALLOC_SIZE) 217 218 static size_t chunk_data_size(const struct chunk_hdr *chunk, struct hyp_allocator *allocator) 219 { 220 struct chunk_hdr *next = chunk_get_next(chunk); 221 void *end; 222 223 if (next) 224 end = (void *)next; 225 else 226 end = allocator->end; 227 228 return end - chunk_data(chunk); 229 } 230 231 static size_t chunk_mapped_data_size(const struct chunk_hdr *chunk, struct hyp_allocator *allocator) 232 { 233 void *unmapped = chunk_unmapped(chunk); 234 235 if (!unmapped) 236 return chunk_data_size(chunk, allocator); 237 238 return unmapped - chunk_data(chunk); 239 } 240 241 static size_t chunk_used_size(const struct chunk_hdr *chunk, struct hyp_allocator *allocator) 242 { 243 struct chunk_hdr *next = chunk_get_next(chunk); 244 245 if (!chunk_is_used(chunk)) 246 return 0; 247 248 if (next) 249 return chunk_mapped_data_size(chunk, allocator); 250 251 return allocator->last_used - chunk_data(chunk); 252 } 253 254 static void chunk_list_insert(struct chunk_hdr *chunk, struct chunk_hdr *prev) 255 { 256 struct chunk_hdr *next = NULL; 257 258 WARN_ON(!chunk); 259 260 if (prev) { 261 next = chunk_get_next(prev); 262 chunk_set_next(prev, chunk); 263 chunk_set_hash(prev); 264 } 265 266 if (next) { 267 chunk_set_prev(next, chunk); 268 chunk_set_hash(next); 269 } 270 271 chunk_set_next(chunk, next); 272 chunk_set_prev(chunk, prev); 273 } 274 275 static void chunk_list_del(struct chunk_hdr *chunk) 276 { 277 struct chunk_hdr *prev, *next; 278 279 WARN_ON(!chunk); 280 281 prev = chunk_get_prev(chunk); 282 next = chunk_get_next(chunk); 283 284 if (prev) { 285 chunk_set_next(prev, next); 286 chunk_set_hash(prev); 287 } 288 289 if (next) { 290 chunk_set_prev(next, prev); 291 chunk_set_hash(next); 292 } 293 } 294 295 /* 296 * Return a fixup start address for chunk creation. It makes sure the chunk 297 * header doesn't cross any page boundary and that it leaves enough space at the 298 * start of page. This is intended to prevent orphan mapped regions during chunk 299 * memory reclaim 300 */ 301 static void *chunk_start(void *start) 302 { 303 void *page = PTR_ALIGN(start, PAGE_SIZE); 304 305 if (page - start < chunk_hdr_size()) 306 return page; 307 308 page = PTR_ALIGN_DOWN(start, PAGE_SIZE); 309 if (start - page < chunk_min_size()) 310 return page + chunk_min_size(); 311 312 return start; 313 } 314 315 static void hyp_allocator_set_errno(struct hyp_allocator *allocator, int errno) 316 { 317 *this_cpu_ptr(allocator->errno) = errno; 318 } 319 320 static int hyp_allocator_errno(struct hyp_allocator *allocator) 321 { 322 int *errno = this_cpu_ptr(allocator->errno); 323 int ret = *errno; 324 325 *errno = 0; 326 327 return ret; 328 } 329 330 static int hyp_allocator_map(struct hyp_allocator *allocator, struct chunk_hdr *chunk, 331 struct chunk_hdr *next, 332 void *addr, void *end) 333 { 334 void *unmapped = chunk ? chunk_unmapped(chunk) : allocator->first_unmapped; 335 void *unmapped_end = next ?: allocator->end; 336 337 /* 338 * hyp_allocator_can_create_chunk() already validates addr/end 339 * belong to the chunk. 340 */ 341 WARN_ON(end <= addr); 342 343 /* The chunk does not span an unmapped region */ 344 if (!unmapped) 345 return 0; 346 347 while (unmapped < end) { 348 void *page = pop_hyp_memcache(&allocator->mc, hyp_phys_to_virt); 349 int ret; 350 351 if (!page) { 352 end = PTR_ALIGN(end, PAGE_SIZE); 353 *this_cpu_ptr(allocator->topup_needed) = 354 (unsigned long)(end - unmapped) >> PAGE_SHIFT; 355 return -ENOMEM; 356 } 357 358 ret = pkvm_map_private_va_range(unmapped, hyp_virt_to_phys(page), PAGE_SIZE); 359 if (ret) { 360 push_hyp_memcache(&allocator->mc, page, hyp_virt_to_phys); 361 return ret; 362 } 363 364 unmapped += PAGE_SIZE; 365 366 /* 367 * Reset the unmap field if we've reached the next chunk or the 368 * allocator boundary. Chunks are always installed to cover a 369 * mapped region followed by an unmapped one. Therefore, we 370 * expect next to be PAGE_ALIGNED. 371 */ 372 WARN_ON(!PAGE_ALIGNED(unmapped_end)); 373 if (unmapped == unmapped_end) 374 unmapped = NULL; 375 376 if (chunk) { 377 chunk_set_unmapped(chunk, unmapped); 378 chunk_set_hash(chunk); 379 } else { 380 allocator->first_unmapped = unmapped; 381 } 382 383 if (!unmapped) 384 break; 385 } 386 387 return 0; 388 } 389 390 static void hyp_allocator_unmap(struct hyp_allocator *allocator, struct chunk_hdr *chunk, 391 void *addr, void *end) 392 { 393 void *unmap = addr; 394 395 /* 396 * hyp_allocator_chunk_reclaimable() already computes valid addr/end, no 397 * need to check them again 398 */ 399 WARN_ON(end <= addr); 400 401 while (unmap < end) { 402 phys_addr_t pa = pkvm_private_va_range_pa((void *)unmap); 403 void *page = hyp_phys_to_virt(pa); 404 405 push_hyp_memcache(&allocator->mc, page, hyp_virt_to_phys); 406 unmap += PAGE_SIZE; 407 } 408 409 pkvm_remove_mappings(addr, end); 410 411 if (chunk) { 412 chunk_set_unmapped(chunk, addr); 413 chunk_set_hash(chunk); 414 } else { 415 allocator->first_unmapped = addr; 416 } 417 } 418 419 static bool hyp_allocator_can_create_chunk(struct hyp_allocator *allocator, 420 const struct chunk_hdr *prev, 421 const struct chunk_hdr *next, 422 void *addr, void *end) 423 { 424 void *page, *unmapped; 425 426 if (addr < allocator->start || end > allocator->end) 427 return false; 428 429 /* First chunk created must be installed at allocator->start */ 430 if (!prev) 431 return addr == allocator->start; 432 433 /* Must not overwrite the next chunk */ 434 if (next && end > (void *)next) 435 return false; 436 437 /* Must not overwrite the previous chunk */ 438 if (addr < (chunk_data(prev) + chunk_used_size(prev, allocator))) 439 return false; 440 441 /* Header must not cross page boundaries */ 442 page = PTR_ALIGN(addr, PAGE_SIZE); 443 if (page != addr && (page - addr) < chunk_hdr_size()) 444 return false; 445 446 /* Must leave a minimum distance from a page-start to maximise reclaim */ 447 page = PTR_ALIGN_DOWN(addr, PAGE_SIZE); 448 if (page != addr && (addr - page) < chunk_min_size()) 449 return false; 450 451 unmapped = chunk_unmapped(prev); 452 if (!unmapped) 453 return true; 454 455 /* Must never create an orphan mapped region */ 456 if (addr > unmapped) 457 return false; 458 459 return true; 460 } 461 462 /* 463 * Tries to create a new chunk in the allocator whose header starts at @addr and 464 * whose data finishes at @end. 465 */ 466 static struct chunk_hdr *hyp_allocator_create_chunk(struct hyp_allocator *allocator, 467 struct chunk_hdr *prev, void *addr, 468 void *end, bool used) 469 { 470 struct chunk_hdr *next, *chunk = addr; 471 void *unmapped; 472 int ret; 473 474 if (end > allocator->end) 475 return ERR_PTR(-E2BIG); 476 477 next = prev ? chunk_get_next(prev) : NULL; 478 if (!hyp_allocator_can_create_chunk(allocator, prev, next, addr, end)) 479 return ERR_PTR(-EINVAL); 480 481 ret = hyp_allocator_map(allocator, prev, next, addr, end); 482 if (ret) 483 return ERR_PTR(ret); 484 485 memset(chunk, 0, sizeof(*chunk)); 486 if (used) 487 chunk_set_used(chunk); 488 else 489 chunk_set_unused(chunk); 490 491 /* First chunk, first allocation */ 492 if (!prev) { 493 chunk_set_unmapped(chunk, allocator->first_unmapped); 494 chunk_list_insert(chunk, NULL); 495 chunk_set_hash(chunk); 496 497 allocator->last_used = end; 498 allocator->head = allocator->tail = chunk; 499 return chunk; 500 } 501 502 /* Last chunk in the list */ 503 if (!next) { 504 allocator->last_used = end; 505 allocator->tail = chunk; 506 } 507 508 /* Inherit prev's unmapped region */ 509 unmapped = chunk_unmapped(prev); 510 chunk_set_unmapped(chunk, unmapped); 511 chunk_list_insert(chunk, prev); 512 chunk_set_hash(chunk); 513 514 chunk_set_unmapped(prev, NULL); 515 chunk_set_hash(prev); 516 517 return chunk; 518 } 519 520 static bool hyp_allocator_can_destroy_chunk(const struct chunk_hdr *prev, 521 const struct chunk_hdr *next, 522 const struct chunk_hdr *chunk) 523 { 524 if (chunk_is_used(chunk)) 525 return false; 526 527 /* Can't merge down unless we are the last one in the list */ 528 if (next && chunk_is_used(prev)) 529 return false; 530 531 /* Must never create an orphan mapped region */ 532 if (chunk_unmapped(prev)) 533 return false; 534 535 return true; 536 } 537 538 static int hyp_allocator_destroy_chunk(struct hyp_allocator *allocator, 539 struct chunk_hdr *prev, 540 struct chunk_hdr *chunk) 541 { 542 struct chunk_hdr *next = chunk_get_next(chunk); 543 544 if (!hyp_allocator_can_destroy_chunk(prev, next, chunk)) 545 return -EINVAL; 546 547 /* Last chunk in the list */ 548 if (!next) { 549 allocator->last_used = chunk; 550 allocator->tail = prev; 551 } 552 553 chunk_set_unmapped(prev, chunk_unmapped(chunk)); 554 chunk_set_hash(prev); 555 chunk_list_del(chunk); 556 557 return 0; 558 } 559 560 /* 561 * Return the best unused chunk for recycling, that is the smallest chunk 562 * fitting the allocation which needs to use the least unmapped region. 563 */ 564 static struct chunk_hdr *hyp_allocator_find_efficient_chunk(struct hyp_allocator *allocator, 565 size_t size) 566 { 567 struct chunk_hdr *chunk, *best_chunk = NULL; 568 size_t best_data_size = SIZE_MAX; 569 size_t best_missing = SIZE_MAX; 570 571 chunk = allocator->head; 572 while (chunk) { 573 size_t missing, mapped, data_size; 574 575 if (chunk_is_used(chunk)) 576 goto next; 577 578 data_size = chunk_data_size(chunk, allocator); 579 if (data_size < size) 580 goto next; 581 582 mapped = chunk_mapped_data_size(chunk, allocator); 583 missing = (size > mapped) ? DIV_ROUND_UP(size - mapped, PAGE_SIZE) : 0; 584 if (missing > best_missing) 585 goto next; 586 587 if (missing == best_missing && data_size >= best_data_size) 588 goto next; 589 590 best_missing = missing; 591 best_data_size = data_size; 592 best_chunk = chunk; 593 594 next: 595 chunk = chunk_get_next(chunk); 596 } 597 598 return best_chunk; 599 } 600 601 static struct chunk_hdr *hyp_allocator_reuse_chunk(struct hyp_allocator *allocator, 602 struct chunk_hdr *chunk, size_t size) 603 { 604 struct chunk_hdr *next = chunk_get_next(chunk); 605 void *start, *end, *split, *split_end; 606 int ret; 607 608 start = chunk_data(chunk); 609 end = start + size; 610 611 /* Last chunk in the list, no need to split */ 612 if (!next) { 613 split = split_end = NULL; 614 allocator->last_used = chunk_data(chunk) + size; 615 } else { 616 split = chunk_start(end); 617 split_end = split + chunk_min_size(); 618 619 if (!hyp_allocator_can_create_chunk(allocator, chunk, next, split, split_end)) 620 split = split_end = NULL; 621 } 622 623 /* Batch the mapping of the reused chunk and the split */ 624 ret = hyp_allocator_map(allocator, chunk, next, chunk_data(chunk), split ? split_end : end); 625 if (ret) 626 return ERR_PTR(ret); 627 628 if (split) 629 WARN_ON(IS_ERR_OR_NULL( 630 hyp_allocator_create_chunk(allocator, chunk, split, split_end, false))); 631 632 chunk_set_used(chunk); 633 chunk_set_hash(chunk); 634 635 return chunk; 636 } 637 638 static struct chunk_hdr *hyp_allocator_alloc_chunk(struct hyp_allocator *allocator, size_t size) 639 { 640 struct chunk_hdr *chunk; 641 void *start, *end; 642 643 /* First allocation */ 644 if (!allocator->head) { 645 start = allocator->start; 646 end = start + chunk_hdr_size() + size; 647 return hyp_allocator_create_chunk(allocator, NULL, start, end, true); 648 } 649 650 chunk = hyp_allocator_find_efficient_chunk(allocator, size); 651 652 /* Nothing found, create a new chunk at the end in the list */ 653 if (!chunk) { 654 start = chunk_start(chunk_data(allocator->tail) + 655 chunk_used_size(allocator->tail, allocator)); 656 end = start + chunk_hdr_size() + size; 657 return hyp_allocator_create_chunk(allocator, allocator->tail, start, end, true); 658 } 659 660 return hyp_allocator_reuse_chunk(allocator, chunk, size); 661 } 662 663 static void *hyp_allocator_alloc(struct hyp_allocator *allocator, size_t size) 664 { 665 struct chunk_hdr *chunk; 666 667 size = max(size, MIN_ALLOC_SIZE); 668 669 /* Ensure we do not overflow ALIGN(MIN_ALLOC_SIZE) */ 670 if (size > U32_MAX) { 671 hyp_allocator_set_errno(allocator, -E2BIG); 672 return NULL; 673 } 674 675 size = ALIGN(size, MIN_ALLOC_SIZE); 676 if (size > (allocator->end - allocator->start - chunk_hdr_size())) { 677 hyp_allocator_set_errno(allocator, -E2BIG); 678 return NULL; 679 } 680 681 scoped_guard(hyp_spinlock, &allocator->lock) { 682 chunk = hyp_allocator_alloc_chunk(allocator, size); 683 if (IS_ERR_OR_NULL(chunk)) { 684 hyp_allocator_set_errno(allocator, 685 IS_ERR(chunk) ? PTR_ERR(chunk) : -EINVAL); 686 return NULL; 687 } 688 } 689 690 memset(chunk_data(chunk), 0, size); 691 return chunk_data(chunk); 692 } 693 694 static void hyp_allocator_free(struct hyp_allocator *allocator, void *data) 695 { 696 struct chunk_hdr *chunk, *next, *prev; 697 698 if (!data) 699 return; 700 701 WARN_ON(!IS_ALIGNED((unsigned long)data, MIN_ALLOC_SIZE)); 702 WARN_ON(data >= allocator->end || data < allocator->start + chunk_hdr_size()); 703 704 guard(hyp_spinlock)(&allocator->lock); 705 706 chunk = chunk_get(container_of(data, struct chunk_hdr, data)); 707 WARN_ON(!chunk_is_used(chunk)); 708 chunk_set_unused(chunk); 709 chunk_set_hash(chunk); 710 711 next = chunk_get_next(chunk); 712 if (next) 713 hyp_allocator_destroy_chunk(allocator, chunk, next); 714 715 prev = chunk_get_prev(chunk); 716 if (prev) 717 hyp_allocator_destroy_chunk(allocator, prev, chunk); 718 } 719 720 static unsigned long hyp_allocator_chunk_reclaimable(struct hyp_allocator *allocator, 721 const struct chunk_hdr *chunk, 722 u64 *__addr, u64 *__end) 723 { 724 struct chunk_hdr *next; 725 void *addr, *end; 726 727 /* Last chunk in the allocator */ 728 if (chunk == allocator->head && chunk == allocator->tail && !chunk_is_used(chunk)) { 729 addr = (void *)chunk; 730 end = chunk_unmapped(chunk); 731 if (!end) 732 end = allocator->end; 733 goto end; 734 } 735 736 next = chunk_get_next(chunk); 737 738 /* Last chunk in the list we can reclaim, even if used */ 739 if (!next) { 740 addr = chunk_data(chunk) + chunk_used_size(chunk, allocator); 741 addr = PTR_ALIGN(addr, PAGE_SIZE); 742 end = chunk_unmapped(chunk); 743 if (!end) 744 end = allocator->end; 745 goto end; 746 } 747 748 if (chunk_is_used(chunk)) 749 return 0; 750 751 addr = PTR_ALIGN(chunk_data(chunk), PAGE_SIZE); 752 end = chunk_unmapped(chunk); 753 if (!end) 754 end = PTR_ALIGN_DOWN(next, PAGE_SIZE); 755 756 end: 757 if (addr >= end) 758 return 0; 759 760 if (__end) 761 *__end = (u64)end; 762 if (__addr) 763 *__addr = (u64)addr; 764 765 return (end - addr) >> PAGE_SHIFT; 766 } 767 768 static void hyp_allocator_reclaim_chunk(struct hyp_allocator *allocator, struct chunk_hdr *chunk, 769 void *addr, void *end) 770 { 771 struct chunk_hdr *next; 772 773 WARN_ON(end <= addr); 774 775 /* We are about to destroy the last chunk in the allocator */ 776 if (addr == allocator->start) { 777 allocator->tail = allocator->head = chunk = NULL; 778 goto unmap; 779 } 780 781 next = chunk_get_next(chunk); 782 783 /* 784 * Split the reclaimed chunk at the next page boundary, 785 * this ensures no orphan mapped region is created. Splitting at the page boundary is always 786 * possible because chunks always leave a minimum distance to the page start. 787 * 788 * +--------------+ 789 * |______________| 790 * |______________|<- Next chunk 791 * |_ _ _ __ _ _ _| 792 * | |<- Page-aligned split 793 * +--------------+ 794 * +--------------+ 795 * | | 796 * | |<- Page reclaimed 797 * | | 798 * | | 799 * +--------------+ 800 * +--------------+ 801 * | | 802 * |______________| 803 * |______________|<- Chunk to split 804 * | | 805 * +--------------+ 806 */ 807 if (next && !chunk_unmapped(chunk) && next != end) 808 WARN_ON(IS_ERR_OR_NULL(hyp_allocator_create_chunk(allocator, chunk, end, next, 809 false))); 810 unmap: 811 hyp_allocator_unmap(allocator, chunk, addr, end); 812 } 813 814 /* 815 * Return the best reclaimable chunk which is the highest chunk in the list 816 * with the biggest reclaimable region. 817 */ 818 static struct chunk_hdr *hyp_allocator_find_reclaimable_chunk(struct hyp_allocator *allocator, 819 u64 *addr, u64 *end) 820 { 821 struct chunk_hdr *chunk, *best_chunk = NULL; 822 unsigned long best_reclaimable = 0; 823 824 chunk = allocator->head; 825 while (chunk) { 826 u64 __addr, __end; 827 unsigned long reclaimable = hyp_allocator_chunk_reclaimable(allocator, chunk, 828 &__addr, &__end); 829 830 /* Favour the top biggest chunks */ 831 if (reclaimable && reclaimable >= best_reclaimable) { 832 best_reclaimable = reclaimable; 833 best_chunk = chunk; 834 *addr = __addr; 835 *end = __end; 836 } 837 838 chunk = chunk_get_next(chunk); 839 } 840 841 return best_chunk; 842 } 843 844 static void hyp_allocator_drain_memcache(struct hyp_allocator *allocator, 845 struct kvm_hyp_memcache *host_mc, 846 unsigned long target) 847 { 848 struct kvm_hyp_memcache *mc = &allocator->mc; 849 850 while (target && mc->nr_pages) { 851 void *page = pop_hyp_memcache(mc, hyp_phys_to_virt); 852 853 memset(page, 0, PAGE_SIZE); 854 kvm_flush_dcache_to_poc(page, PAGE_SIZE); 855 push_hyp_memcache(host_mc, page, hyp_virt_to_phys); 856 WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(page), 1)); 857 858 target--; 859 } 860 } 861 862 static void hyp_allocator_reclaim(struct hyp_allocator *allocator, struct kvm_hyp_memcache *host_mc, 863 unsigned long target) 864 { 865 unsigned long reclaimed = 0; 866 867 if (!target) 868 return; 869 870 guard(hyp_spinlock)(&allocator->lock); 871 872 do { 873 struct chunk_hdr *chunk; 874 unsigned long r; 875 u64 addr, end; 876 877 chunk = hyp_allocator_find_reclaimable_chunk(allocator, &addr, &end); 878 if (!chunk) 879 break; 880 881 r = min((end - addr) >> PAGE_SHIFT, target - reclaimed); 882 addr = end - (r << PAGE_SHIFT); 883 hyp_allocator_reclaim_chunk(allocator, chunk, (void *)addr, (void *)end); 884 885 reclaimed += r; 886 } while (reclaimed < target); 887 888 hyp_allocator_drain_memcache(allocator, host_mc, target); 889 } 890 891 static unsigned long hyp_allocator_reclaimable(struct hyp_allocator *allocator) 892 { 893 unsigned long reclaimable; 894 struct chunk_hdr *chunk; 895 896 guard(hyp_spinlock)(&allocator->lock); 897 898 /* 899 * While allocator->mc typically contains transient pages, 900 * over-allocation or an aborted operation could leave pages behind. 901 * Account for allocator->mc so stalled topup pages can be reclaimed. 902 */ 903 reclaimable = allocator->mc.nr_pages; 904 905 chunk = allocator->head; 906 while (chunk) { 907 reclaimable += hyp_allocator_chunk_reclaimable(allocator, chunk, NULL, NULL); 908 chunk = chunk_get_next(chunk); 909 } 910 911 return reclaimable; 912 } 913 914 static int hyp_allocator_topup(struct hyp_allocator *allocator, 915 struct kvm_hyp_memcache *host_mc) 916 { 917 struct kvm_hyp_memcache *alloc_mc = &allocator->mc; 918 919 guard(hyp_spinlock)(&allocator->lock); 920 return refill_memcache(alloc_mc, host_mc->nr_pages + alloc_mc->nr_pages, host_mc); 921 } 922 923 static u32 hyp_allocator_topup_needed(struct hyp_allocator *allocator) 924 { 925 u32 *topup_needed = this_cpu_ptr(allocator->topup_needed); 926 u32 ret = *topup_needed; 927 928 *topup_needed = 0; 929 930 return ret; 931 } 932 933 static int hyp_allocator_init(struct hyp_allocator *allocator, size_t size) 934 { 935 unsigned long start; 936 int ret; 937 938 size = PAGE_ALIGN(size); 939 940 /* constrained by chunk_hdr u32 types */ 941 if (size > U32_MAX || !size) 942 return -EINVAL; 943 944 ret = pkvm_alloc_private_va_range(size, &start); 945 if (ret) 946 return ret; 947 948 allocator->first_unmapped = allocator->start = (void *)start; 949 allocator->end = allocator->start + size; 950 hyp_spin_lock_init(&allocator->lock); 951 952 return 0; 953 } 954 955 static DEFINE_PER_CPU(int, __hyp_allocator_errno); 956 static DEFINE_PER_CPU(u32, __hyp_allocator_topup_needed); 957 958 static struct hyp_allocator hyp_allocator = { 959 .errno = &__hyp_allocator_errno, 960 .topup_needed = &__hyp_allocator_topup_needed, 961 }; 962 963 /** 964 * hyp_alloc() - Allocate memory from the heap allocator 965 * 966 * @size: Allocation size in bytes. 967 * 968 * Callers must ensure they do not hold pkvm_pgd_lock to avoid deadlocks, 969 * as the allocator may modify the hyp stage-1 page-table. 970 * 971 * Return: A pointer to the allocated memory on success, else NULL. 972 */ 973 void *hyp_alloc(size_t size) 974 { 975 return hyp_allocator_alloc(&hyp_allocator, size); 976 } 977 978 /** 979 * hyp_free() - Free memory allocated with hyp_alloc() 980 * 981 * @data: Address returned by the original hyp_alloc(). 982 * 983 * The use of any other address than one returned by hyp_alloc() will cause a 984 * hypervisor panic. 985 */ 986 void hyp_free(void *data) 987 { 988 hyp_allocator_free(&hyp_allocator, data); 989 } 990 991 /** 992 * hyp_alloc_errno() - Read the errno on allocation error 993 * 994 * Get the return code from an allocation failure. 995 * 996 * Return: -ENOMEM if the allocator needs a refill from the host, -E2BIG if 997 * there is no VA space left else 0. 998 */ 999 int hyp_alloc_errno(void) 1000 { 1001 return hyp_allocator_errno(&hyp_allocator); 1002 } 1003 1004 static int selftest_init(void); 1005 1006 int hyp_alloc_init(size_t size) 1007 { 1008 int ret; 1009 1010 ret = hyp_allocator_init(&hyp_allocator, size); 1011 if (ret) 1012 return ret; 1013 1014 return selftest_init(); 1015 } 1016 1017 void hyp_alloc_reclaim(struct kvm_hyp_memcache *mc, unsigned long target) 1018 { 1019 hyp_allocator_reclaim(&hyp_allocator, mc, target); 1020 } 1021 1022 unsigned long hyp_alloc_reclaimable(void) 1023 { 1024 return hyp_allocator_reclaimable(&hyp_allocator); 1025 } 1026 1027 int hyp_alloc_topup(struct kvm_hyp_memcache *host_mc) 1028 { 1029 return hyp_allocator_topup(&hyp_allocator, host_mc); 1030 } 1031 1032 u32 hyp_alloc_topup_needed(void) 1033 { 1034 return hyp_allocator_topup_needed(&hyp_allocator); 1035 } 1036 1037 #ifdef CONFIG_NVHE_EL2_DEBUG 1038 #define SELFTEST_MAX_PAGES 6 1039 #define SELFTEST_MAX_SIZE (PAGE_SIZE * SELFTEST_MAX_PAGES) 1040 1041 static DEFINE_PER_CPU(int, __selftest_errno); 1042 static DEFINE_PER_CPU(u32, __selftest_topup_needed); 1043 1044 static struct hyp_allocator selftest_allocator = { 1045 .errno = &__selftest_errno, 1046 .topup_needed = &__selftest_topup_needed, 1047 .lock = __HYP_SPIN_LOCK_UNLOCKED, 1048 }; 1049 1050 int hyp_alloc_selftest_topup(struct kvm_hyp_memcache *host_mc) 1051 { 1052 return hyp_allocator_topup(&selftest_allocator, host_mc); 1053 } 1054 1055 void hyp_alloc_selftest_reclaim(struct kvm_hyp_memcache *host_mc, unsigned long target) 1056 { 1057 hyp_allocator_reclaim(&selftest_allocator, host_mc, target); 1058 } 1059 1060 u32 hyp_alloc_selftest_topup_needed(void) 1061 { 1062 return hyp_allocator_topup_needed(&selftest_allocator); 1063 } 1064 1065 static int selftest_init(void) 1066 { 1067 return hyp_allocator_init(&selftest_allocator, SELFTEST_MAX_SIZE); 1068 } 1069 1070 static void *selftest_alloc(size_t size) 1071 { 1072 return hyp_allocator_alloc(&selftest_allocator, size); 1073 } 1074 1075 static void selftest_free(void *addr) 1076 { 1077 hyp_allocator_free(&selftest_allocator, addr); 1078 } 1079 1080 static int selftest_errno(void) 1081 { 1082 return hyp_allocator_errno(&selftest_allocator); 1083 } 1084 1085 int hyp_allocator_selftest(void) 1086 { 1087 struct hyp_allocator *allocator = &selftest_allocator; 1088 static DEFINE_HYP_SPINLOCK(selftest_lock); 1089 struct kvm_hyp_memcache host_mc = { }; 1090 void *addr1, *addr2, *addr3, *addr4; 1091 int ret; 1092 1093 guard(hyp_spinlock)(&selftest_lock); 1094 1095 if (allocator->mc.nr_pages < SELFTEST_MAX_PAGES) { 1096 *this_cpu_ptr(allocator->topup_needed) = SELFTEST_MAX_PAGES - 1097 allocator->mc.nr_pages; 1098 return -ENOMEM; 1099 } 1100 1101 selftest_alloc(SELFTEST_MAX_SIZE); 1102 if (selftest_errno() != -E2BIG) 1103 return -EINVAL; 1104 1105 selftest_alloc(SIZE_MAX); 1106 if (selftest_errno() != -E2BIG) 1107 return -EINVAL; 1108 1109 /* Test first chunk */ 1110 addr1 = selftest_alloc(0); 1111 if (!addr1 || addr1 != (void *)allocator->start + chunk_hdr_size()) 1112 return -EINVAL; 1113 1114 /* Test second contiguous chunk with unaligned size */ 1115 addr2 = selftest_alloc(MIN_ALLOC_SIZE + 1); 1116 if (!addr2) 1117 return -EINVAL; 1118 addr3 = selftest_alloc(0); 1119 if (!addr3 || 1120 addr3 != addr2 + (2 * MIN_ALLOC_SIZE) + chunk_hdr_size()) 1121 return -EINVAL; 1122 1123 selftest_free(addr3); 1124 1125 /* Test chunk recycling */ 1126 selftest_free(addr1); 1127 if (addr1 != selftest_alloc(0)) 1128 return -EINVAL; 1129 1130 /* Test chunk forward merging */ 1131 addr3 = selftest_alloc(0); 1132 selftest_free(addr2); 1133 selftest_free(addr1); 1134 if (addr1 != selftest_alloc(MIN_ALLOC_SIZE * 2)) 1135 return -EINVAL; 1136 1137 selftest_free(addr1); 1138 1139 /* Test chunk splitting */ 1140 if (addr1 != selftest_alloc(0)) 1141 return -EINVAL; 1142 if (addr2 != selftest_alloc(0)) 1143 return -EINVAL; 1144 1145 /* Test chunk backward merging */ 1146 selftest_free(addr1); 1147 selftest_free(addr2); 1148 if (addr1 != selftest_alloc(MIN_ALLOC_SIZE * 2)) 1149 return -EINVAL; 1150 1151 selftest_free(addr1); 1152 1153 /* Test chunk 3-way merging */ 1154 addr1 = selftest_alloc(0); 1155 addr2 = selftest_alloc(0); 1156 addr4 = selftest_alloc(0); 1157 selftest_free(addr1); 1158 selftest_free(addr3); 1159 selftest_free(addr2); 1160 if (addr1 != selftest_alloc(MIN_ALLOC_SIZE * 3)) 1161 return -EINVAL; 1162 1163 selftest_free(addr4); 1164 selftest_free(addr1); 1165 1166 /* Test reclaiming */ 1167 if (addr1 != selftest_alloc(0)) 1168 return -EINVAL; 1169 if (addr2 != selftest_alloc(PAGE_SIZE * 2)) 1170 return -EINVAL; 1171 addr3 = selftest_alloc(0); 1172 addr4 = selftest_alloc(PAGE_SIZE); 1173 1174 /* Test reclaiming the last chunk of the list */ 1175 selftest_free(addr4); 1176 hyp_allocator_reclaim(allocator, &host_mc, SELFTEST_MAX_PAGES); 1177 if (host_mc.nr_pages != SELFTEST_MAX_PAGES - 3) 1178 return -EINVAL; 1179 1180 /* Test punching a hole in the middle of a free chunk ... */ 1181 selftest_free(addr2); 1182 hyp_allocator_reclaim(allocator, &host_mc, SELFTEST_MAX_PAGES); 1183 if (host_mc.nr_pages != SELFTEST_MAX_PAGES - 2) 1184 return -EINVAL; 1185 1186 if (selftest_alloc(PAGE_SIZE)) 1187 return -EINVAL; 1188 if (selftest_errno() != -ENOMEM) 1189 return -EINVAL; 1190 1191 /* ... and to refill this hole */ 1192 ret = hyp_allocator_topup(allocator, &host_mc); 1193 if (ret) 1194 return ret; 1195 /* Chunk at addr2 was made smaller by the reclaim */ 1196 if (addr2 != selftest_alloc(PAGE_SIZE)) 1197 return -EINVAL; 1198 1199 /* Test reclaiming the entire allocator from the host */ 1200 selftest_free(addr3); 1201 selftest_free(addr2); 1202 selftest_free(addr1); 1203 if (addr1 != selftest_alloc(SELFTEST_MAX_PAGES * PAGE_SIZE - chunk_hdr_size())) 1204 return -EINVAL; 1205 selftest_free(addr1); 1206 1207 return 0; 1208 } 1209 #else 1210 static int selftest_init(void) { return 0; } 1211 #endif 1212