From 75a7353e0ad8f83192b710979e925c6964700ade Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 2 Jul 2009 11:21:16 +0100 Subject: [PATCH] --- yaml --- r: 154795 b: refs/heads/master c: 75e6bf9638992dfc0fec9c3ca10444c8e0d6a638 h: refs/heads/master i: 154793: a77bf301a20a8b118c059255a6130f9315c57dff 154791: e22719659bf3951528822a6850640887ce8c0f58 v: v3 --- [refs] | 2 +- trunk/drivers/pci/intel-iommu.c | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/[refs] b/[refs] index 8eaf1a80cd83..4e87b6673932 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7766a3fb905f0b078b05f5d6a6be8df4c64b9f51 +refs/heads/master: 75e6bf9638992dfc0fec9c3ca10444c8e0d6a638 diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index 2c1b2babfdc5..dcf0295a9b60 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -240,6 +240,11 @@ static inline bool dma_pte_present(struct dma_pte *pte) return (pte->val & 3) != 0; } +static inline int first_pte_in_page(struct dma_pte *pte) +{ + return !((unsigned long)pte & ~VTD_PAGE_MASK); +} + /* * This domain is a statically identity mapping domain. * 1. This domain creats a static 1:1 mapping to all usable memory. @@ -780,13 +785,12 @@ static void dma_pte_clear_range(struct dmar_domain *domain, start_pfn = align_to_level(start_pfn + 1, 2); continue; } - while (start_pfn <= last_pfn && - (unsigned long)pte >> VTD_PAGE_SHIFT == - (unsigned long)first_pte >> VTD_PAGE_SHIFT) { + do { dma_clear_pte(pte); start_pfn++; pte++; - } + } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); + domain_flush_cache(domain, first_pte, (void *)pte - (void *)first_pte); } @@ -821,14 +825,14 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, tmp = align_to_level(tmp + 1, level + 1); continue; } - while (tmp + level_size(level) - 1 <= last_pfn && - (unsigned long)pte >> VTD_PAGE_SHIFT == - (unsigned long)first_pte >> VTD_PAGE_SHIFT) { + do { free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); dma_clear_pte(pte); pte++; tmp += level_size(level); - } + } while (!first_pte_in_page(pte) && + tmp + level_size(level) - 1 <= last_pfn); + domain_flush_cache(domain, first_pte, (void *)pte - (void *)first_pte); @@ -1694,9 +1698,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, WARN_ON(1); } pte++; - if (!nr_pages || - (unsigned long)pte >> VTD_PAGE_SHIFT != - (unsigned long)first_pte >> VTD_PAGE_SHIFT) { + if (!nr_pages || first_pte_in_page(pte)) { domain_flush_cache(domain, first_pte, (void *)pte - (void *)first_pte); pte = NULL;