From: Joerg Roedel Date: Tue, 25 Jun 2013 21:34:29 +0000 (+0200) Subject: Merge branches 'x86/vt-d', 'arm/omap', 'core', 'x86/amd' and 'arm/smmu' into next X-Git-Tag: v3.11-rc1~48^2 X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=01ce784acfa69a171afe6ec3f85a959546f2d18a;p=~andy%2Flinux Merge branches 'x86/vt-d', 'arm/omap', 'core', 'x86/amd' and 'arm/smmu' into next --- 01ce784acfa69a171afe6ec3f85a959546f2d18a diff --cc drivers/iommu/amd_iommu.c index 5a02d0776a6,21d02b0d907,21d02b0d907,4b029c17f8d,21d02b0d907..6dc659426a5 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@@@@@ -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)