From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
To: <linux-kernel@vger.kernel.org>, <iommu@lists.linux.dev>,
<joro@8bytes.org>, <jgg@nvidia.com>
Cc: <yi.l.liu@intel.com>, <kevin.tian@intel.com>,
<nicolinc@nvidia.com>, <vasant.hegde@amd.com>,
<jon.grimm@amd.com>, <santosh.shukla@amd.com>, <Sairaj.K@amd.com>,
<jay.chen@amd.com>, <wvw@google.com>, <wnliu@google.com>,
<dantuluris@google.com>, <chriscli@google.com>,
<kpsingh@google.com>, <alejandro.j.jimenez@oracle.com>,
<joao.m.martins@oracle.com>,
"Suravee Suthikulpanit" <suravee.suthikulpanit@amd.com>
Subject: [PATCH 24/24] iommu/amd: Relocate vIOMMU translate-device-id on PCI reserve
Date: Mon, 27 Jul 2026 13:29:13 +0000 [thread overview]
Message-ID: <20260727132913.22475-25-suravee.suthikulpanit@amd.com> (raw)
In-Reply-To: <20260727132913.22475-1-suravee.suthikulpanit@amd.com>
When PCI attach reserves a BDF already allocated to a vIOMMU, relocate
that vIOMMU to a newly allocated translate-device-id before marking the
BDF reserved for the device. Reprogram translation DTE and VFctrl under
trans_devid_lock; roll back the pool on failure.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
drivers/iommu/amd/trans_devid.c | 116 +++++++++++++++++++++++++++++++-
1 file changed, 115 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd/trans_devid.c b/drivers/iommu/amd/trans_devid.c
index 9d7d93c5dcdb..6fb1ba3c9444 100644
--- a/drivers/iommu/amd/trans_devid.c
+++ b/drivers/iommu/amd/trans_devid.c
@@ -82,16 +82,120 @@ void amd_iommu_pci_seg_trans_devid_fini(struct amd_iommu_pci_seg *pci_seg)
xa_destroy(&pci_seg->trans_devid_xa);
}
+/**
+ * trans_devid_do_relocate - move vIOMMU translation DTE from @old_id to @new_id
+ *
+ * Caller holds @aviommu->trans_devid_lock. Pool xarray already records @new_id
+ * as allocated to @aviommu and @old_id as reserved.
+ */
+static int trans_devid_do_relocate(struct amd_iommu_viommu *aviommu,
+ u16 old_id, u16 new_id)
+{
+ struct iommufd_viommu *viommu = &aviommu->core;
+ struct amd_iommu *iommu =
+ container_of(viommu->iommu_dev, struct amd_iommu, iommu);
+ int ret;
+
+ aviommu->trans_devid = new_id;
+
+ ret = amd_iommu_set_translate_dte(viommu);
+ if (ret)
+ goto err_restore_id;
+
+ amd_iommu_update_vfctrl_mmio_translate_devid(iommu, aviommu->gid, new_id);
+
+ if (search_dev_data(iommu, old_id))
+ amd_iommu_clear_translate_dte(iommu, old_id);
+
+ return 0;
+
+err_restore_id:
+ aviommu->trans_devid = old_id;
+ return ret;
+}
+
+/**
+ * trans_devid_relocate - move an allocated id to a new slot and reserve @from_id
+ *
+ * Called when PCI attach needs a BDF that a vIOMMU already owns. Updates the
+ * per-segment pool, then reprograms DTE and VFctrl on the owning vIOMMU.
+ *
+ * Locking: takes @aviommu->trans_devid_lock, then pci_seg->trans_devid_mutex
+ * (same order as destroy). Hardware steps run with the viommu lock held and
+ * the segment mutex dropped.
+ */
+static int trans_devid_relocate(struct amd_iommu_pci_seg *pci_seg, u16 from_id,
+ struct amd_iommu_viommu *aviommu)
+{
+ u16 new_id;
+ int ret;
+
+ mutex_lock(&aviommu->trans_devid_lock);
+
+ mutex_lock(&pci_seg->trans_devid_mutex);
+ if (trans_devid_xa_owner(xa_load(&pci_seg->trans_devid_xa, from_id)) !=
+ aviommu) {
+ ret = -ENOENT;
+ goto unlock_seg;
+ }
+
+ if (aviommu->trans_devid != from_id) {
+ ret = -EINVAL;
+ goto unlock_seg;
+ }
+
+ new_id = trans_devid_find_free_locked(pci_seg);
+ if (new_id < 0) {
+ ret = new_id;
+ goto unlock_seg;
+ }
+
+ ret = trans_devid_xa_install_allocated_locked(pci_seg, new_id, aviommu);
+ if (ret)
+ goto unlock_seg;
+
+ ret = trans_devid_xa_install_reserved_locked(pci_seg, from_id);
+ if (ret) {
+ xa_erase(&pci_seg->trans_devid_xa, new_id);
+ goto unlock_seg;
+ }
+
+ mutex_unlock(&pci_seg->trans_devid_mutex);
+
+ ret = trans_devid_do_relocate(aviommu, from_id, new_id);
+ if (ret) {
+ mutex_lock(&pci_seg->trans_devid_mutex);
+ xa_erase(&pci_seg->trans_devid_xa, new_id);
+ trans_devid_xa_install_allocated_locked(pci_seg, from_id,
+ aviommu);
+ mutex_unlock(&pci_seg->trans_devid_mutex);
+ }
+
+ mutex_unlock(&aviommu->trans_devid_lock);
+ return ret;
+
+unlock_seg:
+ mutex_unlock(&pci_seg->trans_devid_mutex);
+ mutex_unlock(&aviommu->trans_devid_lock);
+ return ret;
+}
+
/**
* amd_iommu_trans_devid_reserve - occupy @id so it is never returned by alloc
*
* Reservation is done when attaching device to a domain (see amd_iommu_attach_device()).
*
- * Return: 0 on success. A second reserve of an already-reserved @id succeeds.
+ * When @id is allocated to a vIOMMU (e.g. after PCI hot-plug), the driver relocates
+ * that vIOMMU to a newly allocated translate-device-id and reserves @id for the PCI
+ * function.
+ *
+ * Return: 0 on success, %-ENOSPC if relocation cannot find a free id, or another
+ * errno from relocation. A second reserve of an already-reserved @id succeeds.
*/
int amd_iommu_trans_devid_reserve(struct amd_iommu_pci_seg *pci_seg, u16 id)
{
void *entry;
+ struct amd_iommu_viommu *aviommu;
int ret = 0;
mutex_lock(&pci_seg->trans_devid_mutex);
@@ -99,6 +203,16 @@ int amd_iommu_trans_devid_reserve(struct amd_iommu_pci_seg *pci_seg, u16 id)
if (trans_devid_xa_is_reserved(entry))
goto unlock;
+ aviommu = trans_devid_xa_owner(entry);
+ if (aviommu) {
+ mutex_unlock(&pci_seg->trans_devid_mutex);
+ ret = trans_devid_relocate(pci_seg, id, aviommu);
+ if (!ret)
+ pr_debug("%s: Reserved trans_devid %#x after relocation (seg %#x)\n",
+ __func__, id, pci_seg->id);
+ return ret;
+ }
+
ret = trans_devid_xa_install_reserved_locked(pci_seg, id);
unlock:
mutex_unlock(&pci_seg->trans_devid_mutex);
--
2.34.1
next prev parent reply other threads:[~2026-07-27 13:32 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-27 13:28 [PATCH v4 00/24] iommu/amd: Introduce AMD Hardware-accelerated Virtualized IOMMU (vIOMMU) Support Suravee Suthikulpanit
2026-07-27 13:28 ` [PATCH 01/24] iommu/amd: Make amd_iommu_completion_wait() non-static Suravee Suthikulpanit
2026-08-05 17:01 ` Vasant Hegde
2026-07-27 13:28 ` [PATCH 02/24] iommu/amd: Introduce vIOMMU-specific events and event Suravee Suthikulpanit
2026-08-10 7:12 ` Vasant Hegde
2026-07-27 13:28 ` [PATCH 03/24] iommu/amd: Detect and initialize AMD vIOMMU feature Suravee Suthikulpanit
2026-08-10 8:13 ` Vasant Hegde
2026-07-27 13:28 ` [PATCH 04/24] iommu/amd: Introduce IOMMUFD vIOMMU support for AMD Suravee Suthikulpanit
2026-07-27 13:28 ` [PATCH 05/24] iommu/amd: Allocate Guest IDs for IOMMUFD vIOMMU instances Suravee Suthikulpanit
2026-08-10 9:21 ` Vasant Hegde
2026-07-27 13:28 ` [PATCH 06/24] iommu/amd: Map vIOMMU VF and VF Control MMIO BARs Suravee Suthikulpanit
2026-08-10 10:00 ` Vasant Hegde
2026-07-27 13:28 ` [PATCH 07/24] iommu/amd: Add support for AMD vIOMMU VF MMIO region Suravee Suthikulpanit
2026-08-10 10:49 ` Vasant Hegde
2026-07-27 13:28 ` [PATCH 08/24] iommu/amd: Introduce Reset vMMIO Command Suravee Suthikulpanit
2026-07-27 13:28 ` [PATCH 09/24] iommu/amd: Introduce and map vIOMMU private IPA region Suravee Suthikulpanit
2026-07-27 13:28 ` [PATCH 10/24] iommu/amd: Pass iommu to device_flush_dte() Suravee Suthikulpanit
2026-08-10 11:07 ` Vasant Hegde
2026-07-27 13:29 ` [PATCH 11/24] iommu/amd: Export amd_iommu_alloc_dev_data() helper Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 12/24] iommu/amd: Pass iommu and devid to amd_iommu_make_clear_dte() Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 13/24] iommu/amd: Assign IOMMU Private Address domain to IOMMU Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 14/24] iommu/amd: Add per-VM private IPA alloc/map helpers Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 15/24] iommu/amd: Add helper functions to manage DevID / DomID mapping tables Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 16/24] iommu/amd: Introduce IOMMUFD vDevice support for AMD Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 17/24] iommu/amd: Introduce helper function for updating domain ID mapping table Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 18/24] iommu/amd: Introduce helper function for updating device " Suravee Suthikulpanit
2026-08-10 15:17 ` Vasant Hegde
2026-07-27 13:29 ` [PATCH 19/24] iommu/amd: Add per-segment translate device ID pool Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 20/24] iommu/amd: Reserve translate-device-id for PCI requestor aliases Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 21/24] iommu/amd: Add translation DTE and VFctrl TransDevID helpers Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 22/24] iommu/amd: Add translate-device-id alloc/free with vIOMMU owner Suravee Suthikulpanit
2026-07-27 13:29 ` [PATCH 23/24] iommu/amd: Assign per-vIOMMU translate device ID Suravee Suthikulpanit
2026-07-27 13:29 ` Suravee Suthikulpanit [this message]
2026-08-11 7:18 ` [PATCH v4 00/24] iommu/amd: Introduce AMD Hardware-accelerated Virtualized IOMMU (vIOMMU) Support Tian, Kevin
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=20260727132913.22475-25-suravee.suthikulpanit@amd.com \
--to=suravee.suthikulpanit@amd.com \
--cc=Sairaj.K@amd.com \
--cc=alejandro.j.jimenez@oracle.com \
--cc=chriscli@google.com \
--cc=dantuluris@google.com \
--cc=iommu@lists.linux.dev \
--cc=jay.chen@amd.com \
--cc=jgg@nvidia.com \
--cc=joao.m.martins@oracle.com \
--cc=jon.grimm@amd.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kpsingh@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=santosh.shukla@amd.com \
--cc=vasant.hegde@amd.com \
--cc=wnliu@google.com \
--cc=wvw@google.com \
--cc=yi.l.liu@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.