From 9e2ddae4d3c3b283f15f4bc6ad9426d470dc5811 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 9 Dec 2021 11:51:12 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Unmap PVM firmware from host stage-2 during de-privilege Unmap the PVM firmware memory from the pKVM host by transferring ownership of the pages to the hypervisor when the host deprivileges itself during boot. Signed-off-by: Will Deacon Bug: 209580772 Change-Id: I311642f543c0c73d0e0cf2ec051e8e2d9759c5d1 Signed-off-by: Will Deacon --- arch/arm64/include/asm/kvm_pkvm.h | 3 +++ arch/arm64/kvm/hyp/nvhe/setup.c | 10 ++++++++++ arch/arm64/kvm/pkvm.c | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index f96f8fa7059e..a5a0dca0c633 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -231,6 +231,9 @@ static inline int pkvm_get_max_wrps(void) extern struct memblock_region kvm_nvhe_sym(hyp_memory)[]; extern unsigned int kvm_nvhe_sym(hyp_memblock_nr); +extern phys_addr_t kvm_nvhe_sym(pvmfw_base); +extern phys_addr_t kvm_nvhe_sym(pvmfw_size); + static inline unsigned long hyp_vmemmap_memblock_size(struct memblock_region *reg, size_t vmemmap_entry_size) { diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index 3e5099074dae..3ac328332848 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -21,6 +21,9 @@ unsigned long hyp_nr_cpus; +phys_addr_t pvmfw_base; +phys_addr_t pvmfw_size; + #define hyp_percpu_size ((unsigned long)__per_cpu_end - \ (unsigned long)__per_cpu_start) @@ -135,6 +138,13 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, if (ret) return ret; + start = hyp_phys_to_virt(pvmfw_base); + end = start + pvmfw_size; + prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_OWNED); + ret = pkvm_create_mappings(start, end, prot); + if (ret) + return ret; + return 0; } diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 670b4cead5c4..273d288ffdd7 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -18,6 +18,8 @@ #include "hyp_constants.h" static struct reserved_mem *pkvm_firmware_mem; +static phys_addr_t *pvmfw_base = &kvm_nvhe_sym(pvmfw_base); +static phys_addr_t *pvmfw_size = &kvm_nvhe_sym(pvmfw_size); static struct memblock_region *hyp_memory = kvm_nvhe_sym(hyp_memory); static unsigned int *hyp_memblock_nr_ptr = &kvm_nvhe_sym(hyp_memblock_nr); @@ -217,6 +219,8 @@ static int __init pkvm_firmware_rmem_init(struct reserved_mem *rmem) if (!PAGE_ALIGNED(rmem->size)) return pkvm_firmware_rmem_err(rmem, "size is not page-aligned"); + *pvmfw_size = rmem->size; + *pvmfw_base = rmem->base; pkvm_firmware_mem = rmem; return 0; }