From 923ea2cbed9733d64f1a4c604552f076617a494c Mon Sep 17 00:00:00 2001 From: Mitchel Humpherys Date: Fri, 20 Feb 2015 15:54:11 -0800 Subject: [PATCH] iommu/arm-smmu: preserve the far during fault handling We're currently wiping out the `far' variable in our context fault handler when CONFIG_64BIT is enabled. Fix the bug. Change-Id: I86e57c7de8bfc10118f902d6702d3b9059a8762a Signed-off-by: Mitchel Humpherys --- drivers/iommu/arm-smmu.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 32e1c6c9f640..d69325885147 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -848,8 +848,8 @@ static phys_addr_t arm_smmu_iova_to_phys_soft(struct iommu_domain *domain, static irqreturn_t arm_smmu_context_fault(int irq, void *dev) { int flags, ret; - u32 fsr, far, fsynr, resume; - unsigned long iova; + u32 fsr, fsynr, resume; + unsigned long iova, far; struct iommu_domain *domain = dev; struct arm_smmu_domain *smmu_domain = domain->priv; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; @@ -880,11 +880,10 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) flags = fsynr & FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ; far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_LO); - iova = far; #ifdef CONFIG_64BIT - far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_HI); - iova |= ((unsigned long)far << 32); + far |= ((u64)readl_relaxed(cb_base + ARM_SMMU_CB_FAR_HI)) << 32; #endif + iova = far; phys_soft = arm_smmu_iova_to_phys_soft(domain, iova); if (!report_iommu_fault(domain, smmu->dev, iova, flags)) {