Merge branches 'x86/vt-d', 'arm/omap', 'core', 'x86/amd' and 'arm/smmu' into next
authorJoerg Roedel <joro@8bytes.org>
Tue, 25 Jun 2013 21:34:29 +0000 (23:34 +0200)
committerJoerg Roedel <joro@8bytes.org>
Tue, 25 Jun 2013 21:34:29 +0000 (23:34 +0200)
1  2  3  4  5 
drivers/iommu/amd_iommu.c

index 5a02d0776a66a9a21f57bcd2867cae613a60eb2e,21d02b0d907c1ada17aa3b1d0e13352cd2e4cbf3,21d02b0d907c1ada17aa3b1d0e13352cd2e4cbf3,4b029c17f8d009263ca0aef0a10fdd62d89a5113,21d02b0d907c1ada17aa3b1d0e13352cd2e4cbf3..6dc659426a51f5cca55fdbaf2348b3c28fa03dde
@@@@@@ -1906,34 -1893,34 -1893,34 -1897,59 -1893,34 +1910,59 @@@@@@ static void domain_id_free(int id
        write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
     }
     
+++ +#define DEFINE_FREE_PT_FN(LVL, FN)                         \
+++ +static void free_pt_##LVL (unsigned long __pt)                     \
+++ +{                                                          \
+++ +   unsigned long p;                                        \
+++ +   u64 *pt;                                                \
+++ +   int i;                                                  \
+++ +                                                           \
+++ +   pt = (u64 *)__pt;                                       \
+++ +                                                           \
+++ +   for (i = 0; i < 512; ++i) {                             \
+++ +           if (!IOMMU_PTE_PRESENT(pt[i]))                  \
+++ +                   continue;                               \
+++ +                                                           \
+++ +           p = (unsigned long)IOMMU_PTE_PAGE(pt[i]);       \
+++ +           FN(p);                                          \
+++ +   }                                                       \
+++ +   free_page((unsigned long)pt);                           \
+++ +}
+++ +
+++ +DEFINE_FREE_PT_FN(l2, free_page)
+++ +DEFINE_FREE_PT_FN(l3, free_pt_l2)
+++ +DEFINE_FREE_PT_FN(l4, free_pt_l3)
+++ +DEFINE_FREE_PT_FN(l5, free_pt_l4)
+++ +DEFINE_FREE_PT_FN(l6, free_pt_l5)
+++ +
     static void free_pagetable(struct protection_domain *domain)
     {
--- -   int i, j;
--- -   u64 *p1, *p2, *p3;
-    
-       p1 = domain->pt_root;
-    
-       if (!p1)
-               return;
-    
-       for (i = 0; i < 512; ++i) {
-               if (!IOMMU_PTE_PRESENT(p1[i]))
-                       continue;
-    
-               p2 = IOMMU_PTE_PAGE(p1[i]);
-               for (j = 0; j < 512; ++j) {
-                       if (!IOMMU_PTE_PRESENT(p2[j]))
-                               continue;
-                       p3 = IOMMU_PTE_PAGE(p2[j]);
-                       free_page((unsigned long)p3);
-               }
+++ +   unsigned long root = (unsigned long)domain->pt_root;
     
 -- -   p1 = domain->pt_root;
 -- -
 -- -   if (!p1)
 -- -           return;
 -- -
 -- -   for (i = 0; i < 512; ++i) {
 -- -           if (!IOMMU_PTE_PRESENT(p1[i]))
 -- -                   continue;
 -- -
 -- -           p2 = IOMMU_PTE_PAGE(p1[i]);
 -- -           for (j = 0; j < 512; ++j) {
 -- -                   if (!IOMMU_PTE_PRESENT(p2[j]))
 -- -                           continue;
 -- -                   p3 = IOMMU_PTE_PAGE(p2[j]);
 -- -                   free_page((unsigned long)p3);
 -- -           }
 -- -
--- -           free_page((unsigned long)p2);
+++ +   switch (domain->mode) {
+++ +   case PAGE_MODE_NONE:
+++ +           break;
+++ +   case PAGE_MODE_1_LEVEL:
+++ +           free_page(root);
+++ +           break;
+++ +   case PAGE_MODE_2_LEVEL:
+++ +           free_pt_l2(root);
+++ +           break;
+++ +   case PAGE_MODE_3_LEVEL:
+++ +           free_pt_l3(root);
+++ +           break;
+++ +   case PAGE_MODE_4_LEVEL:
+++ +           free_pt_l4(root);
+++ +           break;
+++ +   case PAGE_MODE_5_LEVEL:
+++ +           free_pt_l5(root);
+++ +           break;
+++ +   case PAGE_MODE_6_LEVEL:
+++ +           free_pt_l6(root);
+++ +           break;
+++ +   default:
+++ +           BUG();
        }
--- -
--- -   free_page((unsigned long)p1);
--- -
--- -   domain->pt_root = NULL;
     }
     
     static void free_gcr3_tbl_level1(u64 *tbl)