From: Vincent Donnefort <vdonnefort@google.com>
To: maz@kernel.org, oupton@kernel.org, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org
Cc: joey.gouly@arm.com, seiden@linux.ibm.com, suzuki.poulose@arm.com,
yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org,
kernel-team@android.com, tabba@google.com, qperret@google.com,
Vincent Donnefort <vdonnefort@google.com>
Subject: [PATCH v3 14/17] KVM: arm64: Alloc pkvm_hyp_vcpu using pKVM heap allocator
Date: Mon, 20 Jul 2026 18:15:10 +0100 [thread overview]
Message-ID: <20260720171513.1415357-15-vdonnefort@google.com> (raw)
In-Reply-To: <20260720171513.1415357-1-vdonnefort@google.com>
Transition the allocation of the hypervisor vCPU state structure
(pkvm_hyp_vcpu) from the host to the hypervisor using the new pKVM heap
allocator (hyp_alloc()).
Previously, the host was responsible for calculating the size of,
allocating, and donating memory for pkvm_hyp_vcpu during VM creation.
With the heap allocator in place, the hypervisor now allocates this
structure dynamically at EL2.
Use the pkvm_call_hyp_req() wrapper in the host to invoke
__pkvm_create_hyp_vcpu, which automatically handles any top-up requests
if the hypervisor runs out of heap memory during allocation.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index caea8e9986d1..95e05cee0f3a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -268,7 +268,6 @@ typedef u16 pkvm_handle_t;
struct kvm_protected_vm {
pkvm_handle_t handle;
- struct kvm_hyp_memcache teardown_mc;
struct kvm_hyp_memcache stage2_teardown_mc;
bool is_protected;
bool is_created;
diff --git a/arch/arm64/kvm/hyp/hyp-constants.c b/arch/arm64/kvm/hyp/hyp-constants.c
index 501ab35a3840..b2caae21f271 100644
--- a/arch/arm64/kvm/hyp/hyp-constants.c
+++ b/arch/arm64/kvm/hyp/hyp-constants.c
@@ -7,6 +7,5 @@
int main(void)
{
DEFINE(STRUCT_HYP_PAGE_SIZE, sizeof(struct hyp_page));
- DEFINE(PKVM_HYP_VCPU_SIZE, sizeof(struct pkvm_hyp_vcpu));
return 0;
}
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 8e930c8729af..cfb6e409bf49 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -83,8 +83,7 @@ void pkvm_hyp_vm_table_init(void *tbl);
int __pkvm_reserve_vm(void);
void __pkvm_unreserve_vm(pkvm_handle_t handle);
int __pkvm_init_vm(struct kvm *host_kvm, void *pgd);
-int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
- unsigned long vcpu_hva);
+int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu);
int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 gfn);
int __pkvm_start_teardown_vm(pkvm_handle_t handle);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 595db3a936fe..01e7ffc489f5 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -605,10 +605,9 @@ static void handle___pkvm_init_vcpu(struct kvm_cpu_context *host_ctxt)
{
DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 2);
- DECLARE_REG(unsigned long, vcpu_hva, host_ctxt, 3);
host_vcpu = kern_hyp_va(host_vcpu);
- cpu_reg(host_ctxt, 1) = __pkvm_init_vcpu(handle, host_vcpu, vcpu_hva);
+ errno_to_smccc(__pkvm_init_vcpu(handle, host_vcpu), host_ctxt);
}
static void handle___pkvm_vcpu_in_poison_fault(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index 09f609db8556..fffd2f4bc071 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -645,30 +645,6 @@ static size_t pkvm_get_hyp_vm_size(unsigned int nr_vcpus)
size_mul(sizeof(struct pkvm_hyp_vcpu *), nr_vcpus));
}
-static void *map_donated_memory_noclear(unsigned long host_va, size_t size)
-{
- void *va = (void *)kern_hyp_va(host_va);
-
- if (!PAGE_ALIGNED(va))
- return NULL;
-
- if (__pkvm_host_donate_hyp(hyp_virt_to_pfn(va),
- PAGE_ALIGN(size) >> PAGE_SHIFT))
- return NULL;
-
- return va;
-}
-
-static void *map_donated_memory(unsigned long host_va, size_t size)
-{
- void *va = map_donated_memory_noclear(host_va, size);
-
- if (va)
- memset(va, 0, size);
-
- return va;
-}
-
static void __unmap_donated_memory(void *va, size_t size)
{
kvm_flush_dcache_to_poc(va, size);
@@ -896,16 +872,15 @@ static int register_hyp_vcpu(struct pkvm_hyp_vm *hyp_vm,
return 0;
}
-int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
- unsigned long vcpu_hva)
+int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu)
{
struct pkvm_hyp_vcpu *hyp_vcpu;
struct pkvm_hyp_vm *hyp_vm;
int ret;
- hyp_vcpu = map_donated_memory(vcpu_hva, sizeof(*hyp_vcpu));
+ hyp_vcpu = hyp_alloc(sizeof(*hyp_vcpu));
if (!hyp_vcpu)
- return -ENOMEM;
+ return hyp_alloc_errno();
hyp_spin_lock(&vm_table_lock);
@@ -926,24 +901,12 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
}
unlock:
hyp_spin_unlock(&vm_table_lock);
-
if (ret)
- unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu));
+ hyp_free(hyp_vcpu);
+
return ret;
}
-static void
-teardown_donated_memory(struct kvm_hyp_memcache *mc, void *addr, size_t size)
-{
- size = PAGE_ALIGN(size);
- memset(addr, 0, size);
-
- for (void *start = addr; start < addr + size; start += PAGE_SIZE)
- push_hyp_memcache(mc, start, hyp_virt_to_phys);
-
- unmap_donated_memory_noclear(addr, size);
-}
-
int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 gfn)
{
struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
@@ -993,7 +956,7 @@ int __pkvm_start_teardown_vm(pkvm_handle_t handle)
int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
{
- struct kvm_hyp_memcache *mc, *stage2_mc;
+ struct kvm_hyp_memcache *stage2_mc;
struct pkvm_hyp_vm *hyp_vm;
struct kvm *host_kvm;
unsigned int idx;
@@ -1014,7 +977,6 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
hyp_spin_unlock(&vm_table_lock);
/* Reclaim guest pages (including page-table pages) */
- mc = &host_kvm->arch.pkvm.teardown_mc;
stage2_mc = &host_kvm->arch.pkvm.stage2_teardown_mc;
reclaim_pgtable_pages(hyp_vm, stage2_mc);
unpin_host_vcpus(hyp_vm->vcpus, hyp_vm->kvm.created_vcpus);
@@ -1036,7 +998,7 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
unmap_donated_memory_noclear(addr, PAGE_SIZE);
}
- teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
+ hyp_free(hyp_vcpu);
}
hyp_free(hyp_vm);
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index a9b85ad37787..3b29b3f43ffa 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -153,28 +153,19 @@ static void __pkvm_destroy_hyp_vm(struct kvm *kvm)
kvm->arch.pkvm.handle = 0;
kvm->arch.pkvm.is_created = false;
- free_hyp_memcache(&kvm->arch.pkvm.teardown_mc);
free_hyp_memcache(&kvm->arch.pkvm.stage2_teardown_mc);
}
static int __pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu)
{
- size_t hyp_vcpu_sz = PAGE_ALIGN(PKVM_HYP_VCPU_SIZE);
pkvm_handle_t handle = vcpu->kvm->arch.pkvm.handle;
- void *hyp_vcpu;
int ret;
init_hyp_stage2_memcache(&vcpu->arch.pkvm_memcache);
- hyp_vcpu = alloc_pages_exact(hyp_vcpu_sz, GFP_KERNEL_ACCOUNT);
- if (!hyp_vcpu)
- return -ENOMEM;
-
- ret = kvm_call_hyp_nvhe(__pkvm_init_vcpu, handle, vcpu, hyp_vcpu);
+ ret = pkvm_call_hyp_req(__pkvm_init_vcpu, handle, vcpu);
if (!ret)
vcpu_set_flag(vcpu, VCPU_PKVM_FINALIZED);
- else
- free_pages_exact(hyp_vcpu, hyp_vcpu_sz);
return ret;
}
--
2.55.0.229.g6434b31f56-goog
next prev parent reply other threads:[~2026-07-20 17:15 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 17:14 [PATCH v3 00/17] KVM: arm64: Introduce pKVM hypervisor heap allocator Vincent Donnefort
2026-07-20 17:14 ` [PATCH v3 01/17] KVM: arm64: Add pkvm_private_va_range_pa Vincent Donnefort
2026-07-20 17:25 ` sashiko-bot
2026-07-20 17:14 ` [PATCH v3 02/17] KVM: arm64: Add pkvm_remove_mappings Vincent Donnefort
2026-07-20 17:27 ` sashiko-bot
2026-07-20 17:14 ` [PATCH v3 03/17] KVM: arm64: Add pkvm_map_private_va_range Vincent Donnefort
2026-07-20 17:29 ` sashiko-bot
2026-07-20 17:15 ` [PATCH v3 04/17] KVM: arm64: Add a heap allocator for the pKVM hyp Vincent Donnefort
2026-07-20 17:26 ` sashiko-bot
2026-07-20 17:15 ` [PATCH v3 05/17] KVM: arm64: Allow kvm_hyp_memcache usage outside of stage-2 Vincent Donnefort
2026-07-20 17:15 ` [PATCH v3 06/17] KVM: arm64: Add pkvm_hyp_req infrastructure Vincent Donnefort
2026-07-20 17:15 ` [PATCH v3 07/17] KVM: arm64: Add PKVM_HYP_REQ_HYP_ALLOC request Vincent Donnefort
2026-07-20 17:36 ` sashiko-bot
2026-07-20 17:15 ` [PATCH v3 08/17] KVM: arm64: Add reclaim interface for the pKVM heap alloc Vincent Donnefort
2026-07-20 17:32 ` sashiko-bot
2026-07-20 17:15 ` [PATCH v3 09/17] KVM: arm64: Add selftests for the pKVM heap allocator Vincent Donnefort
2026-07-20 17:31 ` sashiko-bot
2026-07-20 17:15 ` [PATCH v3 10/17] KVM: arm64: Add a shrinker for pKVM Vincent Donnefort
2026-07-20 17:15 ` [PATCH v3 11/17] KVM: arm64: Filter out non-kernel addresses in kern_hyp_va Vincent Donnefort
2026-07-20 17:28 ` sashiko-bot
2026-07-20 17:15 ` [PATCH v3 12/17] KVM: arm64: Move hyp_vm refcount into the structure Vincent Donnefort
2026-07-20 17:15 ` [PATCH v3 13/17] KVM: arm64: Alloc pkvm_hyp_vm using pKVM heap allocator Vincent Donnefort
2026-07-20 17:44 ` sashiko-bot
2026-07-20 17:15 ` Vincent Donnefort [this message]
2026-07-20 17:41 ` [PATCH v3 14/17] KVM: arm64: Alloc pkvm_hyp_vcpu " sashiko-bot
2026-07-20 17:15 ` [PATCH v3 15/17] KVM: arm64: Reject hyp trace descriptors with fewer CPUs than hyp_nr_cpus Vincent Donnefort
2026-07-20 17:15 ` [PATCH v3 16/17] KVM: arm64: Reject hyp trace descriptors with fewer than 3 pages Vincent Donnefort
2026-07-20 17:15 ` [PATCH v3 17/17] KVM: arm64: Alloc simple_buffer_page using pKVM hyp allocator Vincent Donnefort
2026-07-20 17:47 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260720171513.1415357-15-vdonnefort@google.com \
--to=vdonnefort@google.com \
--cc=catalin.marinas@arm.com \
--cc=joey.gouly@arm.com \
--cc=kernel-team@android.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=qperret@google.com \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.