RE: [RFCv2 PATCH 6/7] iommu/amd: Add nested domain allocation support

From: Tian, Kevin
Date: Mon Jan 22 2024 - 03:55:57 EST


> From: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
> Sent: Friday, January 12, 2024 8:07 AM
>
> To support nested translation, the parent domain is allocated with flag
> IOMMU_HWPT_ALLOC_NEST_PARENT, and stores information of the v1 page
> table
> for stage 2 (i.e. GPA->SPA), whereas the child domain stores information
> of the GCR3 root pointer table for stage 1 (i.e. GVA->GPA).

put support of NEST_PARENT in a separate patch.

> @@ -569,6 +572,9 @@ struct protection_domain {
> bool dirty_tracking; /* dirty tracking is enabled in the domain */
> unsigned dev_cnt; /* devices assigned to this domain */
> unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference
> count */
> + struct protection_domain *parent; /* Nested parent domain */
> + u16 guest_paging_mode; /* Guest paging mode */
> + u16 guest_domain_id; /* Guest domain ID */

not used

> +struct iommu_domain *do_iommu_domain_alloc(unsigned int type,
> struct device *dev, u32 flags)
> {
> bool dirty_tracking = flags &
> IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
> @@ -2454,7 +2465,10 @@ static struct iommu_domain
> *do_iommu_domain_alloc(unsigned int type,
> if (iommu) {
> domain->domain.type = type;
> domain->domain.pgsize_bitmap = iommu->iommu.ops-
> >pgsize_bitmap;
> - domain->domain.ops = iommu->iommu.ops-
> >default_domain_ops;
> + if (type == IOMMU_DOMAIN_NESTED)
> + domain->domain.ops = &nested_domain_ops;
> + else
> + domain->domain.ops = iommu->iommu.ops-
> >default_domain_ops;
>
> if (dirty_tracking)
> domain->domain.dirty_ops = &amd_dirty_ops;

dirty_tracking doesn't apply to nested domain

> +
> +static bool check_nested_support(u32 flags)
> +{
> + if (!(flags & IOMMU_HWPT_ALLOC_NEST_PARENT))
> + return true;

it's more readable by putting this check in the caller.

> +
> + /*
> + * When allocated nested parent domain, the device may already
> + * have been attached to a domain. For example, a device is already
> + * attached to the domain allocated by VFIO, which contains GPA-
> >SPA mapping.
> + * In such case, return reference to the same domain.
> + */
> + if (dev_data->domain && nested_parent) {
> + pr_debug("%s: Found exist: protection domain id=%#x\n",
> + __func__, dev_data->domain->id);
> + dom = &dev_data->domain->domain;

alloc() shouldn't deal with domain reuse. it's the decision in the
caller. If the caller wants to reuse then it can try to attach to an
existing domain if compatible.

if the caller wants to create a new domain then just follow it.