|
@@ -551,6 +551,15 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain *rk_domain,
|
|
spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
|
|
spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
|
|
|
|
+ dma_addr_t iova, size_t size)
|
|
|
|
+{
|
|
|
|
+ rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);
|
|
|
|
+ if (size > SPAGE_SIZE)
|
|
|
|
+ rk_iommu_zap_iova(rk_domain, iova + size - SPAGE_SIZE,
|
|
|
|
+ SPAGE_SIZE);
|
|
|
|
+}
|
|
|
|
+
|
|
static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
|
|
static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
|
|
dma_addr_t iova)
|
|
dma_addr_t iova)
|
|
{
|
|
{
|
|
@@ -575,12 +584,6 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
|
|
rk_table_flush(page_table, NUM_PT_ENTRIES);
|
|
rk_table_flush(page_table, NUM_PT_ENTRIES);
|
|
rk_table_flush(dte_addr, 1);
|
|
rk_table_flush(dte_addr, 1);
|
|
|
|
|
|
- /*
|
|
|
|
- * Zap the first iova of newly allocated page table so iommu evicts
|
|
|
|
- * old cached value of new dte from the iotlb.
|
|
|
|
- */
|
|
|
|
- rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);
|
|
|
|
-
|
|
|
|
done:
|
|
done:
|
|
pt_phys = rk_dte_pt_address(dte);
|
|
pt_phys = rk_dte_pt_address(dte);
|
|
return (u32 *)phys_to_virt(pt_phys);
|
|
return (u32 *)phys_to_virt(pt_phys);
|
|
@@ -630,6 +633,14 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
|
|
|
|
|
|
rk_table_flush(pte_addr, pte_count);
|
|
rk_table_flush(pte_addr, pte_count);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Zap the first and last iova to evict from iotlb any previously
|
|
|
|
+ * mapped cachelines holding stale values for its dte and pte.
|
|
|
|
+ * We only zap the first and last iova, since only they could have
|
|
|
|
+ * dte or pte shared with an existing mapping.
|
|
|
|
+ */
|
|
|
|
+ rk_iommu_zap_iova_first_last(rk_domain, iova, size);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
unwind:
|
|
unwind:
|
|
/* Unmap the range of iovas that we just mapped */
|
|
/* Unmap the range of iovas that we just mapped */
|