From c690c2e305bcb1d51507407e4c131d779b676f4a Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Fri, 25 Mar 2022 19:38:21 +0000 Subject: [PATCH] ANDROID: KVM: arm64: iommu: Create private mapping last Private EL2 mappings currently cannot be removed. Move the creation of IOMMU device mappings at the end of the registration function so that other errors do not result in unnecessary mappings. Bug: 190463801 Signed-off-by: David Brazdil Change-Id: I3139e9af3345f157295eb72441a7cf3cc055116d --- arch/arm64/kvm/hyp/nvhe/iommu.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu.c index 30401b2640d9..fcb842aae892 100644 --- a/arch/arm64/kvm/hyp/nvhe/iommu.c +++ b/arch/arm64/kvm/hyp/nvhe/iommu.c @@ -293,7 +293,7 @@ int __pkvm_iommu_register(unsigned long dev_id, { struct pkvm_iommu *dev = NULL; struct pkvm_iommu_driver *drv; - void *dev_va, *mem_va = NULL; + void *mem_va = NULL; int ret = 0; drv = get_driver(drv_id); @@ -337,20 +337,11 @@ int __pkvm_iommu_register(unsigned long dev_id, goto out; } - /* Create EL2 mapping for the device. */ - dev_va = (void *)__pkvm_create_private_mapping(dev_pa, dev_size, - PAGE_HYP_DEVICE); - if (IS_ERR(dev_va)) { - ret = PTR_ERR(dev_va); - goto out; - } - /* Populate the new device entry. */ *dev = (struct pkvm_iommu){ .id = dev_id, .ops = drv->ops, .pa = dev_pa, - .va = dev_va, .size = dev_size, }; @@ -360,13 +351,22 @@ int __pkvm_iommu_register(unsigned long dev_id, } /* - * Unmap the device's MMIO range from host stage-2. Future attempts to - * map will be blocked by pkvm_iommu_host_stage2_adjust_range. + * Unmap the device's MMIO range from host stage-2. If registration + * is successful, future attempts to re-map will be blocked by + * pkvm_iommu_host_stage2_adjust_range. */ ret = host_stage2_unmap_dev_locked(dev_pa, dev_size); if (ret) goto out; + /* Create EL2 mapping for the device. Do it last as it is irreversible. */ + dev->va = (void *)__pkvm_create_private_mapping(dev_pa, dev_size, + PAGE_HYP_DEVICE); + if (IS_ERR(dev->va)) { + ret = PTR_ERR(dev->va); + goto out; + } + /* Register device and prevent host from mapping the MMIO range. */ list_add_tail(&dev->list, &iommu_list);