[PATCH v2 06/18] KVM: arm64: Add topup interface for the pKVM heap allocator
Fuad Tabba
fuad.tabba at linux.dev
Tue Jul 14 12:28:00 PDT 2026
On Mon, 6 Jul 2026 at 18:54, Vincent Donnefort <vdonnefort at google.com> wrote:
>
> Introduce a host HVC interface and a host side helper to allow refilling
> the pKVM heap allocator.
>
> Signed-off-by: Vincent Donnefort <vdonnefort at google.com>
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 043495f7fc78..681b7bf8ac08 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -114,6 +114,7 @@ enum __kvm_host_smccc_func {
> __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
> __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
> + __KVM_HOST_SMCCC_FUNC___pkvm_hyp_topup,
>
> MARKER(__KVM_HOST_SMCCC_FUNC_MAX)
> };
> diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> index 74fedd9c5ff0..870f7870bb62 100644
> --- a/arch/arm64/include/asm/kvm_pkvm.h
> +++ b/arch/arm64/include/asm/kvm_pkvm.h
> @@ -17,6 +17,10 @@
>
> #define HYP_MEMBLOCK_REGIONS 128
>
> +enum pkvm_topup_id {
> + PKVM_TOPUP_HYP_ALLOC,
> +};
> +
> int pkvm_init_host_vm(struct kvm *kvm, unsigned long type);
> int pkvm_create_hyp_vm(struct kvm *kvm);
> bool pkvm_hyp_vm_is_created(struct kvm *kvm);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d3c69de698f4..e270a974fa37 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -15,6 +15,7 @@
> #include <asm/kvm_hypevents.h>
> #include <asm/kvm_mmu.h>
>
> +#include <nvhe/alloc.h>
> #include <nvhe/ffa.h>
> #include <nvhe/mem_protect.h>
> #include <nvhe/mm.h>
> @@ -632,6 +633,30 @@ static void handle___pkvm_finalize_teardown_vm(struct kvm_cpu_context *host_ctxt
> cpu_reg(host_ctxt, 1) = __pkvm_finalize_teardown_vm(handle);
> }
>
> +static void handle___pkvm_hyp_topup(struct kvm_cpu_context *host_ctxt)
Sashiko caught this. Suggest moving just this helper to patch 8
alongside its caller.
Cheers,
/fuad
> +{
> + DECLARE_REG(enum pkvm_topup_id, id, host_ctxt, 1);
> + DECLARE_REG(phys_addr_t, head, host_ctxt, 2);
> + DECLARE_REG(unsigned long, nr_pages, host_ctxt, 3);
> + struct kvm_hyp_memcache host_mc = {
> + .head = head,
> + .nr_pages = nr_pages,
> + };
> + int ret;
> +
> + switch (id) {
> + case PKVM_TOPUP_HYP_ALLOC:
> + ret = hyp_alloc_topup(&host_mc);
> + break;
> + default:
> + ret = -EINVAL;
> + }
> +
> + cpu_reg(host_ctxt, 1) = ret;
> + cpu_reg(host_ctxt, 2) = host_mc.head;
> + cpu_reg(host_ctxt, 3) = host_mc.nr_pages;
> +}
> +
> static void handle___tracing_load(struct kvm_cpu_context *host_ctxt)
> {
> DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1);
> @@ -762,6 +787,7 @@ static const hcall_t host_hcall[] = {
> HANDLE_FUNC(__pkvm_vcpu_load),
> HANDLE_FUNC(__pkvm_vcpu_put),
> HANDLE_FUNC(__pkvm_tlb_flush_vmid),
> + HANDLE_FUNC(__pkvm_hyp_topup),
> };
>
> static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> index 8324a6a1bc48..e2c8714e8ccc 100644
> --- a/arch/arm64/kvm/pkvm.c
> +++ b/arch/arm64/kvm/pkvm.c
> @@ -85,6 +85,33 @@ void __init kvm_hyp_reserve(void)
> hyp_mem_base);
> }
>
> +static int pkvm_hyp_topup(enum pkvm_topup_id id, unsigned long nr_pages)
> +{
> + struct kvm_hyp_memcache mc;
> + struct arm_smccc_res res;
> + int ret;
> +
> + init_hyp_memcache(&mc);
> + ret = topup_hyp_memcache(&mc, nr_pages);
> + if (ret)
> + goto err;
> +
> + arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__pkvm_hyp_topup), id, mc.head,
> + mc.nr_pages, &res);
> + if (WARN_ON_ONCE(res.a0 != SMCCC_RET_SUCCESS)) {
> + ret = -EINVAL;
> + goto err;
> + }
> +
> + ret = res.a1;
> + mc.head = res.a2;
> + mc.nr_pages = res.a3;
> +
> +err:
> + free_hyp_memcache(&mc);
> + return ret;
> +}
> +
> static void __pkvm_destroy_hyp_vm(struct kvm *kvm)
> {
> if (pkvm_hyp_vm_is_created(kvm)) {
> --
> 2.55.0.rc2.803.g1fd1e6609c-goog
>
More information about the linux-arm-kernel
mailing list