[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