diff options
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index dfbabd151a9c..f08d7865fe00 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1647,20 +1647,18 @@ static int | |||
1647 | domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, | 1647 | domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, |
1648 | u64 hpa, size_t size, int prot) | 1648 | u64 hpa, size_t size, int prot) |
1649 | { | 1649 | { |
1650 | u64 start_pfn, end_pfn; | 1650 | unsigned long start_pfn = hpa >> VTD_PAGE_SHIFT; |
1651 | unsigned long last_pfn = (hpa + size - 1) >> VTD_PAGE_SHIFT; | ||
1651 | struct dma_pte *pte; | 1652 | struct dma_pte *pte; |
1652 | int index; | 1653 | int index = 0; |
1653 | int addr_width = agaw_to_width(domain->agaw); | 1654 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
1654 | 1655 | ||
1655 | BUG_ON(hpa >> addr_width); | 1656 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); |
1656 | 1657 | ||
1657 | if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) | 1658 | if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) |
1658 | return -EINVAL; | 1659 | return -EINVAL; |
1659 | iova &= PAGE_MASK; | 1660 | |
1660 | start_pfn = ((u64)hpa) >> VTD_PAGE_SHIFT; | 1661 | while (start_pfn <= last_pfn) { |
1661 | end_pfn = (VTD_PAGE_ALIGN(((u64)hpa) + size)) >> VTD_PAGE_SHIFT; | ||
1662 | index = 0; | ||
1663 | while (start_pfn < end_pfn) { | ||
1664 | pte = pfn_to_dma_pte(domain, (iova >> VTD_PAGE_SHIFT) + index); | 1662 | pte = pfn_to_dma_pte(domain, (iova >> VTD_PAGE_SHIFT) + index); |
1665 | if (!pte) | 1663 | if (!pte) |
1666 | return -ENOMEM; | 1664 | return -ENOMEM; |