diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2008-12-02 13:59:10 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-01-03 08:11:56 -0500 |
commit | eb74ff6cc0080c7f6270fdfffba65c4eff23d3ad (patch) | |
tree | 243b07c9511fd7ca216e0d5512f66415ee97f39a /arch/x86/kernel/amd_iommu.c | |
parent | c6229ca649aa9b312d1f1de20af8d2603b14eead (diff) |
AMD IOMMU: add domain unmap function for IOMMU API
Impact: add a generic function to unmap pages into protection domains
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 1fcedbe39a99..d8a0abf423ba 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -445,6 +445,30 @@ static int iommu_map_page(struct protection_domain *dom, | |||
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
447 | 447 | ||
448 | #ifdef CONFIG_IOMMU_API | ||
449 | static void iommu_unmap_page(struct protection_domain *dom, | ||
450 | unsigned long bus_addr) | ||
451 | { | ||
452 | u64 *pte; | ||
453 | |||
454 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)]; | ||
455 | |||
456 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
457 | return; | ||
458 | |||
459 | pte = IOMMU_PTE_PAGE(*pte); | ||
460 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
461 | |||
462 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
463 | return; | ||
464 | |||
465 | pte = IOMMU_PTE_PAGE(*pte); | ||
466 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
467 | |||
468 | *pte = 0; | ||
469 | } | ||
470 | #endif | ||
471 | |||
448 | /* | 472 | /* |
449 | * This function checks if a specific unity mapping entry is needed for | 473 | * This function checks if a specific unity mapping entry is needed for |
450 | * this specific IOMMU. | 474 | * this specific IOMMU. |
@@ -1747,4 +1771,21 @@ static int amd_iommu_map_range(struct iommu_domain *dom, | |||
1747 | return 0; | 1771 | return 0; |
1748 | } | 1772 | } |
1749 | 1773 | ||
1774 | static void amd_iommu_unmap_range(struct iommu_domain *dom, | ||
1775 | unsigned long iova, size_t size) | ||
1776 | { | ||
1777 | |||
1778 | struct protection_domain *domain = dom->priv; | ||
1779 | unsigned long i, npages = iommu_num_pages(iova, size, PAGE_SIZE); | ||
1780 | |||
1781 | iova &= PAGE_MASK; | ||
1782 | |||
1783 | for (i = 0; i < npages; ++i) { | ||
1784 | iommu_unmap_page(domain, iova); | ||
1785 | iova += PAGE_SIZE; | ||
1786 | } | ||
1787 | |||
1788 | iommu_flush_domain(domain->id); | ||
1789 | } | ||
1790 | |||
1750 | #endif | 1791 | #endif |