[PATCH v3 03/17] KVM: arm64: Add pkvm_map_private_va_range
Fuad Tabba
tabba at google.com
Thu Jul 23 05:30:28 PDT 2026
On Mon, 20 Jul 2026 at 18:15, Vincent Donnefort <vdonnefort at google.com> wrote:
>
> In preparation for the pKVM heap allocator, introduce
> pkvm_map_private_va_range() to map a physical range into the pKVM
> private range.
>
> 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/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index 00cadd13ee5d..ea97ea49820e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -31,6 +31,7 @@ int __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
> unsigned long *haddr);
> int pkvm_create_stack(phys_addr_t phys, unsigned long *haddr);
> int pkvm_alloc_private_va_range(size_t size, unsigned long *haddr);
> +int pkvm_map_private_va_range(void *haddr, phys_addr_t phys, size_t size);
> phys_addr_t pkvm_private_va_range_pa(void *va);
>
> #endif /* __KVM_HYP_MM_H */
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index 5cd2f1fe51e4..20e4445dd57b 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -25,6 +25,7 @@ struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS];
> unsigned int hyp_memblock_nr;
>
> static u64 __io_map_base;
> +static u64 __hyp_private_va_start;
>
> struct hyp_fixmap_slot {
> u64 addr;
> @@ -90,6 +91,31 @@ int pkvm_alloc_private_va_range(size_t size, unsigned long *haddr)
> return ret;
> }
>
> +/**
> + * pkvm_map_private_va_range() - Map a physical range into the private VA range
> + * @haddr: The virtual address in the private range.
> + * @phys: The physical address to map.
> + * @size: The size of the range to map.
> + *
> + * The hypervisor VA @haddr must have been first allocated with pkvm_alloc_private_va_range()
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int pkvm_map_private_va_range(void *haddr, phys_addr_t phys, size_t size)
> +{
> + unsigned long addr = (unsigned long)haddr;
> +
> + if (!PAGE_ALIGNED(addr | phys | size))
> + return -EINVAL;
> +
> + guard(hyp_spinlock)(&pkvm_pgd_lock);
> +
> + if (addr < __hyp_private_va_start || addr + size > __io_map_base)
> + return -EINVAL;
> +
> + return kvm_pgtable_hyp_map(&pkvm_pgtable, addr, size, phys, PAGE_HYP);
> +}
> +
> phys_addr_t pkvm_private_va_range_pa(void *va)
> {
> kvm_pte_t pte = 0;
> @@ -450,6 +476,7 @@ int hyp_create_idmap(u32 hyp_va_bits)
> */
> __io_map_base = start & BIT(hyp_va_bits - 2);
> __io_map_base ^= BIT(hyp_va_bits - 2);
> + __hyp_private_va_start = __io_map_base;
> __hyp_vmemmap = __io_map_base | BIT(hyp_va_bits - 3);
>
> return __pkvm_create_mappings(start, end - start, start, PAGE_HYP_EXEC);
> --
> 2.55.0.229.g6434b31f56-goog
>
More information about the linux-arm-kernel
mailing list