[PATCH v3 14/22] iommu/amd: Add per-VM private IPA alloc/map helpers

From: Suravee Suthikulpanit

Date: Mon Jun 29 2026 - 11:50:49 EST


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 <suravee.suthikulpanit@xxxxxxx>
---
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 897355a143d6..808f0b304006 100644
--- a/drivers/iommu/amd/viommu.c
+++ b/drivers/iommu/amd/viommu.c
@@ -374,3 +374,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_flush(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_flush_free(iommu, addr, size, *entry);
+
+ *entry = NULL;
+}
--
2.34.1