aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorAllen Kay <allen.m.kay@intel.com>2011-10-14 12:31:54 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-12-21 12:57:37 -0800
commitb0db8ad8ad0cb8f2980c3bd742f4f95eb24818b4 (patch)
treec28b92080f32260be8c1f77d34e6d5a7bd7446c3 /drivers/pci
parent2afc2fbeaafb4c9a5ab0f92efa0fa739c95c26e4 (diff)
downloadkernel_samsung_smdk4412-b0db8ad8ad0cb8f2980c3bd742f4f95eb24818b4.zip
kernel_samsung_smdk4412-b0db8ad8ad0cb8f2980c3bd742f4f95eb24818b4.tar.gz
kernel_samsung_smdk4412-b0db8ad8ad0cb8f2980c3bd742f4f95eb24818b4.tar.bz2
intel-iommu: fix return value of iommu_unmap() API
commit 292827cb164ad00cc7689a21283b1261c0b6daed upstream. 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: Allen Kay <allen.m.kay@intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: Youquan Song <youquan.song@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/intel-iommu.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index f02c34d..4f255c8 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -817,13 +817,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);
@@ -847,6 +848,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 */
@@ -3865,14 +3869,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,