Re: [PATCH v4 17/17] KVM: arm64: Alloc simple_buffer_page using pKVM hyp allocator
Fuad Tabba <[email protected]>
| Newsgroups | dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel |
|---|---|
| Message-ID | <CA+EHjTzGbZnz_SdcMvVwwDTTyHbyjAwukK-A90z2oVJtaBGz3g@mail.gmail.com> |
On Fri, 31 Jul 2026 at 15:36, Vincent Donnefort <[email protected]> wrote: > > In protected mode, transition the allocation of the simple_ring_buffer > structures from the host to the hypervisor using the new pKVM heap > allocator. > > Previously, the host allocated and donated a contiguous backing memory > for these structures. In pKVM the hypervisor can now allocate them > dynamically. > > Use the pkvm_call_hyp_req() wrapper in the host to invoke > __tracing_load, which automatically handles any top-up requests if the > hypervisor runs out of heap memory during allocation. > > Tested-by: Fuad Tabba <[email protected]> > Signed-off-by: Vincent Donnefort <[email protected]> Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c > index 9bab1e802281..ec5bb8541ceb 100644 > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c > @@ -750,7 +750,7 @@ static void handle___tracing_load(struct kvm_cpu_context *host_ctxt) > DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1); > DECLARE_REG(size_t, desc_size, host_ctxt, 2); > > - cpu_reg(host_ctxt, 1) = __tracing_load(desc_hva, desc_size); > + errno_to_smccc(__tracing_load(desc_hva, desc_size), host_ctxt); > } > > static void handle___tracing_unload(struct kvm_cpu_context *host_ctxt) > diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trace.c > index 96afa3d6de2f..5ff19d210508 100644 > --- a/arch/arm64/kvm/hyp/nvhe/trace.c > +++ b/arch/arm64/kvm/hyp/nvhe/trace.c > @@ -4,6 +4,7 @@ > * Author: Vincent Donnefort <[email protected]> > */ > > +#include <nvhe/alloc.h> > #include <nvhe/clock.h> > #include <nvhe/mem_protect.h> > #include <nvhe/mm.h> > @@ -62,18 +63,34 @@ static void __release_host_mem(void *start, u64 size) > WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(start), size >> PAGE_SHIFT)); > } > > -static int hyp_trace_buffer_load_bpage_backing(struct hyp_trace_buffer *trace_buffer, > - struct hyp_trace_desc *desc) > +static int hyp_trace_buffer_alloc_bpages(struct hyp_trace_buffer *trace_buffer, > + struct hyp_trace_desc *desc) > { > - void *start = (void *)kern_hyp_va(desc->bpages_backing_start); > - size_t size = desc->bpages_backing_size; > + void *start; > + size_t size; > int ret; > > - ret = __admit_host_mem(start, size); > - if (ret) > - return ret; > + if (is_protected_kvm_enabled()) { > + struct ring_buffer_desc *rb_desc; > + int cpu; > > - memset(start, 0, size); > + size = 0; > + for_each_ring_buffer_desc(rb_desc, cpu, &desc->trace_buffer_desc) > + size += rb_desc->nr_page_va * sizeof(struct simple_buffer_page); > + > + start = hyp_alloc(size); > + if (!start) > + return hyp_alloc_errno(); > + } else { > + start = (void *)kern_hyp_va(desc->bpages_backing_start); > + size = desc->bpages_backing_size; > + > + ret = __admit_host_mem(start, size); > + if (ret) > + return ret; > + > + memset(start, 0, size); > + } > > trace_buffer->bpages_backing_start = start; > trace_buffer->bpages_backing_size = size; > @@ -81,7 +98,7 @@ static int hyp_trace_buffer_load_bpage_backing(struct hyp_trace_buffer *trace_bu > return 0; > } > > -static void hyp_trace_buffer_unload_bpage_backing(struct hyp_trace_buffer *trace_buffer) > +static void hyp_trace_buffer_free_bpages(struct hyp_trace_buffer *trace_buffer) > { > void *start = trace_buffer->bpages_backing_start; > size_t size = trace_buffer->bpages_backing_size; > @@ -89,9 +106,12 @@ static void hyp_trace_buffer_unload_bpage_backing(struct hyp_trace_buffer *trace > if (!size) > return; > > - memset(start, 0, size); > - > - __release_host_mem(start, size); > + if (is_protected_kvm_enabled()) { > + hyp_free(start); > + } else { > + memset(start, 0, size); > + __release_host_mem(start, size); > + } > > trace_buffer->bpages_backing_start = 0; > trace_buffer->bpages_backing_size = 0; > @@ -128,7 +148,7 @@ static void hyp_trace_buffer_unload(struct hyp_trace_buffer *trace_buffer) > simple_ring_buffer_unload_mm(per_cpu_ptr(trace_buffer->simple_rbs, cpu), > __unpin_shared_page); > > - hyp_trace_buffer_unload_bpage_backing(trace_buffer); > + hyp_trace_buffer_free_bpages(trace_buffer); > } > > static int hyp_trace_buffer_load(struct hyp_trace_buffer *trace_buffer, > @@ -143,7 +163,7 @@ static int hyp_trace_buffer_load(struct hyp_trace_buffer *trace_buffer, > if (hyp_trace_buffer_loaded(trace_buffer)) > return -EINVAL; > > - ret = hyp_trace_buffer_load_bpage_backing(trace_buffer, desc); > + ret = hyp_trace_buffer_alloc_bpages(trace_buffer, desc); > if (ret) > return ret; > > @@ -168,18 +188,16 @@ static bool hyp_trace_desc_is_valid(struct hyp_trace_desc *desc, size_t desc_siz > { > struct ring_buffer_desc *rb_desc; > unsigned int cpu; > - size_t nr_bpages; > void *desc_end; > > if (!is_protected_kvm_enabled()) > return true; > > /* > - * Both desc_size and bpages_backing_size are untrusted host-provided > - * values. We rely on __pkvm_host_donate_hyp() to enforce their validity. > + * desc_size is an untrusted host-provided value. We rely on > + * __pkvm_host_donate_hyp() to enforce its validity. > */ > desc_end = (void *)desc + desc_size; > - nr_bpages = desc->bpages_backing_size / sizeof(struct simple_buffer_page); > > if (desc->trace_buffer_desc.nr_cpus != hyp_nr_cpus) > return false; > @@ -197,17 +215,8 @@ static bool hyp_trace_desc_is_valid(struct hyp_trace_desc *desc, size_t desc_siz > if ((void *)rb_desc + struct_size(rb_desc, page_va, rb_desc->nr_page_va) > desc_end) > return false; > > - /* Overflow bpages backing memory? */ > - if (nr_bpages < rb_desc->nr_page_va) > - return false; > - > - if (cpu >= hyp_nr_cpus) > - return false; > - > if (cpu != rb_desc->cpu) > return false; > - > - nr_bpages -= rb_desc->nr_page_va; > } > > return true; > diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c > index 2411b4c32932..859a926c815f 100644 > --- a/arch/arm64/kvm/hyp_trace.c > +++ b/arch/arm64/kvm/hyp_trace.c > @@ -13,6 +13,7 @@ > #include <asm/kvm_host.h> > #include <asm/kvm_hyptrace.h> > #include <asm/kvm_mmu.h> > +#include <asm/kvm_pkvm.h> > > #include "hyp_trace.h" > > @@ -157,10 +158,17 @@ static void __unshare_page(unsigned long va) > > static int hyp_trace_buffer_alloc_bpages_backing(struct hyp_trace_buffer *trace_buffer, size_t size) > { > - int nr_bpages = (PAGE_ALIGN(size) / PAGE_SIZE) + 1; > size_t backing_size; > + int nr_bpages; > void *start; > > + if (is_protected_kvm_enabled()) { > + trace_buffer->desc->bpages_backing_start = 0; > + trace_buffer->desc->bpages_backing_size = 0; > + return 0; > + } > + > + nr_bpages = (PAGE_ALIGN(size) / PAGE_SIZE) + 1; > backing_size = PAGE_ALIGN(sizeof(struct simple_buffer_page) * nr_bpages * > num_possible_cpus()); > > @@ -176,6 +184,9 @@ static int hyp_trace_buffer_alloc_bpages_backing(struct hyp_trace_buffer *trace_ > > static void hyp_trace_buffer_free_bpages_backing(struct hyp_trace_buffer *trace_buffer) > { > + if (!trace_buffer->desc->bpages_backing_start) > + return; > + > free_pages_exact((void *)trace_buffer->desc->bpages_backing_start, > trace_buffer->desc->bpages_backing_size); > } > @@ -264,7 +275,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv) > if (ret) > goto err_free_buffer; > > - ret = kvm_call_hyp_nvhe(__tracing_load, (unsigned long)desc, desc_size); > + ret = pkvm_call_hyp_req(__tracing_load, (unsigned long)desc, desc_size); > if (ret) > goto err_unload_pages; > > -- > 2.55.0.508.g3f0d502094-goog >