From 9092a6ac8be849cbe360b0c4ecd18ef653ae6b8e Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Thu, 24 Jun 2021 11:02:37 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Add 'host_stage2_set_owner' to kvm_iommu_ops Add a new hook to kvm_iommu_ops that is invoked whenever a range of pages changes their owner in the host stage2. This is currently limited to finalize_host_mappings, which changes the owner of EL2-mapped pages from host to hyp. The driver is expected to apply corresponding changes in the IOMMU it controls, so that only the new owner can access the page range. Test: builds, boots Bug: 190463801 Change-Id: I0809f4859a9117d1a37506b7aa9e19c6bd25ffdb Signed-off-by: David Brazdil (cherry picked from commit 3cd8b5b00be97ba6567d319a8be8bf7b45929936) Signed-off-by: Mostafa Saleh --- arch/arm64/include/asm/kvm_hyp.h | 1 + arch/arm64/kvm/hyp/nvhe/mem_protect.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 92a614b36625..61b8354e1b7d 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -134,6 +134,7 @@ extern bool kvm_nvhe_sym(smccc_trng_available); struct kvm_iommu_ops { int (*init)(void); bool (*host_smc_handler)(struct kvm_cpu_context *host_ctxt); + void (*host_stage2_set_owner)(phys_addr_t addr, size_t size, u8 owner_id); }; extern struct kvm_iommu_ops kvm_iommu_ops; diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 7d742c771a1b..5ec7b76657b5 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -576,14 +576,20 @@ static kvm_pte_t kvm_init_invalid_leaf_owner(u8 owner_id) int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) { kvm_pte_t annotation; + int ret; if (owner_id > KVM_MAX_OWNER_ID) return -EINVAL; annotation = kvm_init_invalid_leaf_owner(owner_id); - return host_stage2_try(kvm_pgtable_stage2_annotate, &host_mmu.pgt, - addr, size, &host_s2_pool, annotation); + ret = host_stage2_try(kvm_pgtable_stage2_annotate, &host_mmu.pgt, + addr, size, &host_s2_pool, annotation); + + if (!ret && kvm_iommu_ops.host_stage2_set_owner) + kvm_iommu_ops.host_stage2_set_owner(addr, size, owner_id); + + return ret; } static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)