aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/amd_iommu.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index d8a0abf423ba..b599e80051fc 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1788,4 +1788,35 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom,
1788 iommu_flush_domain(domain->id); 1788 iommu_flush_domain(domain->id);
1789} 1789}
1790 1790
1791static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
1792 unsigned long iova)
1793{
1794 struct protection_domain *domain = dom->priv;
1795 unsigned long offset = iova & ~PAGE_MASK;
1796 phys_addr_t paddr;
1797 u64 *pte;
1798
1799 pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(iova)];
1800
1801 if (!IOMMU_PTE_PRESENT(*pte))
1802 return 0;
1803
1804 pte = IOMMU_PTE_PAGE(*pte);
1805 pte = &pte[IOMMU_PTE_L1_INDEX(iova)];
1806
1807 if (!IOMMU_PTE_PRESENT(*pte))
1808 return 0;
1809
1810 pte = IOMMU_PTE_PAGE(*pte);
1811 pte = &pte[IOMMU_PTE_L0_INDEX(iova)];
1812
1813 if (!IOMMU_PTE_PRESENT(*pte))
1814 return 0;
1815
1816 paddr = *pte & IOMMU_PAGE_MASK;
1817 paddr |= offset;
1818
1819 return paddr;
1820}
1821
1791#endif 1822#endif