[PATCH 06/20] KVM: arm64: Add a range to __pkvm_host_share/unshare_hyp()
Vincent Donnefort <[email protected]> Mon, 3 Aug 2026 11:08:50 +0100
| Newsgroups | dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel |
|---|---|
| Message-ID | <[email protected]> |
Nothing prevents the host/hyp sharing transition to work on a range. In preparation for testing huge-mapping with the pKVM ownership selftest, add a range to these hypercalls to allow them to be tested just like the others without any special case. Signed-off-by: Vincent Donnefort <[email protected]> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index e2a5d7ffec7d..1f70162fa625 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -31,10 +31,10 @@ enum pkvm_component_id { }; int __pkvm_prot_finalize(void); -int __pkvm_host_share_hyp(u64 pfn); +int __pkvm_host_share_hyp(u64 pfn, u64 nr_pages); int __pkvm_guest_share_host(struct pkvm_hyp_vcpu *vcpu, u64 gfn); int __pkvm_guest_unshare_host(struct pkvm_hyp_vcpu *vcpu, u64 gfn); -int __pkvm_host_unshare_hyp(u64 pfn); +int __pkvm_host_unshare_hyp(u64 pfn, u64 nr_pages); int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages); int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages); int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages); diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index a327c2bbb6b6..a6e12f240c50 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -263,13 +263,13 @@ static void do_ffa_rxtx_map(struct arm_smccc_1_2_regs *res, if (ret) goto out_unlock; - ret = __pkvm_host_share_hyp(hyp_phys_to_pfn(tx)); + ret = __pkvm_host_share_hyp(hyp_phys_to_pfn(tx), 1); if (ret) { ret = FFA_RET_INVALID_PARAMETERS; goto err_unmap; } - ret = __pkvm_host_share_hyp(hyp_phys_to_pfn(rx)); + ret = __pkvm_host_share_hyp(hyp_phys_to_pfn(rx), 1); if (ret) { ret = FFA_RET_INVALID_PARAMETERS; goto err_unshare_tx; @@ -301,9 +301,9 @@ static void do_ffa_rxtx_map(struct arm_smccc_1_2_regs *res, err_unpin_tx: hyp_unpin_shared_mem(tx_virt, tx_virt + 1); err_unshare_rx: - __pkvm_host_unshare_hyp(hyp_phys_to_pfn(rx)); + __pkvm_host_unshare_hyp(hyp_phys_to_pfn(rx), 1); err_unshare_tx: - __pkvm_host_unshare_hyp(hyp_phys_to_pfn(tx)); + __pkvm_host_unshare_hyp(hyp_phys_to_pfn(tx), 1); err_unmap: ffa_unmap_hyp_buffers(); goto out_unlock; @@ -327,11 +327,11 @@ static void do_ffa_rxtx_unmap(struct arm_smccc_1_2_regs *res, } hyp_unpin_shared_mem(host_buffers.tx, host_buffers.tx + 1); - WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_buffers.tx))); + WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_buffers.tx), 1)); host_buffers.tx = NULL; hyp_unpin_shared_mem(host_buffers.rx, host_buffers.rx + 1); - WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_buffers.rx))); + WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_buffers.rx), 1)); host_buffers.rx = NULL; ffa_unmap_hyp_buffers(); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index bed3ba8e48e5..c922288a77e6 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -522,14 +522,14 @@ static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(u64, pfn, host_ctxt, 1); - cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(pfn); + cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(pfn, 1); } static void handle___pkvm_host_unshare_hyp(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(u64, pfn, host_ctxt, 1); - cpu_reg(host_ctxt, 1) = __pkvm_host_unshare_hyp(pfn); + cpu_reg(host_ctxt, 1) = __pkvm_host_unshare_hyp(pfn, 1); } static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index b917537f12a7..3118941a11a7 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -962,12 +962,15 @@ int __pkvm_vcpu_in_poison_fault(struct pkvm_hyp_vcpu *hyp_vcpu) return ret; } -int __pkvm_host_share_hyp(u64 pfn) +int __pkvm_host_share_hyp(u64 pfn, u64 nr_pages) { u64 phys = hyp_pfn_to_phys(pfn); - u64 size = PAGE_SIZE; + u64 size = PAGE_SIZE * nr_pages; int ret; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + host_lock_component(); hyp_lock_component(); @@ -1054,12 +1057,15 @@ int __pkvm_guest_unshare_host(struct pkvm_hyp_vcpu *vcpu, u64 gfn) return ret; } -int __pkvm_host_unshare_hyp(u64 pfn) +int __pkvm_host_unshare_hyp(u64 pfn, u64 nr_pages) { u64 phys = hyp_pfn_to_phys(pfn); - u64 size = PAGE_SIZE; + u64 size = PAGE_SIZE * nr_pages; int ret; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + host_lock_component(); hyp_lock_component(); @@ -1777,8 +1783,8 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr selftest_state.guest[0] = selftest_state.guest[1] = PKVM_NOPAGE; assert_page_state(); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_unshare_ffa, pfn, 1); assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); @@ -1790,15 +1796,15 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr selftest_state.hyp = PKVM_NOPAGE; assert_transition_res(0, __pkvm_hyp_donate_host, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_unshare_ffa, pfn, 1); assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); selftest_state.host = PKVM_PAGE_SHARED_OWNED; selftest_state.hyp = PKVM_PAGE_SHARED_BORROWED; - assert_transition_res(0, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); + assert_transition_res(0, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); @@ -1810,8 +1816,8 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr assert_transition_res(0, hyp_pin_shared_mem, virt, virt + size); hyp_unpin_shared_mem(virt, virt + size); WARN_ON(hyp_page_count(virt) != 1); - assert_transition_res(-EBUSY, __pkvm_host_unshare_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); + assert_transition_res(-EBUSY, __pkvm_host_unshare_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); @@ -1825,15 +1831,15 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr selftest_state.host = PKVM_PAGE_OWNED; selftest_state.hyp = PKVM_NOPAGE; - assert_transition_res(0, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(0, __pkvm_host_unshare_hyp, pfn, 1); selftest_state.host = PKVM_PAGE_SHARED_OWNED; selftest_state.hyp = PKVM_NOPAGE; assert_transition_res(0, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); assert_transition_res(-ENOENT, __pkvm_host_unshare_guest, gfn, 1, vm); @@ -1851,8 +1857,8 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn, 1, vcpu, prot); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_guest, pfn, gfn, vcpu); assert_transition_res(-EPERM, hyp_pin_shared_mem, virt, virt + size); @@ -1877,8 +1883,8 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); selftest_state.host = PKVM_PAGE_SHARED_BORROWED; @@ -1891,8 +1897,8 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); selftest_state.host = PKVM_NOPAGE; @@ -1905,8 +1911,8 @@ int __pkvm_ownership_selftest(u64 pfn, u64 pgtable_pfn, unsigned long pgtable_nr assert_transition_res(-EPERM, __pkvm_host_share_guest, pfn, gfn + 1, 1, vcpu, prot); assert_transition_res(-EPERM, __pkvm_host_share_ffa, pfn, 1); assert_transition_res(-EPERM, __pkvm_host_donate_hyp, pfn, 1); - assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn); - assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn); + assert_transition_res(-EPERM, __pkvm_host_share_hyp, pfn, 1); + assert_transition_res(-EPERM, __pkvm_host_unshare_hyp, pfn, 1); assert_transition_res(-EPERM, __pkvm_hyp_donate_host, pfn, 1); selftest_state.host = PKVM_PAGE_OWNED; -- 2.55.0.508.g3f0d502094-goog