From a6861d2268de3198c99fe463580af9220436f7ab Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 7 Jul 2022 15:49:04 +0100 Subject: [PATCH] Revert "ANDROID: KVM: arm64: iommu: DABT handler callback" This reverts commit 2a61e9901beef458f744492ae68af507257c202e. Bug: 233587962 Signed-off-by: Will Deacon Change-Id: Ib2ebd907f874f214d2c098960f02cf302d215681 --- arch/arm64/kvm/hyp/include/nvhe/iommu.h | 10 ------ arch/arm64/kvm/hyp/nvhe/iommu.c | 22 ------------- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 43 ++++++++++++++++++------- 3 files changed, 31 insertions(+), 44 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/iommu.h b/arch/arm64/kvm/hyp/include/nvhe/iommu.h index 88f6703245ef..74eccae4d466 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/iommu.h +++ b/arch/arm64/kvm/hyp/include/nvhe/iommu.h @@ -29,14 +29,6 @@ struct pkvm_iommu_ops { int (*suspend)(struct pkvm_iommu *dev); int (*resume)(struct pkvm_iommu *dev); - /* - * Host data abort handler callback. Called with host lock held. - * Returns true if the data abort has been handled. - */ - bool (*host_dabt_handler)(struct pkvm_iommu *dev, - struct kvm_cpu_context *host_ctxt, - u32 esr, size_t off); - /* Amount of memory allocated per-device for use by the driver. */ size_t data_size; }; @@ -61,8 +53,6 @@ int __pkvm_iommu_pm_notify(unsigned long dev_id, enum pkvm_iommu_pm_event event); int pkvm_iommu_host_stage2_adjust_range(phys_addr_t addr, phys_addr_t *start, phys_addr_t *end); -bool pkvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u32 esr, - phys_addr_t fault_pa); struct kvm_iommu_ops { int (*init)(void); diff --git a/arch/arm64/kvm/hyp/nvhe/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu.c index 50a0a4634285..4e9a7c39e745 100644 --- a/arch/arm64/kvm/hyp/nvhe/iommu.c +++ b/arch/arm64/kvm/hyp/nvhe/iommu.c @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -359,24 +358,3 @@ int pkvm_iommu_host_stage2_adjust_range(phys_addr_t addr, phys_addr_t *start, *end = new_end; return 0; } - -bool pkvm_iommu_host_dabt_handler(struct kvm_cpu_context *host_ctxt, u32 esr, - phys_addr_t pa) -{ - struct pkvm_iommu *dev; - - assert_host_component_locked(); - - list_for_each_entry(dev, &iommu_list, list) { - if (pa < dev->pa || pa >= dev->pa + dev->size) - continue; - - if (!dev->powered || !dev->ops->host_dabt_handler || - !dev->ops->host_dabt_handler(dev, host_ctxt, esr, pa - dev->pa)) - return false; - - kvm_skip_host_instr(); - return true; - } - return false; -} diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 11af220d8989..06993efb72b2 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -577,10 +577,9 @@ static int host_stage2_idmap(u64 addr) enum kvm_pgtable_prot prot; int ret; - hyp_assert_lock_held(&host_kvm.lock); - prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT; + host_lock_component(); /* * Adjust against IOMMU devices first. host_stage2_adjust_range() should * be called last for proper alignment. @@ -589,14 +588,38 @@ static int host_stage2_idmap(u64 addr) ret = pkvm_iommu_host_stage2_adjust_range(addr, &range.start, &range.end); if (ret) - return ret; + goto unlock; } ret = host_stage2_adjust_range(addr, &range); if (ret) - return ret; + goto unlock; - return host_stage2_idmap_locked(range.start, range.end - range.start, prot); + ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot); +unlock: + host_unlock_component(); + + return ret; +} + +static int host_mmio_dabt_handler(struct kvm_cpu_context *host_ctxt, u32 esr, + phys_addr_t addr) +{ + bool wnr = esr & ESR_ELx_WNR; + unsigned int len = BIT((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT); + int rd = (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT; + bool handled = false; + + if (kvm_iommu_ops.host_mmio_dabt_handler) { + handled = kvm_iommu_ops.host_mmio_dabt_handler(host_ctxt, addr, + len, wnr, rd); + } + + if (!handled) + return -EPERM; + + kvm_skip_host_instr(); + return 0; } static bool is_dabt(u64 esr) @@ -616,18 +639,14 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) addr = (fault.hpfar_el2 & HPFAR_MASK) << 8; addr |= fault.far_el2 & FAR_MASK; - host_lock_component(); - - /* Check if an IOMMU device can handle the DABT. */ - if (is_dabt(esr) && !addr_is_memory(addr) && - pkvm_iommu_host_dabt_handler(host_ctxt, esr, addr)) - ret = 0; + /* See if any subsystem can handle this abort. */ + if (is_dabt(esr) && !addr_is_memory(addr)) + ret = host_mmio_dabt_handler(host_ctxt, esr, addr); /* If not handled, attempt to map the page. */ if (ret == -EPERM) ret = host_stage2_idmap(addr); - host_unlock_component(); BUG_ON(ret && ret != -EAGAIN); }