[RFC PATCH v2 23/32] iommu: Add an API get the preserved state of an IOMMU

From: Samiullah Khawaja
Date: Tue Dec 02 2025 - 18:08:49 EST


After liveupdate kexec during boot, the state of the preserved IOMMU
needs to be restored. Since the state needs to be restored by the IOMMU
drivers during initialization/registration with the IOMMU core, add an
API that can be used by the IOMMU drivers to fetch the preserved state.

Signed-off-by: Samiullah Khawaja <skhawaja@xxxxxxxxxx>
---
drivers/iommu/liveupdate.c | 29 +++++++++++++++++++++++++++++
include/linux/iommu-lu.h | 1 +
2 files changed, 30 insertions(+)

diff --git a/drivers/iommu/liveupdate.c b/drivers/iommu/liveupdate.c
index 0dfa03673178..e7ecf2e9aa4e 100644
--- a/drivers/iommu/liveupdate.c
+++ b/drivers/iommu/liveupdate.c
@@ -175,6 +175,35 @@ int iommu_liveupdate_unregister_flb(struct liveupdate_file_handler *handler)
}
EXPORT_SYMBOL(iommu_liveupdate_unregister_flb);

+struct iommu_ser *iommu_get_preserved_data(u64 token, enum iommu_lu_type type)
+{
+ struct iommu_lu_flb_obj *obj;
+ struct iommus_ser *iommus;
+ int ret, i, idx;
+
+ ret = liveupdate_flb_get_incoming(&iommu_flb, (void **)&obj);
+ if (ret)
+ return NULL;
+
+ iommus = __va(obj->ser->iommus_phys);
+ for (i = 0, idx = 0; i < obj->ser->nr_iommus; ++i, ++idx) {
+ if (idx >= MAX_IOMMU_SERS) {
+ iommus = __va(iommus->objs.next_objs);
+ idx = 0;
+ }
+
+ if (iommus->iommus[idx].obj.deleted)
+ continue;
+
+ if (iommus->iommus[idx].token == token &&
+ iommus->iommus[idx].type == type)
+ return &iommus->iommus[idx];
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(iommu_get_preserved_data);
+
static int reserve_obj_ser(struct iommu_objs_ser **objs_ptr, u64 max_objs)
{
struct iommu_objs_ser *next_objs, *objs = *objs_ptr;
diff --git a/include/linux/iommu-lu.h b/include/linux/iommu-lu.h
index 08a659de8553..ffce7043e997 100644
--- a/include/linux/iommu-lu.h
+++ b/include/linux/iommu-lu.h
@@ -78,6 +78,7 @@ static inline void *iommu_domain_restored_state(struct iommu_domain *domain)
}
#endif

+struct iommu_ser *iommu_get_preserved_data(u64 token, enum iommu_lu_type type);
int iommu_domain_preserve(struct iommu_domain *domain, struct iommu_domain_ser **ser);
int iommu_domain_unpreserve(struct iommu_domain *domain);
int iommu_preserve_device(struct iommu_domain *domain, struct device *dev);
--
2.52.0.158.g65b55ccf14-goog