intel-iommu: Make dma_pte_clear_range() use pfns
authorDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 27 Jun 2009 18:15:01 +0000 (19:15 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 29 Jun 2009 12:26:36 +0000 (13:26 +0100)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/pci/intel-iommu.c

index ad367f53a2bba86c1418acd2aa521ae10c38c44e..d4217f7371594afb1609cb35a0e0b3b25fc18b1a 100644 (file)
@@ -779,21 +779,17 @@ static void dma_pte_clear_one(struct dmar_domain *domain, unsigned long pfn)
 /* clear last level pte, a tlb flush should be followed */
 static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
 {
-       int addr_width = agaw_to_width(domain->agaw);
-       int npages;
-
-       BUG_ON(start >> addr_width);
-       BUG_ON((end-1) >> addr_width);
+       unsigned long start_pfn = IOVA_PFN(start);
+       unsigned long end_pfn = IOVA_PFN(end-1);
+       int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
 
-       /* in case it's partial page */
-       start &= PAGE_MASK;
-       end = PAGE_ALIGN(end);
-       npages = (end - start) / VTD_PAGE_SIZE;
+       BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
+       BUG_ON(addr_width < BITS_PER_LONG && end_pfn >> addr_width);
 
-       /* we don't need lock here, nobody else touches the iova range */
-       while (npages--) {
-               dma_pte_clear_one(domain, start >> VTD_PAGE_SHIFT);
-               start += VTD_PAGE_SIZE;
+       /* we don't need lock here; nobody else touches the iova range */
+       while (start_pfn <= end_pfn) {
+               dma_pte_clear_one(domain, start_pfn);
+               start_pfn++;
        }
 }