AMD IOMMU: make dma_ops_free_pagetable generic
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / amd_iommu.c
index a7b6dec6fc3f4afc72f57651b1523156d415431b..8a0fd3d099735a072c7c936d60502af39d4c6d8a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/iommu-helper.h>
 #include <asm/proto.h>
 #include <asm/iommu.h>
+#include <asm/gart.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 
@@ -235,8 +236,9 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
        status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
        writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
 
-       if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
-               printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
+       if (unlikely(i == EXIT_LOOP_COUNT))
+               panic("AMD IOMMU: Completion wait loop failed\n");
+
 out:
        spin_unlock_irqrestore(&iommu->lock, flags);
 
@@ -336,10 +338,10 @@ static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid)
  * supporting all features of AMD IOMMU page tables like level skipping
  * and full 64 bit address spaces.
  */
-static int iommu_map(struct protection_domain *dom,
-                    unsigned long bus_addr,
-                    unsigned long phys_addr,
-                    int prot)
+static int iommu_map_page(struct protection_domain *dom,
+                         unsigned long bus_addr,
+                         unsigned long phys_addr,
+                         int prot)
 {
        u64 __pte, *pte, *page;
 
@@ -438,7 +440,7 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
 
        for (addr = e->address_start; addr < e->address_end;
             addr += PAGE_SIZE) {
-               ret = iommu_map(&dma_dom->domain, addr, addr, e->prot);
+               ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot);
                if (ret)
                        return ret;
                /*
@@ -585,12 +587,12 @@ static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
        iommu_area_reserve(dom->bitmap, start_page, pages);
 }
 
-static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom)
+static void free_pagetable(struct protection_domain *domain)
 {
        int i, j;
        u64 *p1, *p2, *p3;
 
-       p1 = dma_dom->domain.pt_root;
+       p1 = domain->pt_root;
 
        if (!p1)
                return;
@@ -611,6 +613,8 @@ static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom)
        }
 
        free_page((unsigned long)p1);
+
+       domain->pt_root = NULL;
 }
 
 /*
@@ -622,7 +626,7 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
        if (!dom)
                return;
 
-       dma_ops_free_pagetable(dom);
+       free_pagetable(&dom->domain);
 
        kfree(dom->pte_pages);