From: Jason Gunthorpe <jgg@nvidia.com>
To: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: nicolinc@nvidia.com, linux-kernel@vger.kernel.org,
robin.murphy@arm.com, will@kernel.org, joro@8bytes.org,
kevin.tian@intel.com, jsnitsel@redhat.com, vasant.hegde@amd.com,
iommu@lists.linux.dev, santosh.shukla@amd.com,
sairaj.arunkodilkar@amd.com, jon.grimm@amd.com,
prashanthpra@google.com, wvw@google.com, wnliu@google.com,
gptran@google.com, kpsingh@google.com, joao.m.martins@oracle.com,
alejandro.j.jimenez@oracle.com
Subject: Re: [PATCH v5 11/14] iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation
Date: Tue, 18 Nov 2025 20:11:51 -0400 [thread overview]
Message-ID: <20251119001151.GH120075@nvidia.com> (raw)
In-Reply-To: <20251112182506.7165-12-suravee.suthikulpanit@amd.com>
On Wed, Nov 12, 2025 at 06:25:03PM +0000, Suravee Suthikulpanit wrote:
> Each nested domain is assigned guest domain ID (gDomID), which guest OS
> programs into guest Device Table Entry (gDTE). For each gDomID, the driver
> assigns a corresponding host domain ID (hDomID), which will be programmed
> into the host Device Table Entry (hDTE).
>
> The hDomID is allocated during amd_iommu_alloc_domain_nested(),
> and free during nested_domain_free(). The gDomID-to-hDomID mapping info
> (struct guest_domain_mapping_info) is stored in a per-viommu xarray
> (struct amd_iommu_viommu.gdomid_array), which is indexed by gDomID.
>
> Note also that parent domain can be shared among struct iommufd_viommu.
> Therefore, when hypervisor invalidates the nest parent domain, the AMD
> IOMMU command INVALIDATE_IOMMU_PAGES must be issued for each hDomID in
> the gdomid_array. This is handled by the iommu_flush_pages_v1_hdom_ids(),
> where it iterates through struct protection_domain.viommu_list.
>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
> drivers/iommu/amd/amd_iommu_types.h | 23 +++++++++
> drivers/iommu/amd/iommu.c | 35 +++++++++++++
> drivers/iommu/amd/iommufd.c | 34 ++++++++++++
> drivers/iommu/amd/nested.c | 80 +++++++++++++++++++++++++++++
> 4 files changed, 172 insertions(+)
I think this looks OK in general, just the locking needs fixing up.
> +static int iommu_flush_pages_v1_hdom_ids(struct protection_domain *pdom, u64 address, size_t size)
> +{
> + int ret = 0;
> + struct amd_iommu_viommu *aviommu;
> +
> + list_for_each_entry(aviommu, &pdom->viommu_list, pdom_list) {
> + unsigned long i;
> + struct guest_domain_mapping_info *gdom_info;
> + struct amd_iommu *iommu = container_of(aviommu->core.iommu_dev, struct amd_iommu, iommu);
> +
> + xa_for_each(&aviommu->gdomid_array, i, gdom_info) {
> + struct iommu_cmd cmd;
What is the locking for the xa here?
It looks missing too. Either hold the xa lock for this iteration, or
do something to hold the pdom lock when updating the xarray.
> + pr_debug("%s: iommu=%#x, hdom_id=%#x\n", __func__,
> + iommu->devid, gdom_info->hdom_id);
> + build_inv_iommu_pages(&cmd, address, size, gdom_info->hdom_id,
> + IOMMU_NO_PASID, false);
> + ret |= iommu_queue_command(iommu, &cmd);
> + }
> + }
> + return ret;
> +}
This is kind of painfully slow for invalidation but OK for now, we
don't really expect alot of parent invalidation traffic..
I think after we get this landed:
https://lore.kernel.org/r/cover.1762588839.git.nicolinc@nvidia.com
We should take a serious run at trying to make it shared code and have
AMD use it. That would resolve the performance concern..
> +static void amd_iommufd_viommu_destroy(struct iommufd_viommu *viommu)
> +{
> + unsigned long flags;
> + struct amd_iommu_viommu *entry, *next;
> + struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core);
> + struct protection_domain *pdom = aviommu->parent;
> +
> + spin_lock_irqsave(&pdom->lock, flags);
> + list_for_each_entry_safe(entry, next, &pdom->viommu_list, pdom_list) {
> + if (entry == aviommu)
> + list_del(&entry->pdom_list);
> + }
> + spin_unlock_irqrestore(&pdom->lock, flags);
Same remark as Nicolin
> static void nested_domain_free(struct iommu_domain *dom)
> {
> + struct guest_domain_mapping_info *curr;
> struct nested_domain *ndom = to_ndomain(dom);
> + struct amd_iommu_viommu *aviommu = ndom->viommu;
> +
> + if (!refcount_dec_and_test(&ndom->gdom_info->users))
> + return;
Same locking issues here, you have to hold the xa_lock while doing
this decrement through to thecmpxchg otherwise it will go wrong.
> + /*
> + * The refcount for the gdom_id to hdom_id mapping is zero.
> + * It is now safe to remove the mapping.
> + */
> + curr = xa_cmpxchg(&aviommu->gdomid_array, ndom->gdom_id,
> + ndom->gdom_info, NULL, GFP_ATOMIC);
> + if (curr) {
> + if (xa_err(curr)) {
> + pr_err("%s: Failed to free nested domain gdom_id=%#x\n",
> + __func__, ndom->gdom_id);
Don't log.. This should be a WARN_ON, the cmpxchg cannot fail unless
the xa is corrupted.
> + return;
> + }
> +
> + /* success */
> + pr_debug("%s: Free gdom_id=%#x, hdom_id=%#x\n",
> + __func__, ndom->gdom_id, curr->hdom_id);
> + kfree(curr);
> + }
> +
> + amd_iommu_pdom_id_free(ndom->gdom_info->hdom_id);
?? This should be before the kfree(curr). the hdom_id remains
allocated and valid so long as the gdom_info is allocated.
Jason
next prev parent reply other threads:[~2025-11-19 0:11 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-12 18:24 [PATCH v5 00/14] iommu/amd: Introduce Nested Translation support Suravee Suthikulpanit
2025-11-12 18:24 ` [PATCH v5 01/14] iommu/amd: Rename DEV_DOMID_MASK to DTE_DOMID_MASK Suravee Suthikulpanit
2025-11-12 18:24 ` [PATCH v5 02/14] iommu/amd: Make amd_iommu_pdom_id_alloc() non-static Suravee Suthikulpanit
2025-11-12 18:24 ` [PATCH v5 03/14] iommu/amd: Make amd_iommu_pdom_id_free() non-static Suravee Suthikulpanit
2025-11-12 18:24 ` [PATCH v5 04/14] iommu/amd: Make amd_iommu_make_clear_dte() non-static inline Suravee Suthikulpanit
2025-11-18 23:44 ` Jason Gunthorpe
2025-11-12 18:24 ` [PATCH v5 05/14] iommu/amd: Introduce helper function amd_iommu_update_dte() Suravee Suthikulpanit
2025-11-13 19:18 ` Nicolin Chen
2026-01-15 9:20 ` Suthikulpanit, Suravee
2025-11-18 23:50 ` Jason Gunthorpe
2025-11-12 18:24 ` [PATCH v5 06/14] iommufd: Introduce data struct for AMD nested domain allocation Suravee Suthikulpanit
2025-11-12 18:24 ` [PATCH v5 07/14] iommu/amd: Always enable GCR3TRPMode when supported Suravee Suthikulpanit
2025-11-13 19:19 ` Nicolin Chen
2025-11-12 18:25 ` [PATCH v5 08/14] iommu/amd: Add support for nest parent domain allocation Suravee Suthikulpanit
2025-11-12 18:25 ` [PATCH v5 09/14] iommu/amd: Introduce struct amd_iommu_viommu Suravee Suthikulpanit
2025-11-13 19:21 ` Nicolin Chen
2025-11-12 18:25 ` [PATCH v5 10/14] iommu/amd: Add support for nested domain allocation Suravee Suthikulpanit
2025-11-12 18:25 ` [PATCH v5 11/14] iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation Suravee Suthikulpanit
2025-11-13 20:36 ` Nicolin Chen
2025-11-19 0:02 ` Jason Gunthorpe
2026-01-15 9:25 ` Suthikulpanit, Suravee
2026-01-15 9:21 ` Suthikulpanit, Suravee
2025-11-19 0:11 ` Jason Gunthorpe [this message]
2025-11-19 1:10 ` Nicolin Chen
2025-11-12 18:25 ` [PATCH v5 12/14] iommu/amd: Refactor persistent DTE bits programming into amd_iommu_make_clear_dte() Suravee Suthikulpanit
2025-11-13 20:42 ` Nicolin Chen
2025-11-12 18:25 ` [PATCH v5 13/14] iommu/amd: Refactor logic to program the host page table in DTE Suravee Suthikulpanit
2025-11-13 21:19 ` Nicolin Chen
2025-11-13 21:29 ` Nicolin Chen
2025-11-19 0:21 ` Jason Gunthorpe
2025-11-19 0:20 ` Jason Gunthorpe
2026-01-15 9:24 ` Suthikulpanit, Suravee
2025-11-19 0:18 ` Jason Gunthorpe
2025-11-12 18:25 ` [PATCH v5 14/14] iommu/amd: Add support for nested domain attach/detach Suravee Suthikulpanit
2025-11-13 21:34 ` Nicolin Chen
2025-11-19 0:28 ` Jason Gunthorpe
2025-11-13 21:52 ` [PATCH v5 00/14] iommu/amd: Introduce Nested Translation support Nicolin Chen
2025-11-17 17:54 ` Jason Gunthorpe
2026-01-15 9:18 ` Suthikulpanit, Suravee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251119001151.GH120075@nvidia.com \
--to=jgg@nvidia.com \
--cc=alejandro.j.jimenez@oracle.com \
--cc=gptran@google.com \
--cc=iommu@lists.linux.dev \
--cc=joao.m.martins@oracle.com \
--cc=jon.grimm@amd.com \
--cc=joro@8bytes.org \
--cc=jsnitsel@redhat.com \
--cc=kevin.tian@intel.com \
--cc=kpsingh@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=prashanthpra@google.com \
--cc=robin.murphy@arm.com \
--cc=sairaj.arunkodilkar@amd.com \
--cc=santosh.shukla@amd.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=vasant.hegde@amd.com \
--cc=will@kernel.org \
--cc=wnliu@google.com \
--cc=wvw@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox