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