[PATCH v4 07/17] KVM: arm64: Add PKVM_HYP_REQ_HYP_ALLOC request
Fuad Tabba
fuad.tabba at linux.dev
Tue Aug 18 08:12:07 PDT 2026
On Fri, 31 Jul 2026 at 15:36, 'Vincent Donnefort' via kernel-team
<kernel-team at android.com> wrote:
>
> Introduce a new pkvm_hyp_request type asking the host to top up the pKVM
> heap allocator.
>
> Tested-by: Fuad Tabba <fuad.tabba at linux.dev>
> Signed-off-by: Vincent Donnefort <vdonnefort at google.com>
Reviewed-by: Fuad Tabba <fuad.tabba at linux.dev>
Cheers,
/fuad
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 043495f7fc78..b77acfd7d1c8 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -89,6 +89,7 @@ enum __kvm_host_smccc_func {
> __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
> __KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
> __KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
> + __KVM_HOST_SMCCC_FUNC___pkvm_hyp_topup,
>
> MARKER(__KVM_HOST_SMCCC_FUNC_PKVM_ONLY),
>
> diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
> index 6c2497047f8d..99daa985856f 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);
> @@ -201,6 +205,7 @@ struct pkvm_mapping {
>
> enum pkvm_hyp_req_type {
> PKVM_HYP_NO_REQ = 0,
> + PKVM_HYP_REQ_HYP_ALLOC,
> __PKVM_HYP_REQ_TYPE_MAX,
> };
>
> @@ -222,9 +227,13 @@ struct pkvm_hyp_req {
>
> static inline size_t pkvm_hyp_req_arg_size(u8 type)
> {
> + struct pkvm_hyp_req *req;
> +
> switch (type) {
> case PKVM_HYP_NO_REQ:
> return 0;
> + case PKVM_HYP_REQ_HYP_ALLOC:
> + return sizeof(req->mem);
> default:
> WARN_ON(1);
> }
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d3c69de698f4..439b91fc8aec 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)
> +{
> + 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);
> @@ -740,6 +765,7 @@ static const hcall_t host_hcall[] = {
> HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
> HANDLE_FUNC(__vgic_v5_save_apr),
> HANDLE_FUNC(__vgic_v5_restore_vmcr_apr),
> + HANDLE_FUNC(__pkvm_hyp_topup),
>
> HANDLE_FUNC(__pkvm_host_share_hyp),
> HANDLE_FUNC(__pkvm_host_unshare_hyp),
> diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
> index a626978dc91f..d26e7435d34d 100644
> --- a/arch/arm64/kvm/pkvm.c
> +++ b/arch/arm64/kvm/pkvm.c
> @@ -88,6 +88,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)) {
> @@ -599,6 +626,9 @@ static int pkvm_handle_hyp_req(struct pkvm_hyp_req *req)
> int ret = -EINVAL;
>
> switch (req->type) {
> + case PKVM_HYP_REQ_HYP_ALLOC:
> + ret = pkvm_hyp_topup(PKVM_TOPUP_HYP_ALLOC, req->mem.nr_pages);
> + break;
> }
>
> trace_kvm_handle_pkvm_hyp_req(req, ret);
> diff --git a/arch/arm64/kvm/trace_pkvm.h b/arch/arm64/kvm/trace_pkvm.h
> index 3966c111e3ad..493225e3282d 100644
> --- a/arch/arm64/kvm/trace_pkvm.h
> +++ b/arch/arm64/kvm/trace_pkvm.h
> @@ -9,9 +9,11 @@
> #define TRACE_SYSTEM kvm
>
> TRACE_DEFINE_ENUM(PKVM_HYP_NO_REQ);
> +TRACE_DEFINE_ENUM(PKVM_HYP_REQ_HYP_ALLOC);
>
> -#define PKVM_HYP_REQ_TYPES \
> - { PKVM_HYP_NO_REQ, "NO_REQ" }
> +#define PKVM_HYP_REQ_TYPES \
> + { PKVM_HYP_NO_REQ, "NO_REQ" }, \
> + { PKVM_HYP_REQ_HYP_ALLOC, "HYP_ALLOC" }
>
> TRACE_EVENT(kvm_handle_pkvm_hyp_req,
> TP_PROTO(struct pkvm_hyp_req *req, int ret),
> --
> 2.55.0.508.g3f0d502094-goog
>
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe at android.com.
>
More information about the linux-arm-kernel
mailing list