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 21/24] iommu/amd: Add translation DTE and VFctrl TransDevID helpers
Date: Mon, 27 Jul 2026 13:29:10 +0000 [thread overview]
Message-ID: <20260727132913.22475-22-suravee.suthikulpanit@amd.com> (raw)
In-Reply-To: <20260727132913.22475-1-suravee.suthikulpanit@amd.com>
The hardware vIOMMU uses a per-vIOMMU translate device ID (TransDevID)
to index the host device table when guest IOMMU traffic needs GPA->SPA
translation. The VF Control guest miscellaneous register tells the
IOMMU which TransDevID to use; the corresponding device table entry
(DTE) points at the nest parent v1 page table that performs the walk
from guest physical to system physical addresses.
Add amd_iommu_set_translate_dte() and amd_iommu_clear_translate_dte()
to install or clear that DTE for a given TransDevID slot through
iommu_dev_data and the existing DTE update path, restoring IVRS
persistent bits via amd_iommu_make_clear_dte() on teardown. Add
amd_iommu_update_vfctrl_mmio_translate_devid() to publish the
TransDevID in VFctrl guest-misc MMIO, and
VIOMMU_VFCTRL_GUEST_MISC_CONTROL_OFFSET for the register offset.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
drivers/iommu/amd/amd_iommu.h | 5 ++
drivers/iommu/amd/amd_iommu_types.h | 2 +
drivers/iommu/amd/iommu.c | 82 ++++++++++++++++++++++++++++-
3 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
index f61cc51ef9a2..200640ed0ef6 100644
--- a/drivers/iommu/amd/amd_iommu.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -232,6 +232,11 @@ static inline void
amd_iommu_pci_seg_trans_devid_fini(struct amd_iommu_pci_seg *pci_seg) { }
#endif
+int amd_iommu_set_translate_dte(struct iommufd_viommu *viommu);
+void amd_iommu_clear_translate_dte(struct amd_iommu *iommu, u32 trans_devid);
+void amd_iommu_update_vfctrl_mmio_translate_devid(struct amd_iommu *iommu,
+ u16 gid, u32 trans_devid);
+
static inline void
amd_iommu_make_clear_dte(struct amd_iommu *iommu, u16 devid,
struct dev_table_entry *new)
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index c102d059964a..f288a7b384d0 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -495,6 +495,7 @@ extern bool amdr_ivrs_remap_support;
/* VIOMMU stuff */
#define VIOMMU_VF_MMIO_ENTRY_SIZE 4096
#define VIOMMU_VFCTRL_MMIO_ENTRY_SIZE 64
+#define VIOMMU_VFCTRL_GUEST_MISC_CONTROL_OFFSET 0x10
/* Host ioremap/request_mem_region sizes for VF / VF_CNTL BARs */
#define VIOMMU_VF_MMIO_MAP_SIZE 0x10000000UL
@@ -556,6 +557,7 @@ struct amd_iommu_viommu {
u64 *devid_table;
u64 *domid_table;
+ u16 trans_devid;
/* Offset for mmap() of guest VF MMIO; set after iommufd_viommu_alloc_mmap(). */
unsigned long vfmmio_mmap_offset;
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 6207879528bf..ad592c8aa455 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -213,7 +213,12 @@ void amd_iommu_update_dte(struct amd_iommu *iommu,
struct dev_table_entry *new)
{
update_dte256(iommu, dev_data, new);
- clone_aliases(iommu, dev_data->dev);
+ /*
+ * The dev_data for trans_devid does not have struct dev.
+ * So clone_aliases is not supported for translate-device-id.
+ */
+ if (dev_data->dev)
+ clone_aliases(iommu, dev_data->dev);
device_flush_dte(iommu, dev_data);
amd_iommu_completion_wait(iommu);
}
@@ -1747,7 +1752,11 @@ static int device_flush_dte(struct amd_iommu *iommu, struct iommu_dev_data *dev_
u16 alias;
int ret;
- if (dev_is_pci(dev_data->dev))
+ /*
+ * The dev_data for trans_devid does not have struct dev.
+ * So, it is not considered as a PCI device.
+ */
+ if (dev_data->dev && dev_is_pci(dev_data->dev))
pdev = to_pci_dev(dev_data->dev);
if (pdev)
@@ -3275,6 +3284,75 @@ static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain)
return true;
}
+#if IS_ENABLED(CONFIG_AMD_IOMMU_IOMMUFD)
+
+void amd_iommu_update_vfctrl_mmio_translate_devid(struct amd_iommu *iommu,
+ u16 gid, u32 devid)
+{
+ writeq((devid & 0xFFFFULL) << 16,
+ VIOMMU_VFCTRL_MMIO_BASE(iommu, gid) +
+ VIOMMU_VFCTRL_GUEST_MISC_CONTROL_OFFSET);
+}
+
+int amd_iommu_set_translate_dte(struct iommufd_viommu *viommu)
+{
+ 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 protection_domain *pdom = aviommu->parent;
+ u16 gid = aviommu->gid;
+ u32 trans_devid = aviommu->trans_devid;
+ struct dev_table_entry new = {};
+ struct iommu_dev_data *trans_dev_data;
+ struct pt_iommu_amdv1_hw_info pt_info;
+
+ trans_dev_data = search_dev_data(iommu, trans_devid);
+ if (!trans_dev_data) {
+ trans_dev_data = amd_iommu_alloc_dev_data(iommu, trans_devid);
+ if (!trans_dev_data) {
+ pr_err("%s: Failed to allocate dev_data for translate-device-id %#x\n",
+ __func__, trans_devid);
+ return -ENOMEM;
+ }
+ }
+
+ trans_dev_data->dev = NULL;
+ trans_dev_data->devid = trans_devid;
+ trans_dev_data->domain = pdom;
+
+ amd_iommu_make_clear_dte(iommu, trans_devid, &new);
+ /* Setup DTE for v1 page table at the offset specified by trans_devid */
+ pt_iommu_amdv1_hw_info(&pdom->amdv1, &pt_info);
+
+ pr_debug("%s: gid=%#x, iommu_devid=%#x, devid=%#x, host_pt_root=%#llx, mode=%#x\n",
+ __func__, gid, iommu->devid, trans_devid, pt_info.host_pt_root, pt_info.mode);
+
+ amd_iommu_set_dte_v1(trans_dev_data, pdom, pdom->id, &pt_info, &new);
+ amd_iommu_update_dte(iommu, trans_dev_data, &new);
+ return 0;
+}
+
+void amd_iommu_clear_translate_dte(struct amd_iommu *iommu, u32 trans_devid)
+{
+ struct dev_table_entry new = {};
+ struct iommu_dev_data *trans_dev_data;
+
+ pr_debug("%s: iommu_devid=%#x, trans_devid=%#x\n",
+ __func__, iommu->devid, trans_devid);
+
+ trans_dev_data = search_dev_data(iommu, trans_devid);
+ if (!trans_dev_data) {
+ WARN_ON_ONCE(1);
+ return;
+ }
+
+ amd_iommu_make_clear_dte(iommu, trans_devid, &new);
+ amd_iommu_update_dte(iommu, trans_dev_data, &new);
+ amd_iommu_free_dev_data(iommu, trans_dev_data);
+}
+#endif /* CONFIG_AMD_IOMMU_IOMMUFD */
+
const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.hw_info = amd_iommufd_hw_info,
--
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 ` Suravee Suthikulpanit [this message]
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 ` [PATCH 24/24] iommu/amd: Relocate vIOMMU translate-device-id on PCI reserve Suravee Suthikulpanit
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-22-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.