diff options
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 31 |
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 | ||
1791 | static 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 |