summaryrefslogtreecommitdiff
path: root/drivers/iommu/amd/io_pgtable.c
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2020-12-15 10:37:03 +0300
committerJoerg Roedel <jroedel@suse.de>2021-01-28 18:51:18 +0300
commit441555c63aca3300a0f6cd5948dbf5bd6e7760b3 (patch)
tree0df0af8cb08965309f466bb4f1510018d2a55b30 /drivers/iommu/amd/io_pgtable.c
parent0633bbcc1eedb7015554254d54e14602b1d8b989 (diff)
downloadlinux-441555c63aca3300a0f6cd5948dbf5bd6e7760b3.tar.xz
iommu/amd: Introduce iommu_v1_iova_to_phys
This implements iova_to_phys for AMD IOMMU v1 pagetable, which will be used by the IO page table framework. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Link: https://lore.kernel.org/r/20201215073705.123786-12-suravee.suthikulpanit@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/amd/io_pgtable.c')
-rw-r--r--drivers/iommu/amd/io_pgtable.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
index d7924eb20178..b70eb79d05fb 100644
--- a/drivers/iommu/amd/io_pgtable.c
+++ b/drivers/iommu/amd/io_pgtable.c
@@ -488,6 +488,26 @@ unsigned long iommu_unmap_page(struct protection_domain *dom,
return unmapped;
}
+static phys_addr_t iommu_v1_iova_to_phys(struct io_pgtable_ops *ops, unsigned long iova)
+{
+ struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops);
+ unsigned long offset_mask, pte_pgsize;
+ u64 *pte, __pte;
+
+ if (pgtable->mode == PAGE_MODE_NONE)
+ return iova;
+
+ pte = fetch_pte(pgtable, iova, &pte_pgsize);
+
+ if (!pte || !IOMMU_PTE_PRESENT(*pte))
+ return 0;
+
+ offset_mask = pte_pgsize - 1;
+ __pte = __sme_clr(*pte & PM_ADDR_MASK);
+
+ return (__pte & ~offset_mask) | (iova & offset_mask);
+}
+
/*
* ----------------------------------------------------
*/
@@ -528,6 +548,8 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo
cfg->oas = IOMMU_OUT_ADDR_BIT_SIZE,
cfg->tlb = &v1_flush_ops;
+ pgtable->iop.ops.iova_to_phys = iommu_v1_iova_to_phys;
+
return &pgtable->iop;
}