summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-02-20 15:54:11 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:11:40 -0700
commit923ea2cbed9733d64f1a4c604552f076617a494c (patch)
tree4ffb6cbcd32b0a4200cda8a0330509fa83922105
parent94c0e12871f3a4ce0db0b27849041a90ff30df52 (diff)
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 <mitchelh@codeaurora.org>
-rw-r--r--drivers/iommu/arm-smmu.c9
1 files 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)) {