[PATCH 14/24] iommu/amd: Add per-VM private IPA alloc/map helpers
Suravee Suthikulpanit <[email protected]> Mon, 27 Jul 2026 13:29:03 +0000
| Newsgroups | dev.linux.lists.iommu,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Guest device ID and guest domain ID tables use dedicated slots in the vIOMMU private address (IPA) region, indexed by guest ID (GID). Add alloc_private_vm_region() and free_private_vm_region() to allocate backing pages, map them through viommu_pdom, and tear down with an unmap flush on VM destroy. Signed-off-by: Suravee Suthikulpanit <[email protected]> --- drivers/iommu/amd/viommu.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/iommu/amd/viommu.c b/drivers/iommu/amd/viommu.c index d2782f9070ee..2c1a267826dc 100644 --- a/drivers/iommu/amd/viommu.c +++ b/drivers/iommu/amd/viommu.c @@ -367,3 +367,41 @@ int __init amd_viommu_init(struct amd_iommu *iommu) viommu_free_self_dev_data(iommu, dte_set); return ret; } + +static int __maybe_unused alloc_private_vm_region(struct amd_iommu *iommu, u64 **entry, + u64 base, size_t size, u16 gid) +{ + int ret; + void *va = NULL; + u64 addr = base + (gid * size); + + ret = viommu_priv_alloc_map(iommu, addr, size, GFP_KERNEL | __GFP_ZERO, &va); + if (ret) { + *entry = NULL; + return ret; + } + + *entry = (u64 *)va; + + pr_debug("%s: entry=%#llx(%#llx), addr=%#llx, size=%#lx\n", __func__, + (unsigned long long)*entry, iommu_virt_to_phys(*entry), addr, size); + + return 0; +} + +static void __maybe_unused free_private_vm_region(struct amd_iommu *iommu, u64 **entry, + u64 base, size_t size, u16 gid) +{ + u64 addr = base + (gid * size); + + if (!iommu || !iommu->viommu_pdom || !*entry) + return; + + pr_debug("%s: entry=%#llx(%#llx), base=%#llx, addr=%#llx, size=%#lx\n", + __func__, (unsigned long long)*entry, + iommu_virt_to_phys(*entry), base, addr, size); + + viommu_priv_unmap_free(iommu, addr, size, *entry); + + *entry = NULL; +} -- 2.34.1