diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h index 3d1ed95e257d..5aaa02adfc7f 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h +++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h @@ -3,6 +3,7 @@ #define __ARM64_KVM_NVHE_IOMMU_H__ #include +#include #include @@ -32,6 +33,9 @@ void kvm_iommu_reclaim_pages(void *p, u8 order); #define kvm_iommu_donate_page_nc() kvm_iommu_donate_pages(0, IOMMU_PAGE_NOCACHE) #define kvm_iommu_reclaim_page(p) kvm_iommu_reclaim_pages(p, 0) +void kvm_iommu_host_stage2_idmap(phys_addr_t start, phys_addr_t end, + enum kvm_pgtable_prot prot); + struct kvm_iommu_ops { int (*init)(void); int (*alloc_domain)(struct kvm_hyp_iommu_domain *domain, int type); diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c index bb4869592a16..8c9e5cae475e 100644 --- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c +++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c @@ -432,3 +432,8 @@ int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu) return pkvm_init_power_domain(&iommu->power_domain, &iommu_power_ops); } + +void kvm_iommu_host_stage2_idmap(phys_addr_t start, phys_addr_t end, + enum kvm_pgtable_prot prot) +{ +} diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 3a17a6127787..0e6094c5ab79 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -432,7 +432,7 @@ int host_stage2_unmap_reg_locked(phys_addr_t start, u64 size) if (ret) return ret; - /* XXX: unmap from IOMMU once available */ + kvm_iommu_host_stage2_idmap(start, start + size, 0); return 0; } @@ -551,8 +551,15 @@ static bool range_is_memory(u64 start, u64 end) static inline int __host_stage2_idmap(u64 start, u64 end, enum kvm_pgtable_prot prot) { - return kvm_pgtable_stage2_map(&host_mmu.pgt, start, end - start, start, - prot, &host_s2_pool, 0); + int ret; + + ret = kvm_pgtable_stage2_map(&host_mmu.pgt, start, end - start, start, + prot, &host_s2_pool, 0); + if (ret) + return ret; + + kvm_iommu_host_stage2_idmap(start, end, prot); + return 0; } /* @@ -664,6 +671,9 @@ static int __host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_i else __host_update_page_state(addr, size, PKVM_NOPAGE | nopage_state); + prot = owner_id == PKVM_ID_HOST ? PKVM_HOST_MEM_PROT : 0; + kvm_iommu_host_stage2_idmap(addr, addr + size, prot); + return 0; }