|
@@ -819,13 +819,14 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
|
|
|
}
|
|
|
|
|
|
/* clear last level pte, a tlb flush should be followed */
|
|
|
-static void dma_pte_clear_range(struct dmar_domain *domain,
|
|
|
+static int dma_pte_clear_range(struct dmar_domain *domain,
|
|
|
unsigned long start_pfn,
|
|
|
unsigned long last_pfn)
|
|
|
{
|
|
|
int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
|
|
|
unsigned int large_page = 1;
|
|
|
struct dma_pte *first_pte, *pte;
|
|
|
+ int order;
|
|
|
|
|
|
BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
|
|
|
BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
|
|
@@ -849,6 +850,9 @@ static void dma_pte_clear_range(struct dmar_domain *domain,
|
|
|
(void *)pte - (void *)first_pte);
|
|
|
|
|
|
} while (start_pfn && start_pfn <= last_pfn);
|
|
|
+
|
|
|
+ order = (large_page - 1) * 9;
|
|
|
+ return order;
|
|
|
}
|
|
|
|
|
|
/* free page table pages. last level pte should already be cleared */
|
|
@@ -3869,14 +3873,15 @@ static int intel_iommu_unmap(struct iommu_domain *domain,
|
|
|
{
|
|
|
struct dmar_domain *dmar_domain = domain->priv;
|
|
|
size_t size = PAGE_SIZE << gfp_order;
|
|
|
+ int order;
|
|
|
|
|
|
- dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
|
|
|
+ order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
|
|
|
(iova + size - 1) >> VTD_PAGE_SHIFT);
|
|
|
|
|
|
if (dmar_domain->max_addr == iova + size)
|
|
|
dmar_domain->max_addr = iova;
|
|
|
|
|
|
- return gfp_order;
|
|
|
+ return order;
|
|
|
}
|
|
|
|
|
|
static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
|