diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 9fab66e8c70c..3838ce532f56 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -64,7 +64,9 @@ int __pkvm_host_use_dma(u64 phys_addr, size_t size); int __pkvm_host_unuse_dma(u64 phys_addr, size_t size); bool addr_is_memory(phys_addr_t phys); -int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); +int host_stage2_idmap_locked(phys_addr_t addr, u64 size, + enum kvm_pgtable_prot prot, + bool update_iommu); int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id); int host_stage2_unmap_reg_locked(phys_addr_t start, u64 size); int kvm_host_prepare_stage2(void *pgt_pool_base); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 0e6094c5ab79..0f7c305c8527 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -159,7 +159,7 @@ static int prepopulate_host_stage2(void) for (i = 0; i < hyp_memblock_nr; i++) { reg = &hyp_memory[i]; - ret = host_stage2_idmap_locked(reg->base, reg->size, PKVM_HOST_MEM_PROT); + ret = host_stage2_idmap_locked(reg->base, reg->size, PKVM_HOST_MEM_PROT, false); if (ret) return ret; } @@ -549,7 +549,8 @@ static bool range_is_memory(u64 start, u64 end) } static inline int __host_stage2_idmap(u64 start, u64 end, - enum kvm_pgtable_prot prot) + enum kvm_pgtable_prot prot, + bool update_iommu) { int ret; @@ -558,7 +559,8 @@ static inline int __host_stage2_idmap(u64 start, u64 end, if (ret) return ret; - kvm_iommu_host_stage2_idmap(start, end, prot); + if (update_iommu) + kvm_iommu_host_stage2_idmap(start, end, prot); return 0; } @@ -623,9 +625,10 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) } int host_stage2_idmap_locked(phys_addr_t addr, u64 size, - enum kvm_pgtable_prot prot) + enum kvm_pgtable_prot prot, + bool update_iommu) { - return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); + return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot, update_iommu); } #define KVM_MAX_OWNER_ID FIELD_MAX(KVM_INVALID_PTE_OWNER_MASK) @@ -655,7 +658,7 @@ static int __host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_i if (owner_id == PKVM_ID_HOST) { prot = default_host_prot(addr_is_memory(addr)); - ret = host_stage2_idmap_locked(addr, size, prot); + ret = host_stage2_idmap_locked(addr, size, prot, false); } else { annotation = kvm_init_invalid_leaf_owner(owner_id); ret = host_stage2_try(kvm_pgtable_stage2_annotate, @@ -725,13 +728,14 @@ static int host_stage2_idmap(u64 addr) bool is_memory = !!find_mem_range(addr, &range); enum kvm_pgtable_prot prot = default_host_prot(is_memory); int ret; + bool update_iommu = !is_memory; host_lock_component(); ret = host_stage2_adjust_range(addr, &range); if (ret) goto unlock; - ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot); + ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot, update_iommu); unlock: host_unlock_component(); @@ -1016,7 +1020,7 @@ static int __host_set_page_state_range(u64 addr, u64 size, enum pkvm_page_state state) { if (hyp_phys_to_page(addr)->host_state & PKVM_NOPAGE) { - int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT); + int ret = host_stage2_idmap_locked(addr, size, PKVM_HOST_MEM_PROT, true); if (ret) return ret; @@ -2054,7 +2058,7 @@ update: PKVM_MODULE_OWNED_PAGE); } else { ret = host_stage2_idmap_locked( - addr, nr_pages << PAGE_SHIFT, prot); + addr, nr_pages << PAGE_SHIFT, prot, false); } if (WARN_ON(ret) || !page || !prot)