From 7570c3494944837c51de3aaba4453fd411eff2a0 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 7 Jul 2022 15:49:02 +0100 Subject: [PATCH] Revert "ANDROID: KVM: arm64: s2mpu: Replace DABT handler with callback" This reverts commit 0f911c35cab21f263baa0fe975bfb0e220437977. Bug: 233587962 Signed-off-by: Will Deacon Change-Id: I97bc2398abddb5835ec0681dcf58eb011f3eaa42 --- arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c | 31 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c b/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c index cd621190120f..51c26ea93f19 100644 --- a/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c +++ b/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c @@ -369,6 +369,17 @@ static int s2mpu_suspend(struct pkvm_iommu *dev) return initialize_with_prot(dev, MPT_PROT_NONE); } +static struct pkvm_iommu *find_s2mpu_by_addr(phys_addr_t addr) +{ + struct pkvm_iommu *dev; + + for_each_s2mpu(dev) { + if (dev->pa <= addr && addr < (dev->pa + S2MPU_MMIO_SIZE)) + return dev; + } + return NULL; +} + static u32 host_mmio_reg_access_mask(size_t off, bool is_write) { const u32 no_access = 0; @@ -395,19 +406,23 @@ static u32 host_mmio_reg_access_mask(size_t off, bool is_write) return no_access; } -static bool s2mpu_host_dabt_handler(struct pkvm_iommu *dev, - struct kvm_cpu_context *host_ctxt, - u32 esr, size_t off) +static bool s2mpu_host_mmio_dabt_handler(struct kvm_cpu_context *host_ctxt, + phys_addr_t fault_pa, unsigned int len, + bool is_write, int rd) { - bool is_write = 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; + struct pkvm_iommu *dev; + size_t off; u32 mask; /* Only handle MMIO access with u32 size and alignment. */ - if ((len != sizeof(u32)) || (off & (sizeof(u32) - 1))) + if ((len != sizeof(u32)) || (fault_pa & (sizeof(u32) - 1))) return false; + dev = find_s2mpu_by_addr(fault_pa); + if (!dev || !is_powered_on(dev)) + return false; + + off = fault_pa - dev->pa; mask = host_mmio_reg_access_mask(off, is_write); if (!mask) return false; @@ -483,10 +498,10 @@ const struct pkvm_iommu_ops pkvm_s2mpu_ops = (struct pkvm_iommu_ops){ .validate = s2mpu_validate, .resume = s2mpu_resume, .suspend = s2mpu_suspend, - .host_dabt_handler = s2mpu_host_dabt_handler, .data_size = sizeof(struct s2mpu_drv_data), }; const struct kvm_iommu_ops kvm_s2mpu_ops = (struct kvm_iommu_ops){ + .host_mmio_dabt_handler = s2mpu_host_mmio_dabt_handler, .host_stage2_set_owner = s2mpu_host_stage2_set_owner, };