1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2020 Google LLC 4 * Author: Quentin Perret <qperret@google.com> 5 */ 6 7 #include <linux/kvm_host.h> 8 9 #include <asm/kvm_emulate.h> 10 #include <asm/kvm_hyp.h> 11 #include <asm/kvm_mmu.h> 12 #include <asm/kvm_pgtable.h> 13 #include <asm/kvm_pkvm.h> 14 #include <asm/stage2_pgtable.h> 15 16 #include <hyp/fault.h> 17 18 #include <nvhe/arm-smccc.h> 19 #include <nvhe/gfp.h> 20 #include <nvhe/memory.h> 21 #include <nvhe/mem_protect.h> 22 #include <nvhe/mm.h> 23 #include <nvhe/trap_handler.h> 24 25 #define KVM_HOST_S2_FLAGS (KVM_PGTABLE_S2_AS_S1 | KVM_PGTABLE_S2_IDMAP) 26 27 struct host_mmu host_mmu; 28 29 static struct hyp_pool host_s2_pool; 30 31 static DEFINE_PER_CPU(struct pkvm_hyp_vm *, __current_vm); 32 #define current_vm (*this_cpu_ptr(&__current_vm)) 33 34 static void pkvm_sme_dvmsync_fw_call(void) 35 { 36 if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714)) { 37 struct arm_smccc_res res; 38 39 /* 40 * Ignore the return value. Probing for the workaround 41 * availability took place in init_hyp_mode(). 42 */ 43 hyp_smccc_1_1_smc(ARM_SMCCC_CPU_WORKAROUND_4193714, &res); 44 } 45 } 46 47 static void guest_lock_component(struct pkvm_hyp_vm *vm) 48 { 49 hyp_spin_lock(&vm->lock); 50 current_vm = vm; 51 } 52 53 static void guest_unlock_component(struct pkvm_hyp_vm *vm) 54 { 55 current_vm = NULL; 56 hyp_spin_unlock(&vm->lock); 57 } 58 59 static void host_lock_component(void) 60 { 61 hyp_spin_lock(&host_mmu.lock); 62 } 63 64 static void host_unlock_component(void) 65 { 66 hyp_spin_unlock(&host_mmu.lock); 67 } 68 69 static void hyp_lock_component(void) 70 { 71 hyp_spin_lock(&pkvm_pgd_lock); 72 } 73 74 static void hyp_unlock_component(void) 75 { 76 hyp_spin_unlock(&pkvm_pgd_lock); 77 } 78 79 #define for_each_hyp_page(__p, __st, __sz) \ 80 for (struct hyp_page *__p = hyp_phys_to_page(__st), \ 81 *__e = __p + ((__sz) >> PAGE_SHIFT); \ 82 __p < __e; __p++) 83 84 static void *host_s2_zalloc_pages_exact(size_t size) 85 { 86 void *addr = hyp_alloc_pages(&host_s2_pool, get_order(size)); 87 88 hyp_split_page(hyp_virt_to_page(addr)); 89 90 /* 91 * The size of concatenated PGDs is always a power of two of PAGE_SIZE, 92 * so there should be no need to free any of the tail pages to make the 93 * allocation exact. 94 */ 95 WARN_ON(size != (PAGE_SIZE << get_order(size))); 96 97 return addr; 98 } 99 100 static void *host_s2_zalloc_page(void *pool) 101 { 102 return hyp_alloc_pages(pool, 0); 103 } 104 105 static void host_s2_get_page(void *addr) 106 { 107 hyp_get_page(&host_s2_pool, addr); 108 } 109 110 static void host_s2_put_page(void *addr) 111 { 112 hyp_put_page(&host_s2_pool, addr); 113 } 114 115 static void host_s2_free_unlinked_table(void *addr, s8 level) 116 { 117 kvm_pgtable_stage2_free_unlinked(&host_mmu.mm_ops, addr, level); 118 } 119 120 static int prepare_s2_pool(void *pgt_pool_base) 121 { 122 unsigned long nr_pages, pfn; 123 int ret; 124 125 pfn = hyp_virt_to_pfn(pgt_pool_base); 126 nr_pages = host_s2_pgtable_pages(); 127 ret = hyp_pool_init(&host_s2_pool, pfn, nr_pages, 0); 128 if (ret) 129 return ret; 130 131 host_mmu.mm_ops = (struct kvm_pgtable_mm_ops) { 132 .zalloc_pages_exact = host_s2_zalloc_pages_exact, 133 .zalloc_page = host_s2_zalloc_page, 134 .free_unlinked_table = host_s2_free_unlinked_table, 135 .phys_to_virt = hyp_phys_to_virt, 136 .virt_to_phys = hyp_virt_to_phys, 137 .page_count = hyp_page_count, 138 .get_page = host_s2_get_page, 139 .put_page = host_s2_put_page, 140 }; 141 142 return 0; 143 } 144 145 static void prepare_host_vtcr(void) 146 { 147 u32 parange, phys_shift; 148 149 /* The host stage 2 is id-mapped, so use parange for T0SZ */ 150 parange = kvm_get_parange(id_aa64mmfr0_el1_sys_val); 151 phys_shift = id_aa64mmfr0_parange_to_phys_shift(parange); 152 153 host_mmu.arch.mmu.vtcr = kvm_get_vtcr(id_aa64mmfr0_el1_sys_val, 154 id_aa64mmfr1_el1_sys_val, phys_shift); 155 } 156 157 static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot); 158 159 int kvm_host_prepare_stage2(void *pgt_pool_base) 160 { 161 struct kvm_s2_mmu *mmu = &host_mmu.arch.mmu; 162 int ret; 163 164 prepare_host_vtcr(); 165 hyp_spin_lock_init(&host_mmu.lock); 166 mmu->arch = &host_mmu.arch; 167 168 ret = prepare_s2_pool(pgt_pool_base); 169 if (ret) 170 return ret; 171 172 ret = __kvm_pgtable_stage2_init(&host_mmu.pgt, mmu, 173 &host_mmu.mm_ops, KVM_HOST_S2_FLAGS, 174 host_stage2_force_pte_cb); 175 if (ret) 176 return ret; 177 178 mmu->pgd_phys = __hyp_pa(host_mmu.pgt.pgd); 179 mmu->pgt = &host_mmu.pgt; 180 atomic64_set(&mmu->vmid.id, 0); 181 182 return 0; 183 } 184 185 static void *guest_s2_zalloc_pages_exact(size_t size) 186 { 187 void *addr = hyp_alloc_pages(¤t_vm->pool, get_order(size)); 188 189 WARN_ON(size != (PAGE_SIZE << get_order(size))); 190 hyp_split_page(hyp_virt_to_page(addr)); 191 192 return addr; 193 } 194 195 static void guest_s2_free_pages_exact(void *addr, unsigned long size) 196 { 197 u8 order = get_order(size); 198 unsigned int i; 199 200 for (i = 0; i < (1 << order); i++) 201 hyp_put_page(¤t_vm->pool, addr + (i * PAGE_SIZE)); 202 } 203 204 static void *guest_s2_zalloc_page(void *mc) 205 { 206 struct hyp_page *p; 207 void *addr; 208 209 addr = hyp_alloc_pages(¤t_vm->pool, 0); 210 if (addr) 211 return addr; 212 213 addr = pop_hyp_memcache(mc, hyp_phys_to_virt); 214 if (!addr) 215 return addr; 216 217 memset(addr, 0, PAGE_SIZE); 218 p = hyp_virt_to_page(addr); 219 p->refcount = 1; 220 221 return addr; 222 } 223 224 static void guest_s2_get_page(void *addr) 225 { 226 hyp_get_page(¤t_vm->pool, addr); 227 } 228 229 static void guest_s2_put_page(void *addr) 230 { 231 hyp_put_page(¤t_vm->pool, addr); 232 } 233 234 static void __apply_guest_page(void *va, size_t size, 235 void (*func)(void *addr, size_t size)) 236 { 237 size += va - PTR_ALIGN_DOWN(va, PAGE_SIZE); 238 va = PTR_ALIGN_DOWN(va, PAGE_SIZE); 239 size = PAGE_ALIGN(size); 240 241 while (size) { 242 size_t map_size = PAGE_SIZE; 243 void *map; 244 245 if (IS_ALIGNED((unsigned long)va, PMD_SIZE) && size >= PMD_SIZE) 246 map = hyp_fixblock_map(__hyp_pa(va), &map_size); 247 else 248 map = hyp_fixmap_map(__hyp_pa(va)); 249 250 func(map, map_size); 251 252 if (map_size == PMD_SIZE) 253 hyp_fixblock_unmap(); 254 else 255 hyp_fixmap_unmap(); 256 257 size -= map_size; 258 va += map_size; 259 } 260 } 261 262 static void clean_dcache_guest_page(void *va, size_t size) 263 { 264 __apply_guest_page(va, size, __clean_dcache_guest_page); 265 } 266 267 static void invalidate_icache_guest_page(void *va, size_t size) 268 { 269 __apply_guest_page(va, size, __invalidate_icache_guest_page); 270 } 271 272 int kvm_guest_prepare_stage2(struct pkvm_hyp_vm *vm, void *pgd) 273 { 274 struct kvm_s2_mmu *mmu = &vm->kvm.arch.mmu; 275 unsigned long nr_pages; 276 int ret; 277 278 nr_pages = kvm_pgtable_stage2_pgd_size(mmu->vtcr) >> PAGE_SHIFT; 279 ret = hyp_pool_init(&vm->pool, hyp_virt_to_pfn(pgd), nr_pages, 0); 280 if (ret) 281 return ret; 282 283 hyp_spin_lock_init(&vm->lock); 284 vm->mm_ops = (struct kvm_pgtable_mm_ops) { 285 .zalloc_pages_exact = guest_s2_zalloc_pages_exact, 286 .free_pages_exact = guest_s2_free_pages_exact, 287 .zalloc_page = guest_s2_zalloc_page, 288 .phys_to_virt = hyp_phys_to_virt, 289 .virt_to_phys = hyp_virt_to_phys, 290 .page_count = hyp_page_count, 291 .get_page = guest_s2_get_page, 292 .put_page = guest_s2_put_page, 293 .dcache_clean_inval_poc = clean_dcache_guest_page, 294 .icache_inval_pou = invalidate_icache_guest_page, 295 }; 296 297 guest_lock_component(vm); 298 ret = __kvm_pgtable_stage2_init(mmu->pgt, mmu, &vm->mm_ops, 0, NULL); 299 guest_unlock_component(vm); 300 if (ret) 301 return ret; 302 303 vm->kvm.arch.mmu.pgd_phys = __hyp_pa(vm->pgt.pgd); 304 305 return 0; 306 } 307 308 void kvm_guest_destroy_stage2(struct pkvm_hyp_vm *vm) 309 { 310 guest_lock_component(vm); 311 kvm_pgtable_stage2_destroy(&vm->pgt); 312 vm->kvm.arch.mmu.pgd_phys = 0ULL; 313 guest_unlock_component(vm); 314 } 315 316 void reclaim_pgtable_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc) 317 { 318 struct hyp_page *page; 319 void *addr; 320 321 /* Dump all pgtable pages in the hyp_pool */ 322 kvm_guest_destroy_stage2(vm); 323 324 /* Drain the hyp_pool into the memcache */ 325 addr = hyp_alloc_pages(&vm->pool, 0); 326 while (addr) { 327 page = hyp_virt_to_page(addr); 328 page->refcount = 0; 329 push_hyp_memcache(mc, addr, hyp_virt_to_phys); 330 WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1)); 331 addr = hyp_alloc_pages(&vm->pool, 0); 332 } 333 } 334 335 int __pkvm_prot_finalize(void) 336 { 337 struct kvm_s2_mmu *mmu = &host_mmu.arch.mmu; 338 struct kvm_nvhe_init_params *params = this_cpu_ptr(&kvm_init_params); 339 340 if (params->hcr_el2 & HCR_VM) 341 return -EPERM; 342 343 params->vttbr = kvm_get_vttbr(mmu); 344 params->vtcr = mmu->vtcr; 345 params->hcr_el2 |= HCR_VM; 346 if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB)) 347 params->hcr_el2 |= HCR_FWB; 348 349 /* 350 * The CMO below not only cleans the updated params to the 351 * PoC, but also provides the DSB that ensures ongoing 352 * page-table walks that have started before we trapped to EL2 353 * have completed. 354 */ 355 kvm_flush_dcache_to_poc(params, sizeof(*params)); 356 357 write_sysreg_hcr(params->hcr_el2); 358 __load_stage2(&host_mmu.arch.mmu); 359 360 /* 361 * Make sure to have an ISB before the TLB maintenance below but only 362 * when __load_stage2() doesn't include one already. 363 */ 364 asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT)); 365 366 /* Invalidate stale HCR bits that may be cached in TLBs */ 367 __tlbi(vmalls12e1); 368 dsb(nsh); 369 isb(); 370 371 return 0; 372 } 373 374 static int host_stage2_unmap_dev_all(void) 375 { 376 struct kvm_pgtable *pgt = &host_mmu.pgt; 377 struct memblock_region *reg; 378 u64 addr = 0; 379 int i, ret; 380 381 /* Unmap all non-memory regions to recycle the pages */ 382 for (i = 0; i < hyp_memblock_nr; i++, addr = reg->base + reg->size) { 383 reg = &hyp_memory[i]; 384 ret = kvm_pgtable_stage2_unmap(pgt, addr, reg->base - addr); 385 if (ret) 386 return ret; 387 } 388 return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr); 389 } 390 391 /* 392 * Ensure the PFN range is contained within PA-range. 393 * 394 * This check is also robust to overflows and is therefore a requirement before 395 * using a pfn/nr_pages pair from an untrusted source. 396 */ 397 static bool pfn_range_is_valid(u64 pfn, u64 nr_pages) 398 { 399 u64 limit = BIT(kvm_phys_shift(&host_mmu.arch.mmu) - PAGE_SHIFT); 400 401 return pfn < limit && ((limit - pfn) >= nr_pages); 402 } 403 404 struct kvm_mem_range { 405 u64 start; 406 u64 end; 407 }; 408 409 static struct memblock_region *find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) 410 { 411 int cur, left = 0, right = hyp_memblock_nr; 412 struct memblock_region *reg; 413 phys_addr_t end; 414 415 range->start = 0; 416 range->end = ULONG_MAX; 417 418 /* The list of memblock regions is sorted, binary search it */ 419 while (left < right) { 420 cur = (left + right) >> 1; 421 reg = &hyp_memory[cur]; 422 end = reg->base + reg->size; 423 if (addr < reg->base) { 424 right = cur; 425 range->end = reg->base; 426 } else if (addr >= end) { 427 left = cur + 1; 428 range->start = end; 429 } else { 430 range->start = reg->base; 431 range->end = end; 432 return reg; 433 } 434 } 435 436 return NULL; 437 } 438 439 bool addr_is_memory(phys_addr_t phys) 440 { 441 struct kvm_mem_range range; 442 443 return !!find_mem_range(phys, &range); 444 } 445 446 static bool is_in_mem_range(u64 addr, struct kvm_mem_range *range) 447 { 448 return range->start <= addr && addr < range->end; 449 } 450 451 static int check_range_allowed_memory(u64 start, u64 end) 452 { 453 struct memblock_region *reg; 454 struct kvm_mem_range range; 455 456 /* 457 * Callers can't check the state of a range that overlaps memory and 458 * MMIO regions, so ensure [start, end[ is in the same kvm_mem_range. 459 */ 460 reg = find_mem_range(start, &range); 461 if (!is_in_mem_range(end - 1, &range)) 462 return -EINVAL; 463 464 if (!reg || reg->flags & MEMBLOCK_NOMAP) 465 return -EPERM; 466 467 return 0; 468 } 469 470 static bool range_is_memory(u64 start, u64 end) 471 { 472 struct kvm_mem_range r; 473 474 if (!find_mem_range(start, &r)) 475 return false; 476 477 return is_in_mem_range(end - 1, &r); 478 } 479 480 static inline int __host_stage2_idmap(u64 start, u64 end, 481 enum kvm_pgtable_prot prot) 482 { 483 /* 484 * We don't make permission changes to the host idmap after 485 * initialisation, so we can squash -EAGAIN to save callers 486 * having to treat it like success in the case that they try to 487 * map something that is already mapped. 488 */ 489 return kvm_pgtable_stage2_map(&host_mmu.pgt, start, end - start, start, 490 prot, &host_s2_pool, 491 KVM_PGTABLE_WALK_IGNORE_EAGAIN); 492 } 493 494 /* 495 * The pool has been provided with enough pages to cover all of memory with 496 * page granularity, but it is difficult to know how much of the MMIO range 497 * we will need to cover upfront, so we may need to 'recycle' the pages if we 498 * run out. 499 */ 500 #define host_stage2_try(fn, ...) \ 501 ({ \ 502 int __ret; \ 503 hyp_assert_lock_held(&host_mmu.lock); \ 504 __ret = fn(__VA_ARGS__); \ 505 if (__ret == -ENOMEM) { \ 506 __ret = host_stage2_unmap_dev_all(); \ 507 if (!__ret) \ 508 __ret = fn(__VA_ARGS__); \ 509 } \ 510 __ret; \ 511 }) 512 513 static inline bool range_included(struct kvm_mem_range *child, 514 struct kvm_mem_range *parent) 515 { 516 return parent->start <= child->start && child->end <= parent->end; 517 } 518 519 static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) 520 { 521 struct kvm_mem_range cur; 522 kvm_pte_t pte; 523 u64 granule; 524 s8 level; 525 int ret; 526 527 hyp_assert_lock_held(&host_mmu.lock); 528 ret = kvm_pgtable_get_leaf(&host_mmu.pgt, addr, &pte, &level); 529 if (ret) 530 return ret; 531 532 if (kvm_pte_valid(pte)) 533 return -EEXIST; 534 535 if (pte) { 536 WARN_ON(addr_is_memory(addr) && 537 get_host_state(hyp_phys_to_page(addr)) != PKVM_NOPAGE); 538 return -EPERM; 539 } 540 541 for (; level <= KVM_PGTABLE_LAST_LEVEL; level++) { 542 if (!kvm_level_supports_block_mapping(level)) 543 continue; 544 granule = kvm_granule_size(level); 545 cur.start = ALIGN_DOWN(addr, granule); 546 cur.end = cur.start + granule; 547 if (!range_included(&cur, range) && level < KVM_PGTABLE_LAST_LEVEL) 548 continue; 549 *range = cur; 550 return 0; 551 } 552 553 WARN_ON(1); 554 555 return -EINVAL; 556 } 557 558 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, 559 enum kvm_pgtable_prot prot) 560 { 561 return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); 562 } 563 564 static void __host_update_page_state(phys_addr_t addr, u64 size, enum pkvm_page_state state) 565 { 566 for_each_hyp_page(page, addr, size) 567 set_host_state(page, state); 568 } 569 570 #define KVM_HOST_DONATION_PTE_OWNER_MASK GENMASK(3, 1) 571 #define KVM_HOST_DONATION_PTE_EXTRA_MASK GENMASK(59, 4) 572 static int host_stage2_set_owner_metadata_locked(phys_addr_t addr, u64 size, 573 u8 owner_id, u64 meta) 574 { 575 kvm_pte_t annotation; 576 int ret; 577 578 if (owner_id == PKVM_ID_HOST) 579 return -EINVAL; 580 581 if (!range_is_memory(addr, addr + size)) 582 return -EPERM; 583 584 if (!FIELD_FIT(KVM_HOST_DONATION_PTE_OWNER_MASK, owner_id)) 585 return -EINVAL; 586 587 if (!FIELD_FIT(KVM_HOST_DONATION_PTE_EXTRA_MASK, meta)) 588 return -EINVAL; 589 590 annotation = FIELD_PREP(KVM_HOST_DONATION_PTE_OWNER_MASK, owner_id) | 591 FIELD_PREP(KVM_HOST_DONATION_PTE_EXTRA_MASK, meta); 592 ret = host_stage2_try(kvm_pgtable_stage2_annotate, &host_mmu.pgt, 593 addr, size, &host_s2_pool, 594 KVM_HOST_INVALID_PTE_TYPE_DONATION, annotation); 595 if (!ret) { 596 /* 597 * After stage2 maintenance has happened, but before the page 598 * owner has changed. 599 */ 600 pkvm_sme_dvmsync_fw_call(); 601 __host_update_page_state(addr, size, PKVM_NOPAGE); 602 } 603 604 return ret; 605 } 606 607 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) 608 { 609 int ret = -EINVAL; 610 611 switch (owner_id) { 612 case PKVM_ID_HOST: 613 if (!range_is_memory(addr, addr + size)) 614 return -EPERM; 615 616 ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT); 617 if (!ret) 618 __host_update_page_state(addr, size, PKVM_PAGE_OWNED); 619 break; 620 case PKVM_ID_HYP: 621 ret = host_stage2_set_owner_metadata_locked(addr, size, 622 owner_id, 0); 623 break; 624 } 625 626 return ret; 627 } 628 629 #define KVM_HOST_PTE_OWNER_GUEST_HANDLE_MASK GENMASK(15, 0) 630 /* We need 40 bits for the GFN to cover a 52-bit IPA with 4k pages and LPA2 */ 631 #define KVM_HOST_PTE_OWNER_GUEST_GFN_MASK GENMASK(55, 16) 632 static u64 host_stage2_encode_gfn_meta(struct pkvm_hyp_vm *vm, u64 gfn) 633 { 634 pkvm_handle_t handle = vm->kvm.arch.pkvm.handle; 635 636 BUILD_BUG_ON((pkvm_handle_t)-1 > KVM_HOST_PTE_OWNER_GUEST_HANDLE_MASK); 637 WARN_ON(!FIELD_FIT(KVM_HOST_PTE_OWNER_GUEST_GFN_MASK, gfn)); 638 639 return FIELD_PREP(KVM_HOST_PTE_OWNER_GUEST_HANDLE_MASK, handle) | 640 FIELD_PREP(KVM_HOST_PTE_OWNER_GUEST_GFN_MASK, gfn); 641 } 642 643 static int host_stage2_decode_gfn_meta(kvm_pte_t pte, struct pkvm_hyp_vm **vm, 644 u64 *gfn) 645 { 646 pkvm_handle_t handle; 647 u64 meta; 648 649 if (WARN_ON(kvm_pte_valid(pte))) 650 return -EINVAL; 651 652 if (FIELD_GET(KVM_INVALID_PTE_TYPE_MASK, pte) != 653 KVM_HOST_INVALID_PTE_TYPE_DONATION) { 654 return -EINVAL; 655 } 656 657 if (FIELD_GET(KVM_HOST_DONATION_PTE_OWNER_MASK, pte) != PKVM_ID_GUEST) 658 return -EPERM; 659 660 meta = FIELD_GET(KVM_HOST_DONATION_PTE_EXTRA_MASK, pte); 661 handle = FIELD_GET(KVM_HOST_PTE_OWNER_GUEST_HANDLE_MASK, meta); 662 *vm = get_vm_by_handle(handle); 663 if (!*vm) { 664 /* We probably raced with teardown; try again */ 665 return -EAGAIN; 666 } 667 668 *gfn = FIELD_GET(KVM_HOST_PTE_OWNER_GUEST_GFN_MASK, meta); 669 return 0; 670 } 671 672 static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot) 673 { 674 /* 675 * Block mappings must be used with care in the host stage-2 as a 676 * kvm_pgtable_stage2_map() operation targeting a page in the range of 677 * an existing block will delete the block under the assumption that 678 * mappings in the rest of the block range can always be rebuilt lazily. 679 * That assumption is correct for the host stage-2 with RWX mappings 680 * targeting memory or RW mappings targeting MMIO ranges (see 681 * host_stage2_idmap() below which implements some of the host memory 682 * abort logic). However, this is not safe for any other mappings where 683 * the host stage-2 page-table is in fact the only place where this 684 * state is stored. In all those cases, it is safer to use page-level 685 * mappings, hence avoiding to lose the state because of side-effects in 686 * kvm_pgtable_stage2_map(). 687 */ 688 if (range_is_memory(addr, end)) 689 return prot != PKVM_HOST_MEM_PROT; 690 else 691 return prot != PKVM_HOST_MMIO_PROT; 692 } 693 694 static int host_stage2_idmap(u64 addr) 695 { 696 struct kvm_mem_range range; 697 bool is_memory = !!find_mem_range(addr, &range); 698 enum kvm_pgtable_prot prot; 699 int ret; 700 701 prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT; 702 703 host_lock_component(); 704 ret = host_stage2_adjust_range(addr, &range); 705 if (ret) 706 goto unlock; 707 708 ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot); 709 unlock: 710 host_unlock_component(); 711 712 return ret; 713 } 714 715 static void host_inject_mem_abort(struct kvm_cpu_context *host_ctxt) 716 { 717 u64 ec, esr, spsr; 718 719 esr = read_sysreg_el2(SYS_ESR); 720 spsr = read_sysreg_el2(SYS_SPSR); 721 722 /* Repaint the ESR to report a same-level fault if taken from EL1 */ 723 if ((spsr & PSR_MODE_MASK) != PSR_MODE_EL0t) { 724 ec = ESR_ELx_EC(esr); 725 if (ec == ESR_ELx_EC_DABT_LOW) 726 ec = ESR_ELx_EC_DABT_CUR; 727 else if (ec == ESR_ELx_EC_IABT_LOW) 728 ec = ESR_ELx_EC_IABT_CUR; 729 else 730 WARN_ON(1); 731 esr &= ~ESR_ELx_EC_MASK; 732 esr |= ec << ESR_ELx_EC_SHIFT; 733 } 734 735 /* 736 * Since S1PTW should only ever be set for stage-2 faults, we're pretty 737 * much guaranteed that it won't be set in ESR_EL1 by the hardware. So, 738 * let's use that bit to allow the host abort handler to differentiate 739 * this abort from normal userspace faults. 740 * 741 * Note: although S1PTW is RES0 at EL1, it is guaranteed by the 742 * architecture to be backed by flops, so it should be safe to use. 743 */ 744 esr |= ESR_ELx_S1PTW; 745 inject_host_exception(esr); 746 } 747 748 void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) 749 { 750 struct kvm_vcpu_fault_info fault; 751 u64 esr, addr; 752 753 esr = read_sysreg_el2(SYS_ESR); 754 if (!__get_fault_info(esr, &fault)) { 755 /* 756 * We've presumably raced with a page-table change which caused 757 * AT to fail, try again. 758 */ 759 return; 760 } 761 762 763 /* 764 * Yikes, we couldn't resolve the fault IPA. This should reinject an 765 * abort into the host when we figure out how to do that. 766 */ 767 BUG_ON(!(fault.hpfar_el2 & HPFAR_EL2_NS)); 768 addr = FIELD_GET(HPFAR_EL2_FIPA, fault.hpfar_el2) << 12; 769 770 switch (host_stage2_idmap(addr)) { 771 case -EPERM: 772 host_inject_mem_abort(host_ctxt); 773 fallthrough; 774 case -EEXIST: 775 case 0: 776 break; 777 default: 778 BUG(); 779 } 780 } 781 782 struct check_walk_data { 783 enum pkvm_page_state desired; 784 enum pkvm_page_state (*get_page_state)(kvm_pte_t pte, u64 addr); 785 }; 786 787 static int __check_page_state_visitor(const struct kvm_pgtable_visit_ctx *ctx, 788 enum kvm_pgtable_walk_flags visit) 789 { 790 struct check_walk_data *d = ctx->arg; 791 792 return d->get_page_state(ctx->old, ctx->addr) == d->desired ? 0 : -EPERM; 793 } 794 795 static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size, 796 struct check_walk_data *data) 797 { 798 struct kvm_pgtable_walker walker = { 799 .cb = __check_page_state_visitor, 800 .arg = data, 801 .flags = KVM_PGTABLE_WALK_LEAF, 802 }; 803 804 return kvm_pgtable_walk(pgt, addr, size, &walker); 805 } 806 807 static int __host_check_page_state_range(u64 addr, u64 size, 808 enum pkvm_page_state state) 809 { 810 int ret; 811 812 ret = check_range_allowed_memory(addr, addr + size); 813 if (ret) 814 return ret; 815 816 hyp_assert_lock_held(&host_mmu.lock); 817 818 for_each_hyp_page(page, addr, size) { 819 if (get_host_state(page) != state) 820 return -EPERM; 821 } 822 823 return 0; 824 } 825 826 static int __host_set_page_state_range(u64 addr, u64 size, 827 enum pkvm_page_state state) 828 { 829 if (get_host_state(hyp_phys_to_page(addr)) == PKVM_NOPAGE) { 830 int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT); 831 832 if (ret) 833 return ret; 834 } 835 836 __host_update_page_state(addr, size, state); 837 838 return 0; 839 } 840 841 static void __hyp_set_page_state_range(phys_addr_t phys, u64 size, enum pkvm_page_state state) 842 { 843 for_each_hyp_page(page, phys, size) 844 set_hyp_state(page, state); 845 } 846 847 static int __hyp_check_page_state_range(phys_addr_t phys, u64 size, enum pkvm_page_state state) 848 { 849 for_each_hyp_page(page, phys, size) { 850 if (get_hyp_state(page) != state) 851 return -EPERM; 852 } 853 854 return 0; 855 } 856 857 static int __hyp_check_page_count_range(phys_addr_t phys, u64 size) 858 { 859 for_each_hyp_page(page, phys, size) { 860 if (page->refcount) 861 return -EBUSY; 862 } 863 864 return 0; 865 } 866 867 static bool guest_pte_is_poisoned(kvm_pte_t pte) 868 { 869 if (kvm_pte_valid(pte)) 870 return false; 871 872 return FIELD_GET(KVM_INVALID_PTE_TYPE_MASK, pte) == 873 KVM_GUEST_INVALID_PTE_TYPE_POISONED; 874 } 875 876 static enum pkvm_page_state guest_get_page_state(kvm_pte_t pte, u64 addr) 877 { 878 if (guest_pte_is_poisoned(pte)) 879 return PKVM_POISON; 880 881 if (!kvm_pte_valid(pte)) 882 return PKVM_NOPAGE; 883 884 return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte)); 885 } 886 887 static int __guest_check_page_state_range(struct pkvm_hyp_vm *vm, u64 addr, 888 u64 size, enum pkvm_page_state state) 889 { 890 struct check_walk_data d = { 891 .desired = state, 892 .get_page_state = guest_get_page_state, 893 }; 894 895 hyp_assert_lock_held(&vm->lock); 896 return check_page_state_range(&vm->pgt, addr, size, &d); 897 } 898 899 static int get_valid_guest_pte(struct pkvm_hyp_vm *vm, u64 ipa, kvm_pte_t *ptep, u64 *physp) 900 { 901 kvm_pte_t pte; 902 u64 phys; 903 s8 level; 904 int ret; 905 906 ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level); 907 if (ret) 908 return ret; 909 if (guest_pte_is_poisoned(pte)) 910 return -EHWPOISON; 911 if (!kvm_pte_valid(pte)) 912 return -ENOENT; 913 if (level != KVM_PGTABLE_LAST_LEVEL) 914 return -E2BIG; 915 916 phys = kvm_pte_to_phys(pte); 917 ret = check_range_allowed_memory(phys, phys + PAGE_SIZE); 918 if (WARN_ON(ret)) 919 return ret; 920 921 *ptep = pte; 922 *physp = phys; 923 924 return 0; 925 } 926 927 int __pkvm_vcpu_in_poison_fault(struct pkvm_hyp_vcpu *hyp_vcpu) 928 { 929 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu); 930 kvm_pte_t pte; 931 s8 level; 932 u64 ipa; 933 int ret; 934 935 switch (kvm_vcpu_trap_get_class(&hyp_vcpu->vcpu)) { 936 case ESR_ELx_EC_DABT_LOW: 937 case ESR_ELx_EC_IABT_LOW: 938 if (kvm_vcpu_trap_is_translation_fault(&hyp_vcpu->vcpu)) 939 break; 940 fallthrough; 941 default: 942 return -EINVAL; 943 } 944 945 /* 946 * The host has the faulting IPA when it calls us from the guest 947 * fault handler but we retrieve it ourselves from the FAR so as 948 * to avoid exposing an "oracle" that could reveal data access 949 * patterns of the guest after initial donation of its pages. 950 */ 951 ipa = kvm_vcpu_get_fault_ipa(&hyp_vcpu->vcpu); 952 ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(&hyp_vcpu->vcpu)); 953 954 guest_lock_component(vm); 955 ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level); 956 if (ret) 957 goto unlock; 958 959 if (level != KVM_PGTABLE_LAST_LEVEL) { 960 ret = -EINVAL; 961 goto unlock; 962 } 963 964 ret = guest_pte_is_poisoned(pte); 965 unlock: 966 guest_unlock_component(vm); 967 return ret; 968 } 969 970 int __pkvm_host_share_hyp(u64 pfn) 971 { 972 u64 phys = hyp_pfn_to_phys(pfn); 973 u64 size = PAGE_SIZE; 974 int ret; 975 976 host_lock_component(); 977 hyp_lock_component(); 978 979 ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED); 980 if (ret) 981 goto unlock; 982 ret = __hyp_check_page_state_range(phys, size, PKVM_NOPAGE); 983 if (ret) 984 goto unlock; 985 986 __hyp_set_page_state_range(phys, size, PKVM_PAGE_SHARED_BORROWED); 987 WARN_ON(__host_set_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED)); 988 989 unlock: 990 hyp_unlock_component(); 991 host_unlock_component(); 992 993 return ret; 994 } 995 996 int __pkvm_guest_share_host(struct pkvm_hyp_vcpu *vcpu, u64 gfn) 997 { 998 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 999 u64 phys, ipa = hyp_pfn_to_phys(gfn); 1000 kvm_pte_t pte; 1001 int ret; 1002 1003 host_lock_component(); 1004 guest_lock_component(vm); 1005 1006 ret = get_valid_guest_pte(vm, ipa, &pte, &phys); 1007 if (ret) 1008 goto unlock; 1009 1010 ret = -EPERM; 1011 if (pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte)) != PKVM_PAGE_OWNED) 1012 goto unlock; 1013 if (__host_check_page_state_range(phys, PAGE_SIZE, PKVM_NOPAGE)) 1014 goto unlock; 1015 1016 ret = 0; 1017 WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys, 1018 pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_OWNED), 1019 &vcpu->vcpu.arch.pkvm_memcache, 0)); 1020 WARN_ON(__host_set_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_BORROWED)); 1021 unlock: 1022 guest_unlock_component(vm); 1023 host_unlock_component(); 1024 1025 return ret; 1026 } 1027 1028 int __pkvm_guest_unshare_host(struct pkvm_hyp_vcpu *vcpu, u64 gfn) 1029 { 1030 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1031 u64 meta, phys, ipa = hyp_pfn_to_phys(gfn); 1032 kvm_pte_t pte; 1033 int ret; 1034 1035 host_lock_component(); 1036 guest_lock_component(vm); 1037 1038 ret = get_valid_guest_pte(vm, ipa, &pte, &phys); 1039 if (ret) 1040 goto unlock; 1041 1042 ret = -EPERM; 1043 if (pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte)) != PKVM_PAGE_SHARED_OWNED) 1044 goto unlock; 1045 if (__host_check_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_BORROWED)) 1046 goto unlock; 1047 1048 ret = 0; 1049 meta = host_stage2_encode_gfn_meta(vm, gfn); 1050 WARN_ON(host_stage2_set_owner_metadata_locked(phys, PAGE_SIZE, 1051 PKVM_ID_GUEST, meta)); 1052 WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys, 1053 pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_OWNED), 1054 &vcpu->vcpu.arch.pkvm_memcache, 0)); 1055 unlock: 1056 guest_unlock_component(vm); 1057 host_unlock_component(); 1058 1059 return ret; 1060 } 1061 1062 int __pkvm_host_unshare_hyp(u64 pfn) 1063 { 1064 u64 phys = hyp_pfn_to_phys(pfn); 1065 u64 size = PAGE_SIZE; 1066 int ret; 1067 1068 host_lock_component(); 1069 hyp_lock_component(); 1070 1071 ret = __host_check_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED); 1072 if (ret) 1073 goto unlock; 1074 ret = __hyp_check_page_state_range(phys, size, PKVM_PAGE_SHARED_BORROWED); 1075 if (ret) 1076 goto unlock; 1077 ret = __hyp_check_page_count_range(phys, size); 1078 if (ret) 1079 goto unlock; 1080 1081 __hyp_set_page_state_range(phys, size, PKVM_NOPAGE); 1082 WARN_ON(__host_set_page_state_range(phys, size, PKVM_PAGE_OWNED)); 1083 1084 unlock: 1085 hyp_unlock_component(); 1086 host_unlock_component(); 1087 1088 return ret; 1089 } 1090 1091 int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages) 1092 { 1093 u64 phys = hyp_pfn_to_phys(pfn); 1094 u64 size = PAGE_SIZE * nr_pages; 1095 void *virt = __hyp_va(phys); 1096 int ret; 1097 1098 if (!pfn_range_is_valid(pfn, nr_pages)) 1099 return -EINVAL; 1100 1101 host_lock_component(); 1102 hyp_lock_component(); 1103 1104 ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED); 1105 if (ret) 1106 goto unlock; 1107 ret = __hyp_check_page_state_range(phys, size, PKVM_NOPAGE); 1108 if (ret) 1109 goto unlock; 1110 1111 __hyp_set_page_state_range(phys, size, PKVM_PAGE_OWNED); 1112 WARN_ON(pkvm_create_mappings_locked(virt, virt + size, PAGE_HYP)); 1113 WARN_ON(host_stage2_set_owner_locked(phys, size, PKVM_ID_HYP)); 1114 1115 unlock: 1116 hyp_unlock_component(); 1117 host_unlock_component(); 1118 1119 return ret; 1120 } 1121 1122 int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages) 1123 { 1124 u64 phys = hyp_pfn_to_phys(pfn); 1125 u64 size = PAGE_SIZE * nr_pages; 1126 u64 virt = (u64)__hyp_va(phys); 1127 int ret; 1128 1129 if (!pfn_range_is_valid(pfn, nr_pages)) 1130 return -EINVAL; 1131 1132 host_lock_component(); 1133 hyp_lock_component(); 1134 1135 ret = __hyp_check_page_state_range(phys, size, PKVM_PAGE_OWNED); 1136 if (ret) 1137 goto unlock; 1138 ret = __host_check_page_state_range(phys, size, PKVM_NOPAGE); 1139 if (ret) 1140 goto unlock; 1141 1142 ret = __hyp_check_page_count_range(phys, size); 1143 if (ret) 1144 goto unlock; 1145 1146 __hyp_set_page_state_range(phys, size, PKVM_NOPAGE); 1147 WARN_ON(kvm_pgtable_hyp_unmap(&pkvm_pgtable, virt, size) != size); 1148 WARN_ON(host_stage2_set_owner_locked(phys, size, PKVM_ID_HOST)); 1149 1150 unlock: 1151 hyp_unlock_component(); 1152 host_unlock_component(); 1153 1154 return ret; 1155 } 1156 1157 int hyp_pin_shared_mem(void *from, void *to) 1158 { 1159 u64 cur, start = ALIGN_DOWN((u64)from, PAGE_SIZE); 1160 u64 end = PAGE_ALIGN((u64)to); 1161 u64 phys = __hyp_pa(start); 1162 u64 size = end - start; 1163 struct hyp_page *p; 1164 int ret; 1165 1166 host_lock_component(); 1167 hyp_lock_component(); 1168 1169 ret = __host_check_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED); 1170 if (ret) 1171 goto unlock; 1172 1173 ret = __hyp_check_page_state_range(phys, size, PKVM_PAGE_SHARED_BORROWED); 1174 if (ret) 1175 goto unlock; 1176 1177 for (cur = start; cur < end; cur += PAGE_SIZE) { 1178 p = hyp_virt_to_page(cur); 1179 hyp_page_ref_inc(p); 1180 if (p->refcount == 1) 1181 WARN_ON(pkvm_create_mappings_locked((void *)cur, 1182 (void *)cur + PAGE_SIZE, 1183 PAGE_HYP)); 1184 } 1185 1186 unlock: 1187 hyp_unlock_component(); 1188 host_unlock_component(); 1189 1190 return ret; 1191 } 1192 1193 void hyp_unpin_shared_mem(void *from, void *to) 1194 { 1195 u64 cur, start = ALIGN_DOWN((u64)from, PAGE_SIZE); 1196 u64 end = PAGE_ALIGN((u64)to); 1197 struct hyp_page *p; 1198 1199 host_lock_component(); 1200 hyp_lock_component(); 1201 1202 for (cur = start; cur < end; cur += PAGE_SIZE) { 1203 p = hyp_virt_to_page(cur); 1204 if (p->refcount == 1) 1205 WARN_ON(kvm_pgtable_hyp_unmap(&pkvm_pgtable, cur, PAGE_SIZE) != PAGE_SIZE); 1206 hyp_page_ref_dec(p); 1207 } 1208 1209 hyp_unlock_component(); 1210 host_unlock_component(); 1211 } 1212 1213 int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages) 1214 { 1215 u64 phys = hyp_pfn_to_phys(pfn); 1216 u64 size = PAGE_SIZE * nr_pages; 1217 int ret; 1218 1219 if (!pfn_range_is_valid(pfn, nr_pages)) 1220 return -EINVAL; 1221 1222 host_lock_component(); 1223 ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED); 1224 if (!ret) 1225 ret = __host_set_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED); 1226 host_unlock_component(); 1227 1228 return ret; 1229 } 1230 1231 int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages) 1232 { 1233 u64 phys = hyp_pfn_to_phys(pfn); 1234 u64 size = PAGE_SIZE * nr_pages; 1235 int ret; 1236 1237 if (!pfn_range_is_valid(pfn, nr_pages)) 1238 return -EINVAL; 1239 1240 host_lock_component(); 1241 ret = __host_check_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED); 1242 if (!ret) 1243 ret = __host_set_page_state_range(phys, size, PKVM_PAGE_OWNED); 1244 host_unlock_component(); 1245 1246 return ret; 1247 } 1248 1249 static int __guest_check_transition_size(u64 phys, u64 ipa, u64 nr_pages, u64 *size) 1250 { 1251 size_t block_size; 1252 1253 if (nr_pages == 1) { 1254 *size = PAGE_SIZE; 1255 return 0; 1256 } 1257 1258 /* We solely support second to last level huge mapping */ 1259 block_size = kvm_granule_size(KVM_PGTABLE_LAST_LEVEL - 1); 1260 1261 if (nr_pages != block_size >> PAGE_SHIFT) 1262 return -EINVAL; 1263 1264 if (!IS_ALIGNED(phys | ipa, block_size)) 1265 return -EINVAL; 1266 1267 *size = block_size; 1268 return 0; 1269 } 1270 1271 static void hyp_poison_page(phys_addr_t phys) 1272 { 1273 void *addr = hyp_fixmap_map(phys); 1274 1275 memset(addr, 0, PAGE_SIZE); 1276 /* 1277 * Prefer kvm_flush_dcache_to_poc() over __clean_dcache_guest_page() 1278 * here as the latter may elide the CMO under the assumption that FWB 1279 * will be enabled on CPUs that support it. This is incorrect for the 1280 * host stage-2 and would otherwise lead to a malicious host potentially 1281 * being able to read the contents of newly reclaimed guest pages. 1282 */ 1283 kvm_flush_dcache_to_poc(addr, PAGE_SIZE); 1284 hyp_fixmap_unmap(); 1285 } 1286 1287 static int host_stage2_get_guest_info(phys_addr_t phys, struct pkvm_hyp_vm **vm, 1288 u64 *gfn) 1289 { 1290 enum pkvm_page_state state; 1291 kvm_pte_t pte; 1292 s8 level; 1293 int ret; 1294 1295 if (!addr_is_memory(phys)) 1296 return -EFAULT; 1297 1298 state = get_host_state(hyp_phys_to_page(phys)); 1299 switch (state) { 1300 case PKVM_PAGE_OWNED: 1301 case PKVM_PAGE_SHARED_OWNED: 1302 case PKVM_PAGE_SHARED_BORROWED: 1303 /* The access should no longer fault; try again. */ 1304 return -EAGAIN; 1305 case PKVM_NOPAGE: 1306 break; 1307 default: 1308 return -EPERM; 1309 } 1310 1311 ret = kvm_pgtable_get_leaf(&host_mmu.pgt, phys, &pte, &level); 1312 if (ret) 1313 return ret; 1314 1315 if (WARN_ON(level != KVM_PGTABLE_LAST_LEVEL)) 1316 return -EINVAL; 1317 1318 return host_stage2_decode_gfn_meta(pte, vm, gfn); 1319 } 1320 1321 int __pkvm_host_force_reclaim_page_guest(phys_addr_t phys) 1322 { 1323 struct pkvm_hyp_vm *vm; 1324 u64 gfn, ipa, pa; 1325 kvm_pte_t pte; 1326 int ret; 1327 1328 phys &= PAGE_MASK; 1329 1330 hyp_spin_lock(&vm_table_lock); 1331 host_lock_component(); 1332 1333 ret = host_stage2_get_guest_info(phys, &vm, &gfn); 1334 if (ret) 1335 goto unlock_host; 1336 1337 ipa = hyp_pfn_to_phys(gfn); 1338 guest_lock_component(vm); 1339 ret = get_valid_guest_pte(vm, ipa, &pte, &pa); 1340 if (ret) 1341 goto unlock_guest; 1342 1343 WARN_ON(pa != phys); 1344 if (guest_get_page_state(pte, ipa) != PKVM_PAGE_OWNED) { 1345 ret = -EPERM; 1346 goto unlock_guest; 1347 } 1348 1349 /* We really shouldn't be allocating, so don't pass a memcache */ 1350 ret = kvm_pgtable_stage2_annotate(&vm->pgt, ipa, PAGE_SIZE, NULL, 1351 KVM_GUEST_INVALID_PTE_TYPE_POISONED, 1352 0); 1353 if (ret) 1354 goto unlock_guest; 1355 1356 hyp_poison_page(phys); 1357 WARN_ON(host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HOST)); 1358 unlock_guest: 1359 guest_unlock_component(vm); 1360 unlock_host: 1361 host_unlock_component(); 1362 hyp_spin_unlock(&vm_table_lock); 1363 1364 return ret; 1365 } 1366 1367 int __pkvm_host_reclaim_page_guest(u64 gfn, struct pkvm_hyp_vm *vm) 1368 { 1369 u64 ipa = hyp_pfn_to_phys(gfn); 1370 kvm_pte_t pte; 1371 u64 phys; 1372 int ret; 1373 1374 host_lock_component(); 1375 guest_lock_component(vm); 1376 1377 ret = get_valid_guest_pte(vm, ipa, &pte, &phys); 1378 if (ret) 1379 goto unlock; 1380 1381 switch (guest_get_page_state(pte, ipa)) { 1382 case PKVM_PAGE_OWNED: 1383 WARN_ON(__host_check_page_state_range(phys, PAGE_SIZE, PKVM_NOPAGE)); 1384 hyp_poison_page(phys); 1385 break; 1386 case PKVM_PAGE_SHARED_OWNED: 1387 WARN_ON(__host_check_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_SHARED_BORROWED)); 1388 break; 1389 default: 1390 ret = -EPERM; 1391 goto unlock; 1392 } 1393 1394 WARN_ON(kvm_pgtable_stage2_unmap(&vm->pgt, ipa, PAGE_SIZE)); 1395 WARN_ON(host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HOST)); 1396 1397 unlock: 1398 guest_unlock_component(vm); 1399 host_unlock_component(); 1400 1401 /* 1402 * -EHWPOISON implies that the page was forcefully reclaimed already 1403 * so return success for the GUP pin to be dropped. 1404 */ 1405 return ret && ret != -EHWPOISON ? ret : 0; 1406 } 1407 1408 /* 1409 * share/donate install at most one stage-2 leaf (PAGE_SIZE, or one 1410 * KVM_PGTABLE_LAST_LEVEL - 1 block for share). kvm_mmu_cache_min_pages() 1411 * bounds the worst-case allocation: exact for the PAGE_SIZE leaf, 1412 * conservative by one for the block. 1413 */ 1414 static int __guest_check_pgtable_memcache(struct pkvm_hyp_vcpu *vcpu) 1415 { 1416 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1417 1418 if (vcpu->vcpu.arch.pkvm_memcache.nr_pages < kvm_mmu_cache_min_pages(vm->pgt.mmu)) 1419 return -ENOMEM; 1420 1421 return 0; 1422 } 1423 1424 int __pkvm_host_donate_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu) 1425 { 1426 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1427 u64 phys = hyp_pfn_to_phys(pfn); 1428 u64 ipa = hyp_pfn_to_phys(gfn); 1429 u64 meta; 1430 int ret; 1431 1432 host_lock_component(); 1433 guest_lock_component(vm); 1434 1435 ret = __host_check_page_state_range(phys, PAGE_SIZE, PKVM_PAGE_OWNED); 1436 if (ret) 1437 goto unlock; 1438 1439 ret = __guest_check_page_state_range(vm, ipa, PAGE_SIZE, PKVM_NOPAGE); 1440 if (ret) 1441 goto unlock; 1442 1443 ret = __guest_check_pgtable_memcache(vcpu); 1444 if (ret) 1445 goto unlock; 1446 1447 meta = host_stage2_encode_gfn_meta(vm, gfn); 1448 WARN_ON(host_stage2_set_owner_metadata_locked(phys, PAGE_SIZE, 1449 PKVM_ID_GUEST, meta)); 1450 WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys, 1451 pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_OWNED), 1452 &vcpu->vcpu.arch.pkvm_memcache, 0)); 1453 1454 unlock: 1455 guest_unlock_component(vm); 1456 host_unlock_component(); 1457 1458 return ret; 1459 } 1460 1461 int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu *vcpu, 1462 enum kvm_pgtable_prot prot) 1463 { 1464 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1465 u64 phys = hyp_pfn_to_phys(pfn); 1466 u64 ipa = hyp_pfn_to_phys(gfn); 1467 u64 size; 1468 int ret; 1469 1470 if (prot & ~KVM_PGTABLE_PROT_RWX) 1471 return -EINVAL; 1472 1473 if (!pfn_range_is_valid(pfn, nr_pages)) 1474 return -EINVAL; 1475 1476 ret = __guest_check_transition_size(phys, ipa, nr_pages, &size); 1477 if (ret) 1478 return ret; 1479 1480 ret = check_range_allowed_memory(phys, phys + size); 1481 if (ret) 1482 return ret; 1483 1484 host_lock_component(); 1485 guest_lock_component(vm); 1486 1487 ret = __guest_check_page_state_range(vm, ipa, size, PKVM_NOPAGE); 1488 if (ret) 1489 goto unlock; 1490 1491 for_each_hyp_page(page, phys, size) { 1492 switch (get_host_state(page)) { 1493 case PKVM_PAGE_OWNED: 1494 continue; 1495 case PKVM_PAGE_SHARED_OWNED: 1496 if (page->host_share_guest_count == U32_MAX) { 1497 ret = -EBUSY; 1498 goto unlock; 1499 } 1500 1501 /* Only host to np-guest multi-sharing is tolerated */ 1502 if (page->host_share_guest_count) 1503 continue; 1504 1505 fallthrough; 1506 default: 1507 ret = -EPERM; 1508 goto unlock; 1509 } 1510 } 1511 1512 ret = __guest_check_pgtable_memcache(vcpu); 1513 if (ret) 1514 goto unlock; 1515 1516 for_each_hyp_page(page, phys, size) { 1517 set_host_state(page, PKVM_PAGE_SHARED_OWNED); 1518 page->host_share_guest_count++; 1519 } 1520 1521 WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, size, phys, 1522 pkvm_mkstate(prot, PKVM_PAGE_SHARED_BORROWED), 1523 &vcpu->vcpu.arch.pkvm_memcache, 0)); 1524 1525 unlock: 1526 guest_unlock_component(vm); 1527 host_unlock_component(); 1528 1529 return ret; 1530 } 1531 1532 static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ipa, u64 size) 1533 { 1534 enum pkvm_page_state state; 1535 kvm_pte_t pte; 1536 u64 phys; 1537 s8 level; 1538 int ret; 1539 1540 ret = kvm_pgtable_get_leaf(&vm->pgt, ipa, &pte, &level); 1541 if (ret) 1542 return ret; 1543 if (!kvm_pte_valid(pte)) 1544 return -ENOENT; 1545 if (size && kvm_granule_size(level) != size) 1546 return -E2BIG; 1547 1548 if (!size) 1549 size = kvm_granule_size(level); 1550 1551 state = guest_get_page_state(pte, ipa); 1552 if (state != PKVM_PAGE_SHARED_BORROWED) 1553 return -EPERM; 1554 1555 phys = kvm_pte_to_phys(pte); 1556 ret = check_range_allowed_memory(phys, phys + size); 1557 if (WARN_ON(ret)) 1558 return ret; 1559 1560 for_each_hyp_page(page, phys, size) { 1561 if (get_host_state(page) != PKVM_PAGE_SHARED_OWNED) 1562 return -EPERM; 1563 if (WARN_ON(!page->host_share_guest_count)) 1564 return -EINVAL; 1565 } 1566 1567 *__phys = phys; 1568 1569 return 0; 1570 } 1571 1572 int __pkvm_host_unshare_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *vm) 1573 { 1574 u64 ipa = hyp_pfn_to_phys(gfn); 1575 u64 size, phys; 1576 int ret; 1577 1578 ret = __guest_check_transition_size(0, ipa, nr_pages, &size); 1579 if (ret) 1580 return ret; 1581 1582 host_lock_component(); 1583 guest_lock_component(vm); 1584 1585 ret = __check_host_shared_guest(vm, &phys, ipa, size); 1586 if (ret) 1587 goto unlock; 1588 1589 ret = kvm_pgtable_stage2_unmap(&vm->pgt, ipa, size); 1590 if (ret) 1591 goto unlock; 1592 1593 for_each_hyp_page(page, phys, size) { 1594 /* __check_host_shared_guest() protects against underflow */ 1595 page->host_share_guest_count--; 1596 if (!page->host_share_guest_count) 1597 set_host_state(page, PKVM_PAGE_OWNED); 1598 } 1599 1600 unlock: 1601 guest_unlock_component(vm); 1602 host_unlock_component(); 1603 1604 return ret; 1605 } 1606 1607 static void assert_host_shared_guest(struct pkvm_hyp_vm *vm, u64 ipa, u64 size) 1608 { 1609 u64 phys; 1610 int ret; 1611 1612 if (!IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) 1613 return; 1614 1615 host_lock_component(); 1616 guest_lock_component(vm); 1617 1618 ret = __check_host_shared_guest(vm, &phys, ipa, size); 1619 1620 guest_unlock_component(vm); 1621 host_unlock_component(); 1622 1623 WARN_ON(ret && ret != -ENOENT); 1624 } 1625 1626 int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_pgtable_prot prot) 1627 { 1628 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1629 u64 ipa = hyp_pfn_to_phys(gfn); 1630 int ret; 1631 1632 if (pkvm_hyp_vm_is_protected(vm)) 1633 return -EPERM; 1634 1635 if (prot & ~KVM_PGTABLE_PROT_RWX) 1636 return -EINVAL; 1637 1638 assert_host_shared_guest(vm, ipa, 0); 1639 guest_lock_component(vm); 1640 ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0); 1641 guest_unlock_component(vm); 1642 1643 return ret; 1644 } 1645 1646 int __pkvm_host_wrprotect_guest(u64 gfn, u64 nr_pages, struct pkvm_hyp_vm *vm) 1647 { 1648 u64 size, ipa = hyp_pfn_to_phys(gfn); 1649 int ret; 1650 1651 if (pkvm_hyp_vm_is_protected(vm)) 1652 return -EPERM; 1653 1654 ret = __guest_check_transition_size(0, ipa, nr_pages, &size); 1655 if (ret) 1656 return ret; 1657 1658 assert_host_shared_guest(vm, ipa, size); 1659 guest_lock_component(vm); 1660 ret = kvm_pgtable_stage2_wrprotect(&vm->pgt, ipa, size); 1661 guest_unlock_component(vm); 1662 1663 return ret; 1664 } 1665 1666 int __pkvm_host_test_clear_young_guest(u64 gfn, u64 nr_pages, bool mkold, struct pkvm_hyp_vm *vm) 1667 { 1668 u64 size, ipa = hyp_pfn_to_phys(gfn); 1669 int ret; 1670 1671 if (pkvm_hyp_vm_is_protected(vm)) 1672 return -EPERM; 1673 1674 ret = __guest_check_transition_size(0, ipa, nr_pages, &size); 1675 if (ret) 1676 return ret; 1677 1678 assert_host_shared_guest(vm, ipa, size); 1679 guest_lock_component(vm); 1680 ret = kvm_pgtable_stage2_test_clear_young(&vm->pgt, ipa, size, mkold); 1681 guest_unlock_component(vm); 1682 1683 return ret; 1684 } 1685 1686 int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu) 1687 { 1688 struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1689 u64 ipa = hyp_pfn_to_phys(gfn); 1690 1691 if (pkvm_hyp_vm_is_protected(vm)) 1692 return -EPERM; 1693 1694 assert_host_shared_guest(vm, ipa, 0); 1695 guest_lock_component(vm); 1696 kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0); 1697 guest_unlock_component(vm); 1698 1699 return 0; 1700 } 1701 1702 #ifdef CONFIG_NVHE_EL2_DEBUG 1703 struct pkvm_expected_state { 1704 enum pkvm_page_state host; 1705 enum pkvm_page_state hyp; 1706 enum pkvm_page_state guest[2]; /* [ gfn, gfn + 1 ] */ 1707 }; 1708 1709 static struct pkvm_expected_state selftest_state; 1710 static struct hyp_page *selftest_page; 1711 static struct pkvm_hyp_vcpu *selftest_vcpu; 1712 1713 static u64 selftest_ipa(void) 1714 { 1715 return BIT(selftest_vcpu->vcpu.arch.hw_mmu->pgt->ia_bits - 1); 1716 } 1717 1718 static void assert_page_state(void) 1719 { 1720 void *virt = hyp_page_to_virt(selftest_page); 1721 u64 size = PAGE_SIZE << selftest_page->order; 1722 struct pkvm_hyp_vcpu *vcpu = selftest_vcpu; 1723 u64 phys = hyp_virt_to_phys(virt); 1724 u64 ipa[2] = { selftest_ipa(), selftest_ipa() + PAGE_SIZE }; 1725 struct pkvm_hyp_vm *vm; 1726 1727 vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1728 1729 host_lock_component(); 1730 WARN_ON(__host_check_page_state_range(phys, size, selftest_state.host)); 1731 host_unlock_component(); 1732 1733 hyp_lock_component(); 1734 WARN_ON(__hyp_check_page_state_range(phys, size, selftest_state.hyp)); 1735 hyp_unlock_component(); 1736 1737 guest_lock_component(vm); 1738 WARN_ON(__guest_check_page_state_range(vm, ipa[0], size, selftest_state.guest[0])); 1739 WARN_ON(__guest_check_page_state_range(vm, ipa[1], size, selftest_state.guest[1])); 1740 guest_unlock_component(vm); 1741 } 1742 1743 #define assert_transition_res(res, fn, ...) \ 1744 do { \ 1745 WARN_ON(fn(__VA_ARGS__) != res); \ 1746 assert_page_state(); \ 1747 } while (0) 1748 1749 void pkvm_ownership_selftest(void *base) 1750 { 1751 enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_RWX; 1752 void *virt = hyp_alloc_pages(&host_s2_pool, 0); 1753 struct pkvm_hyp_vcpu *vcpu; 1754 u64 phys, size, pfn, gfn; 1755 struct pkvm_hyp_vm *vm; 1756 1757 WARN_ON(!virt); 1758 selftest_page = hyp_virt_to_page(virt); 1759 selftest_page->refcount = 0; 1760 selftest_vcpu = vcpu = init_selftest_vm(base); 1761 vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu); 1762 1763 size = PAGE_SIZE << selftest_page->order; 1764 phys = hyp_virt_to_phys(virt); 1765 pfn = hyp_phys_to_pfn(phys); 1766 gfn = hyp_phys_to_pfn(selftest_ipa()); 1767 1768 selftest_state.host = PKVM_NOPAGE; 1769 selftest_state.hyp = PKVM_PAGE_OWNED; 1770 selftest_state.guest[0] = selftest_state.guest[1] = PKVM_NOPAGE; 1771 assert_page_state(); 1772 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1773 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1774 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1775 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1776 assert_transition_res(-EPERM, __pkvm_host_unshare_ffa, pfn, 1); 1777 assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); 1778 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1779 assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); 1780 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1781 1782 selftest_state.host = PKVM_PAGE_OWNED; 1783 selftest_state.hyp = PKVM_NOPAGE; 1784 assert_transition_res(0, __pkvm_hyp_donate_host, pfn, 1); 1785 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1786 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1787 assert_transition_res(-EPERM, __pkvm_host_unshare_ffa, pfn, 1); 1788 assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); 1789 assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); 1790 1791 selftest_state.host = PKVM_PAGE_SHARED_OWNED; 1792 selftest_state.hyp = PKVM_PAGE_SHARED_BORROWED; 1793 assert_transition_res(0, __pkvm_host_share_hyp, pfn); 1794 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1795 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1796 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1797 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1798 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1799 assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); 1800 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1801 1802 assert_transition_res(0, hyp_pin_shared_mem, virt, virt + size); 1803 assert_transition_res(0, hyp_pin_shared_mem, virt, virt + size); 1804 hyp_unpin_shared_mem(virt, virt + size); 1805 WARN_ON(hyp_page_count(virt) != 1); 1806 assert_transition_res(-EBUSY, __pkvm_host_unshare_hyp, pfn); 1807 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1808 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1809 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1810 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1811 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1812 assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); 1813 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1814 1815 hyp_unpin_shared_mem(virt, virt + size); 1816 assert_page_state(); 1817 WARN_ON(hyp_page_count(virt)); 1818 1819 selftest_state.host = PKVM_PAGE_OWNED; 1820 selftest_state.hyp = PKVM_NOPAGE; 1821 assert_transition_res(0, __pkvm_host_unshare_hyp, pfn); 1822 1823 selftest_state.host = PKVM_PAGE_SHARED_OWNED; 1824 selftest_state.hyp = PKVM_NOPAGE; 1825 assert_transition_res(0, __pkvm_host_share_ffa, pfn, 1); 1826 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1827 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1828 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1829 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1830 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1831 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1832 assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); 1833 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1834 assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); 1835 1836 selftest_state.host = PKVM_PAGE_OWNED; 1837 selftest_state.hyp = PKVM_NOPAGE; 1838 assert_transition_res(0, __pkvm_host_unshare_ffa, pfn, 1); 1839 assert_transition_res(-EPERM, __pkvm_host_unshare_ffa, pfn, 1); 1840 1841 selftest_state.host = PKVM_PAGE_SHARED_OWNED; 1842 selftest_state.guest[0] = PKVM_PAGE_SHARED_BORROWED; 1843 assert_transition_res(0, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1844 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1845 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1846 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1847 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1848 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1849 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1850 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1851 assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); 1852 1853 selftest_state.guest[1] = PKVM_PAGE_SHARED_BORROWED; 1854 assert_transition_res(0, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); 1855 WARN_ON(hyp_virt_to_page(virt)->host_share_guest_count != 2); 1856 1857 selftest_state.guest[0] = PKVM_NOPAGE; 1858 assert_transition_res(0, __pkvm_host_unshare_guest, gfn, 1, vm); 1859 1860 selftest_state.guest[1] = PKVM_NOPAGE; 1861 selftest_state.host = PKVM_PAGE_OWNED; 1862 assert_transition_res(0, __pkvm_host_unshare_guest, gfn + 1, 1, vm); 1863 1864 selftest_state.host = PKVM_NOPAGE; 1865 selftest_state.guest[0] = PKVM_PAGE_OWNED; 1866 assert_transition_res(0, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1867 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1868 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn + 1, vcpu); 1869 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1870 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); 1871 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1872 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1873 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1874 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1875 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1876 1877 selftest_state.host = PKVM_PAGE_SHARED_BORROWED; 1878 selftest_state.guest[0] = PKVM_PAGE_SHARED_OWNED; 1879 assert_transition_res(0, __pkvm_guest_share_host, vcpu, gfn); 1880 assert_transition_res(-EPERM, __pkvm_guest_share_host, vcpu, gfn); 1881 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1882 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn + 1, vcpu); 1883 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1884 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); 1885 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1886 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1887 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1888 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1889 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1890 1891 selftest_state.host = PKVM_NOPAGE; 1892 selftest_state.guest[0] = PKVM_PAGE_OWNED; 1893 assert_transition_res(0, __pkvm_guest_unshare_host, vcpu, gfn); 1894 assert_transition_res(-EPERM, __pkvm_guest_unshare_host, vcpu, gfn); 1895 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1896 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn + 1, vcpu); 1897 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1898 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); 1899 assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); 1900 assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); 1901 assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); 1902 assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); 1903 assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); 1904 1905 selftest_state.host = PKVM_PAGE_OWNED; 1906 selftest_state.guest[0] = PKVM_POISON; 1907 assert_transition_res(0, __pkvm_host_force_reclaim_page_guest, phys); 1908 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1909 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1910 assert_transition_res(-EHWPOISON, __pkvm_guest_share_host, vcpu, gfn); 1911 assert_transition_res(-EHWPOISON, __pkvm_guest_unshare_host, vcpu, gfn); 1912 1913 selftest_state.host = PKVM_NOPAGE; 1914 selftest_state.guest[1] = PKVM_PAGE_OWNED; 1915 assert_transition_res(0, __pkvm_host_donate_guest, pfn, gfn + 1, vcpu); 1916 1917 selftest_state.host = PKVM_PAGE_OWNED; 1918 selftest_state.guest[1] = PKVM_NOPAGE; 1919 assert_transition_res(0, __pkvm_host_reclaim_page_guest, gfn + 1, vm); 1920 assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); 1921 assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); 1922 1923 selftest_state.host = PKVM_NOPAGE; 1924 selftest_state.hyp = PKVM_PAGE_OWNED; 1925 assert_transition_res(0, __pkvm_host_donate_hyp, pfn, 1); 1926 1927 teardown_selftest_vm(); 1928 selftest_page->refcount = 1; 1929 hyp_put_page(&host_s2_pool, virt); 1930 } 1931 #endif 1932