[PATCH 07/24] iommu/amd: Add support for AMD vIOMMU VF MMIO region
Suravee Suthikulpanit <[email protected]> Mon, 27 Jul 2026 13:28:56 +0000
| Newsgroups | dev.linux.lists.iommu,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
The AMD vIOMMU virtualizes guest MMIO registers at the 3rd 4K region. This is achieved using the iommufd_viommu_alloc_mmap(). Co-developed-by: Vasant Hegde <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Signed-off-by: Suravee Suthikulpanit <[email protected]> --- drivers/iommu/amd/amd_iommu_types.h | 3 +++ drivers/iommu/amd/amd_viommu.h | 7 +++++++ drivers/iommu/amd/iommufd.c | 17 ++++++++++++++++- drivers/iommu/amd/viommu.c | 10 ++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index e88e0bacd1a9..cc7049bbfa14 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -540,6 +540,9 @@ struct amd_iommu_viommu { * Indexed by guest domain ID. */ struct xarray gdomid_array; + + /* Offset for mmap() of guest VF MMIO; set after iommufd_viommu_alloc_mmap(). */ + unsigned long vfmmio_mmap_offset; }; /* diff --git a/drivers/iommu/amd/amd_viommu.h b/drivers/iommu/amd/amd_viommu.h index d0c4fdd00809..447692b9101c 100644 --- a/drivers/iommu/amd/amd_viommu.h +++ b/drivers/iommu/amd/amd_viommu.h @@ -12,6 +12,8 @@ int amd_viommu_init(struct amd_iommu *iommu); void __init amd_viommu_uninit(struct amd_iommu *iommu); +u64 amd_viommu_get_vfmmio_addr(struct amd_iommu *iommu, u16 gid); + #else static inline int amd_viommu_init(struct amd_iommu *iommu) @@ -23,6 +25,11 @@ static inline void amd_viommu_uninit(struct amd_iommu *iommu) { } +static inline u64 amd_viommu_get_vfmmio_addr(struct amd_iommu *iommu, u16 gid) +{ + return 0; +} + #endif /* CONFIG_AMD_IOMMU_IOMMUFD */ #endif /* AMD_VIOMMU_H */ diff --git a/drivers/iommu/amd/iommufd.c b/drivers/iommu/amd/iommufd.c index ec3c14e18c7b..9f76bfa1d6ea 100644 --- a/drivers/iommu/amd/iommufd.c +++ b/drivers/iommu/amd/iommufd.c @@ -7,6 +7,7 @@ #include "iommufd.h" #include "amd_iommu.h" +#include "amd_viommu.h" #include "amd_iommu_types.h" static const struct iommufd_viommu_ops amd_viommu_ops; @@ -44,11 +45,12 @@ int amd_iommufd_viommu_init(struct iommufd_viommu *viommu, struct iommu_domain * const struct iommu_user_data *user_data) { int ret; + phys_addr_t page_base; unsigned long flags; struct iommu_viommu_amd data = {}; struct protection_domain *pdom = to_pdomain(parent); - struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core); struct amd_iommu *iommu = container_of(viommu->iommu_dev, struct amd_iommu, iommu); + struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core); xa_init_flags(&aviommu->gdomid_array, XA_FLAGS_ALLOC1); aviommu->parent = pdom; @@ -68,6 +70,16 @@ int amd_iommufd_viommu_init(struct iommufd_viommu *viommu, struct iommu_domain * aviommu->gid = ret; pr_debug("%s: gid=%#x", __func__, aviommu->gid); + page_base = amd_viommu_get_vfmmio_addr(iommu, aviommu->gid); + + ret = iommufd_viommu_alloc_mmap(&aviommu->core, + page_base, SZ_4K, + &aviommu->vfmmio_mmap_offset); + if (ret) + goto err_mmap; + + data.out_vfmmio_mmap_offset = aviommu->vfmmio_mmap_offset; + ret = iommu_copy_struct_to_user(user_data, &data, IOMMU_VIOMMU_TYPE_AMD, out_vfmmio_mmap_offset); @@ -82,6 +94,8 @@ int amd_iommufd_viommu_init(struct iommufd_viommu *viommu, struct iommu_domain * return 0; err_init: + iommufd_viommu_destroy_mmap(&aviommu->core, aviommu->vfmmio_mmap_offset); +err_mmap: amd_iommu_gid_free(iommu, aviommu->gid); err_gid: return ret; @@ -100,6 +114,7 @@ static void amd_iommufd_viommu_destroy(struct iommufd_viommu *viommu) list_del(&aviommu->pdom_list); spin_unlock_irqrestore(&pdom->lock, flags); xa_destroy(&aviommu->gdomid_array); + iommufd_viommu_destroy_mmap(&aviommu->core, aviommu->vfmmio_mmap_offset); amd_iommu_gid_free(iommu, aviommu->gid); } diff --git a/drivers/iommu/amd/viommu.c b/drivers/iommu/amd/viommu.c index 014ae16bf58b..ee8c09f13035 100644 --- a/drivers/iommu/amd/viommu.c +++ b/drivers/iommu/amd/viommu.c @@ -131,6 +131,16 @@ static int __init viommu_vf_vfcntl_init(struct amd_iommu *iommu) return -ENOMEM; } +/* + * Returns VF MMIO BAR offset for the give guest ID which will be + * mapped to guest vIOMMU 3rd 4K MMIO address + */ +u64 amd_viommu_get_vfmmio_addr(struct amd_iommu *iommu, u16 gid) +{ + /* TODO: Add check for sVIOMMU and set gid[bit 15] */ + return iommu->vf_base_phys + gid * VIOMMU_VF_MMIO_ENTRY_SIZE; +} + int __init amd_viommu_init(struct amd_iommu *iommu) { int ret; -- 2.34.1