Commit 292827cb authored by Allen Kay's avatar Allen Kay Committed by David Woodhouse

intel-iommu: fix return value of iommu_unmap() API

iommu_unmap() API expects IOMMU drivers to return the actual page order
of the address being unmapped.  Previous code was just returning page
order passed in from the caller.  This patch fixes this problem.
Signed-off-by: default avatarAllen Kay <allen.m.kay@intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 3fb39615
...@@ -819,13 +819,14 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, ...@@ -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 */ /* 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 start_pfn,
unsigned long last_pfn) unsigned long last_pfn)
{ {
int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
unsigned int large_page = 1; unsigned int large_page = 1;
struct dma_pte *first_pte, *pte; 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 && start_pfn >> addr_width);
BUG_ON(addr_width < BITS_PER_LONG && last_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, ...@@ -849,6 +850,9 @@ static void dma_pte_clear_range(struct dmar_domain *domain,
(void *)pte - (void *)first_pte); (void *)pte - (void *)first_pte);
} while (start_pfn && start_pfn <= last_pfn); } 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 */ /* free page table pages. last level pte should already be cleared */
...@@ -3869,14 +3873,15 @@ static int intel_iommu_unmap(struct iommu_domain *domain, ...@@ -3869,14 +3873,15 @@ static int intel_iommu_unmap(struct iommu_domain *domain,
{ {
struct dmar_domain *dmar_domain = domain->priv; struct dmar_domain *dmar_domain = domain->priv;
size_t size = PAGE_SIZE << gfp_order; 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); (iova + size - 1) >> VTD_PAGE_SHIFT);
if (dmar_domain->max_addr == iova + size) if (dmar_domain->max_addr == iova + size)
dmar_domain->max_addr = iova; dmar_domain->max_addr = iova;
return gfp_order; return order;
} }
static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment