Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf4e7e64 authored by Prakash Gupta's avatar Prakash Gupta
Browse files

Revert "iommu: arm-smmu: iommu_unmap_fast support"



This reverts commit 49d6dec0.
iommu_unmap_fast support require releasing cb_lock between unmap and tlb
flush. This allows room for a stale walk cache between unmap of last pte in
a pmd, which results in freeing of pmd. This followed by map on the same
pmd range results in valid access initiated on new mapping using stale walk
cache. The can be avoided by ensuring unmap and tlb flush happens while
keeping the cb_lock.

Change-Id: I2ad7e25ee858a2f70d6f9a9c53c66b54bd0df458
Signed-off-by: default avatarPrakash Gupta <guptap@codeaurora.org>
parent e3f07b95
Loading
Loading
Loading
Loading
+22 −25
Original line number Diff line number Diff line
@@ -1241,32 +1241,14 @@ static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu)
	spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
}

static void arm_smmu_tlb_inv_context_s1(void *cookie);

static void arm_smmu_tlb_sync_context(void *cookie)
{
	struct arm_smmu_domain *smmu_domain = cookie;
	struct arm_smmu_device *smmu = smmu_domain->smmu;
	struct device *dev = smmu_domain->dev;
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
	void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
	unsigned long flags;
	size_t ret;
	bool use_tlbiall = smmu->options & ARM_SMMU_OPT_NO_ASID_RETENTION;
	ktime_t cur = ktime_get();

	ret = arm_smmu_domain_power_on(&smmu_domain->domain,
				       smmu_domain->smmu);
	if (ret)
		return;

	trace_tlbi_start(dev, 0);

	if (!use_tlbiall)
		writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID);
	else
		writel_relaxed(0, base + ARM_SMMU_CB_S1_TLBIALL);

	spin_lock_irqsave(&smmu_domain->sync_lock, flags);
	if (__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC,
@@ -1279,10 +1261,6 @@ static void arm_smmu_tlb_sync_context(void *cookie)
		BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG));
	}
	spin_unlock_irqrestore(&smmu_domain->sync_lock, flags);

	trace_tlbi_end(dev, ktime_us_delta(ktime_get(), cur));

	arm_smmu_domain_power_off(&smmu_domain->domain, smmu_domain->smmu);
}

static void arm_smmu_tlb_sync_vmid(void *cookie)
@@ -1294,7 +1272,23 @@ static void arm_smmu_tlb_sync_vmid(void *cookie)

static void arm_smmu_tlb_inv_context_s1(void *cookie)
{
	return;
	struct arm_smmu_domain *smmu_domain = cookie;
	struct device *dev = smmu_domain->dev;
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
	struct arm_smmu_device *smmu = smmu_domain->smmu;
	void __iomem *base = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
	bool use_tlbiall = smmu->options & ARM_SMMU_OPT_NO_ASID_RETENTION;
	ktime_t cur = ktime_get();

	trace_tlbi_start(dev, 0);

	if (!use_tlbiall)
		writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID);
	else
		writel_relaxed(0, base + ARM_SMMU_CB_S1_TLBIALL);

	arm_smmu_tlb_sync_context(cookie);
	trace_tlbi_end(dev, ktime_us_delta(ktime_get(), cur));
}

static void arm_smmu_tlb_inv_context_s2(void *cookie)
@@ -1585,7 +1579,6 @@ static phys_addr_t arm_smmu_verify_fault(struct iommu_domain *domain,

	phys = arm_smmu_iova_to_phys_hard(domain, iova);
	smmu_domain->pgtbl_cfg.tlb->tlb_flush_all(smmu_domain);
	smmu_domain->pgtbl_cfg.tlb->tlb_sync(smmu_domain);
	phys_post_tlbiall = arm_smmu_iova_to_phys_hard(domain, iova);

	if (phys != phys_post_tlbiall) {
@@ -2622,7 +2615,6 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,

	/* Ensure there are no stale mappings for this context bank */
	tlb->tlb_flush_all(smmu_domain);
	tlb->tlb_sync(smmu_domain);
}

static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
@@ -2966,12 +2958,17 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
	if (arm_smmu_is_slave_side_secure(smmu_domain))
		return msm_secure_smmu_unmap(domain, iova, size);

	ret = arm_smmu_domain_power_on(domain, smmu_domain->smmu);
	if (ret)
		return ret;

	arm_smmu_secure_domain_lock(smmu_domain);

	spin_lock_irqsave(&smmu_domain->cb_lock, flags);
	ret = ops->unmap(ops, iova, size);
	spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);

	arm_smmu_domain_power_off(domain, smmu_domain->smmu);
	/*
	 * While splitting up block mappings, we might allocate page table
	 * memory during unmap, so the vmids needs to be assigned to the
+0 −1
Original line number Diff line number Diff line
@@ -201,7 +201,6 @@ static dma_addr_t __fast_smmu_alloc_iova(struct dma_fast_smmu_mapping *mapping,
		bool skip_sync = (attrs & DMA_ATTR_SKIP_CPU_SYNC);

		iommu_tlbiall(mapping->domain);
		iommu_tlb_sync(mapping->domain);
		mapping->have_stale_tlbs = false;
		av8l_fast_clear_stale_ptes(mapping->pgtbl_pmds, skip_sync);
	}
+0 −1
Original line number Diff line number Diff line
@@ -89,7 +89,6 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops)

	iop = container_of(ops, struct io_pgtable, ops);
	io_pgtable_tlb_flush_all(iop);
	io_pgtable_tlb_sync(iop);
	io_pgtable_init_table[iop->fmt]->free(iop);
}