diff options
| author | Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | 2026-01-15 06:08:08 +0000 |
|---|---|---|
| committer | Joerg Roedel <joerg.roedel@amd.com> | 2026-01-18 10:56:12 +0100 |
| commit | b43a29def24f38a28085635e2be39566671976a8 (patch) | |
| tree | ec4722eeb568b80b8f322cfc4b513d4e7ff91f0e /drivers/iommu | |
| parent | b2bb0573ddb2dcac7ebcd65708e172ce0a1de754 (diff) | |
iommu/amd: Add support for nest parent domain allocation
To support nested translation, the nest parent domain is allocated with
IOMMU_HWPT_ALLOC_NEST_PARENT flag, and stores information of the v1 page
table for stage 2 (i.e. GPA->SPA).
Also, only support nest parent domain on AMD system, which can support
the Guest CR3 Table (GCR3TRPMode) feature. This feature is required in
order to program DTE[GCR3 Table Root Pointer] with the GPA.
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu')
| -rw-r--r-- | drivers/iommu/amd/iommu.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 2b7099e09852..a223387eec5c 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2769,6 +2769,14 @@ static struct iommu_domain *amd_iommu_domain_alloc_paging_v2(struct device *dev, return &domain->domain; } +static inline bool is_nest_parent_supported(u32 flags) +{ + /* Only allow nest parent when these features are supported */ + return check_feature(FEATURE_GT) && + check_feature(FEATURE_GIOSUP) && + check_feature2(FEATURE_GCR3TRPMODE); +} + static struct iommu_domain * amd_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags, const struct iommu_user_data *user_data) @@ -2776,16 +2784,28 @@ amd_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags, { struct amd_iommu *iommu = get_amd_iommu_from_dev(dev); const u32 supported_flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING | - IOMMU_HWPT_ALLOC_PASID; + IOMMU_HWPT_ALLOC_PASID | + IOMMU_HWPT_ALLOC_NEST_PARENT; if ((flags & ~supported_flags) || user_data) return ERR_PTR(-EOPNOTSUPP); switch (flags & supported_flags) { case IOMMU_HWPT_ALLOC_DIRTY_TRACKING: - /* Allocate domain with v1 page table for dirty tracking */ - if (!amd_iommu_hd_support(iommu)) + case IOMMU_HWPT_ALLOC_NEST_PARENT: + case IOMMU_HWPT_ALLOC_DIRTY_TRACKING | IOMMU_HWPT_ALLOC_NEST_PARENT: + /* + * Allocate domain with v1 page table for dirty tracking + * and/or Nest parent. + */ + if ((flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) && + !amd_iommu_hd_support(iommu)) + break; + + if ((flags & IOMMU_HWPT_ALLOC_NEST_PARENT) && + !is_nest_parent_supported(flags)) break; + return amd_iommu_domain_alloc_paging_v1(dev, flags); case IOMMU_HWPT_ALLOC_PASID: /* Allocate domain with v2 page table if IOMMU supports PASID. */ |
