]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - arch/powerpc/kernel/iommu.c
powerpc/powernv/iommu: Add real mode version of iommu_table_ops::exchange()
[mirror_ubuntu-zesty-kernel.git] / arch / powerpc / kernel / iommu.c
index 5f202a566ec5f0296a22a71ac238a63a6a90ba7f..685a4767b72238e7264d13fb3f5a8b1021efb467 100644 (file)
@@ -1004,6 +1004,31 @@ long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
 }
 EXPORT_SYMBOL_GPL(iommu_tce_xchg);
 
+#ifdef CONFIG_PPC_BOOK3S_64
+long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
+               unsigned long *hpa, enum dma_data_direction *direction)
+{
+       long ret;
+
+       ret = tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
+
+       if (!ret && ((*direction == DMA_FROM_DEVICE) ||
+                       (*direction == DMA_BIDIRECTIONAL))) {
+               struct page *pg = realmode_pfn_to_page(*hpa >> PAGE_SHIFT);
+
+               if (likely(pg)) {
+                       SetPageDirty(pg);
+               } else {
+                       tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
+                       ret = -EFAULT;
+               }
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_tce_xchg_rm);
+#endif
+
 int iommu_take_ownership(struct iommu_table *tbl)
 {
        unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;