From: Ankit Soni <Ankit.Soni@amd.com>
To: <iommu@lists.linux.dev>, <joro@8bytes.org>, <will@kernel.org>,
<jgg@nvidia.com>
Cc: <suravee.suthikulpanit@amd.com>, <vasant.hegde@amd.com>,
<robin.murphy@arm.com>, <joao.m.martins@oracle.com>,
<alejandro.j.jimenez@oracle.com>, <pasha.tatashin@soleen.com>,
<rppt@kernel.org>, <pratyush@kernel.org>, <skhawaja@google.com>,
<praan@google.com>, <baolu.lu@linux.intel.com>,
<dwmw2@infradead.org>, <kevin.tian@intel.com>,
<dmatlack@google.com>, <vipinsh@google.com>,
<kexec@lists.infradead.org>, <linux-kernel@vger.kernel.org>
Subject: [RFC PATCH 3/7] iommu/kho/abi: add AMD IOMMU live-update serialisation structs
Date: Mon, 5 Oct 2026 06:40:13 +0000 [thread overview]
Message-ID: <20261005064018.1558-4-Ankit.Soni@amd.com> (raw)
In-Reply-To: <20261005064018.1558-1-Ankit.Soni@amd.com>
Describe the AMD IOMMU state that has to cross a live-update kexec: the
device table of a PCI segment, and the domain ID, page-table mode and
GCR3 tree of a preserved device.
Both structs fit inside the existing unions, so the layout and the
version are unchanged. Assert that, since growing either arm past the
Intel one would move the array stride.
Signed-off-by: Ankit Soni <Ankit.Soni@amd.com>
---
include/linux/kho/abi/iommu.h | 70 +++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/include/linux/kho/abi/iommu.h b/include/linux/kho/abi/iommu.h
index 308cd83fd3e3..5cbc8b3589ed 100644
--- a/include/linux/kho/abi/iommu.h
+++ b/include/linux/kho/abi/iommu.h
@@ -8,6 +8,7 @@
#ifndef _LINUX_KHO_ABI_IOMMU_H
#define _LINUX_KHO_ABI_IOMMU_H
+#include <linux/bug.h>
#include <linux/mutex_types.h>
#include <linux/compiler.h>
#include <linux/types.h>
@@ -75,6 +76,7 @@
/**
* enum iommu_type_ser - Type of the IOMMU being preserved
* @IOMMU_INVALID: Invalid type of IOMMU
+ * @IOMMU_AMD: AMD-Vi, whose per-instance state is struct iommu_amd_ser
*
* IOMMU type is stored in the IOMMU HW state to differentiate between various
* IOMMU HWs.
@@ -82,6 +84,7 @@
enum iommu_type_ser {
IOMMU_INVALID,
IOMMU_INTEL,
+ IOMMU_AMD,
};
#define IOMMU_SER_FLAG_DELETED (1 << 0)
@@ -142,6 +145,29 @@ struct iommu_device_intel_ser {
u64 max_pasid;
} __packed;
+/*
+ * Page-table mode of the domain a preserved AMD device was attached to. These
+ * are wire values with their own numbering rather than the kernel's
+ * enum protection_domain_mode, so reordering that enum cannot silently change
+ * the handoff format.
+ */
+#define IOMMU_AMD_SER_PD_MODE_NONE 0
+#define IOMMU_AMD_SER_PD_MODE_V1 1
+#define IOMMU_AMD_SER_PD_MODE_V2 2
+
+/**
+ * struct iommu_device_amd_ser - AMD specific state of serialized device
+ * @gcr3_tbl_phys: Physical address of the device's GCR3 table root, or 0 if
+ * the device has no PASID/GCR3 table.
+ * @gcr3_glx: Number of GCR3 table levels (0, 1, or 2; see amd_iommu_max_glx_val)
+ * @pd_mode: Page-table format of the domain, one of IOMMU_AMD_SER_PD_MODE_*
+ */
+struct iommu_device_amd_ser {
+ u64 gcr3_tbl_phys;
+ u32 gcr3_glx;
+ u32 pd_mode;
+} __packed;
+
/**
* struct iommu_device_ser - Serialized state of a device
* @hdr: Common object header
@@ -150,6 +176,8 @@ struct iommu_device_intel_ser {
* @dma_owner_token: Token to identify the DMA owner of this device
* @domain_iommu_ser: Domain and IOMMU mapping
* @intel: Intel specific serialization data
+ * @amd: AMD-Vi per-device state, valid when the owning IOMMU record is
+ * of type IOMMU_AMD
*/
struct iommu_device_ser {
struct iommu_hdr_ser hdr;
@@ -159,9 +187,18 @@ struct iommu_device_ser {
struct iommu_dev_map_ser domain_iommu_ser;
union {
struct iommu_device_intel_ser intel;
+ struct iommu_device_amd_ser amd;
};
} __packed;
+/*
+ * The Intel arm is the larger one and so sets the size of the union, and with
+ * it the stride of the device array. Growing either arm changes that stride and
+ * needs a version bump.
+ */
+static_assert(sizeof(struct iommu_device_amd_ser) == 16);
+static_assert(sizeof(struct iommu_device_intel_ser) == 24);
+
/* There are maximum 256 buses, so maximum 512 context tables */
#define VTD_PRESERVED_BITMAP_LONGS DIV_ROUND_UP(512, BITS_PER_LONG_LONG)
@@ -181,12 +218,36 @@ struct iommu_intel_ser {
u64 context_tables_bitmap[VTD_PRESERVED_BITMAP_LONGS];
};
+/**
+ * struct iommu_amd_ser - Serialized state of an AMD IOMMU instance
+ * @restored: Whether IOMMU state is restored. Guards against double-restore.
+ * @mmio_phys: Physical address of the IOMMU MMIO register base.
+ * @dev_table_phys: Physical address of this IOMMU's PCI-segment device
+ * table (struct amd_iommu_pci_seg.dev_table).
+ * @dev_table_size: Size of the device table, in bytes.
+ * @pci_seg_id: PCI segment ID that owns the device table.
+ * @efr: Extended Feature Register bits (struct amd_iommu.features).
+ * Compared on restore; a mismatch is fatal.
+ * @efr2: Extended Feature Register 2 bits (struct amd_iommu.features2).
+ */
+struct iommu_amd_ser {
+ u8 restored;
+ u8 padding[7];
+ u64 mmio_phys;
+ u64 dev_table_phys;
+ u32 dev_table_size;
+ u32 pci_seg_id;
+ u64 efr;
+ u64 efr2;
+} __packed;
+
/**
* struct iommu_hw_ser - Serialized state of an IOMMU instance
* @hdr: Common object header
* @token: Unique token for the IOMMU
* @type: IOMMU type serialized state belongs to
* @intel: Intel specific serialization data
+ * @amd: AMD specific serialization data
*/
struct iommu_hw_ser {
struct iommu_hdr_ser hdr;
@@ -194,9 +255,18 @@ struct iommu_hw_ser {
u64 type;
union {
struct iommu_intel_ser intel;
+ struct iommu_amd_ser amd;
};
} __packed;
+/*
+ * The Intel arm is the larger one and so sets the size of the union, and with
+ * it the stride of the IOMMU array. Growing either arm changes that stride and
+ * needs a version bump.
+ */
+static_assert(sizeof(struct iommu_amd_ser) == 48);
+static_assert(sizeof(struct iommu_intel_ser) == 88);
+
/**
* struct iommu_array_hdr_ser - Header for an array of serialized objects
* @next_array_phys: Physical address of the next array of objects
--
2.43.0
next prev parent reply other threads:[~2026-10-05 6:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 6:40 [RFC PATCH 0/7] iommu/amd: Implement live update state preservation Ankit Soni
2026-10-05 6:40 ` [RFC PATCH 1/7] iommu/amd: defer device attach only on a kdump boot Ankit Soni
2026-10-05 6:40 ` [RFC PATCH 2/7] liveupdate: parse the incoming handover tree before late_time_init() Ankit Soni
2026-10-05 6:40 ` Ankit Soni [this message]
2026-10-05 6:40 ` [RFC PATCH 4/7] iommu/amd: preserve IOMMU and device state for live update Ankit Soni
2026-10-05 6:40 ` [RFC PATCH 5/7] iommu/amd: clear unpreserved DTEs and quiesce logs at live-update shutdown Ankit Soni
2026-10-05 6:40 ` [RFC PATCH 6/7] iommu/amd: restore preserved state on a live-update boot Ankit Soni
2026-10-05 6:40 ` [RFC PATCH 7/7] iommu/amd: reattach preserved devices to their restored domains Ankit Soni
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=20261005064018.1558-4-Ankit.Soni@amd.com \
--to=ankit.soni@amd.com \
--cc=alejandro.j.jimenez@oracle.com \
--cc=baolu.lu@linux.intel.com \
--cc=dmatlack@google.com \
--cc=dwmw2@infradead.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joao.m.martins@oracle.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pasha.tatashin@soleen.com \
--cc=praan@google.com \
--cc=pratyush@kernel.org \
--cc=robin.murphy@arm.com \
--cc=rppt@kernel.org \
--cc=skhawaja@google.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=vasant.hegde@amd.com \
--cc=vipinsh@google.com \
--cc=will@kernel.org \
/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
all inboxes | Powered by JetHome®