[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251202230303.1017519-14-skhawaja@google.com>
Date: Tue, 2 Dec 2025 23:02:43 +0000
From: Samiullah Khawaja <skhawaja@...gle.com>
To: David Woodhouse <dwmw2@...radead.org>, Lu Baolu <baolu.lu@...ux.intel.com>,
Joerg Roedel <joro@...tes.org>, Will Deacon <will@...nel.org>,
Pasha Tatashin <pasha.tatashin@...een.com>, Jason Gunthorpe <jgg@...pe.ca>, iommu@...ts.linux.dev
Cc: Samiullah Khawaja <skhawaja@...gle.com>, Robin Murphy <robin.murphy@....com>,
Pratyush Yadav <pratyush@...nel.org>, Kevin Tian <kevin.tian@...el.com>,
Alex Williamson <alex@...zbot.org>, linux-kernel@...r.kernel.org,
Saeed Mahameed <saeedm@...dia.com>, Adithya Jayachandran <ajayachandra@...dia.com>,
Parav Pandit <parav@...dia.com>, Leon Romanovsky <leonro@...dia.com>, William Tu <witu@...dia.com>,
Vipin Sharma <vipinsh@...gle.com>, dmatlack@...gle.com, YiFei Zhu <zhuyifei@...gle.com>,
Chris Li <chrisl@...nel.org>, praan@...gle.com
Subject: [RFC PATCH v2 13/32] iommu: Add APIs to preserve/unpreserve iommu domains
These APIs will be used by iommufd LU handler to preserve and unpreserve
a domain for live update.
Signed-off-by: Samiullah Khawaja <skhawaja@...gle.com>
---
drivers/iommu/liveupdate.c | 82 ++++++++++++++++++++++++++++++++++++++
include/linux/iommu-lu.h | 2 +
include/linux/iommu.h | 4 ++
3 files changed, 88 insertions(+)
diff --git a/drivers/iommu/liveupdate.c b/drivers/iommu/liveupdate.c
index 21ce7be9b87e..25a943e5e1e3 100644
--- a/drivers/iommu/liveupdate.c
+++ b/drivers/iommu/liveupdate.c
@@ -127,3 +127,85 @@ int iommu_liveupdate_unregister_flb(struct liveupdate_file_handler *handler)
return liveupdate_unregister_flb(handler, &iommu_flb);
}
EXPORT_SYMBOL(iommu_liveupdate_unregister_flb);
+
+static int reserve_obj_ser(struct iommu_objs_ser **objs_ptr, u64 max_objs)
+{
+ struct iommu_objs_ser *next_objs, *objs = *objs_ptr;
+ int idx;
+
+ if (objs->nr_objs == max_objs) {
+ next_objs = kho_alloc_preserve(PAGE_SIZE);
+ if (!next_objs)
+ return -ENOMEM;
+
+ objs->next_objs = virt_to_phys(next_objs);
+ objs = next_objs;
+ *objs_ptr = objs;
+ objs->nr_objs = 0;
+ }
+
+ idx = objs->nr_objs++;
+ return idx;
+}
+
+int iommu_domain_preserve(struct iommu_domain *domain, struct iommu_domain_ser **ser)
+{
+ struct iommu_domain_ser *domain_ser;
+ struct iommu_lu_flb_obj *flb_obj;
+ int idx, ret;
+
+ if (!domain->ops->preserve)
+ return -EOPNOTSUPP;
+
+ ret = liveupdate_flb_get_outgoing(&iommu_flb, (void **)&flb_obj);
+ if (ret)
+ return ret;
+
+ guard(mutex)(&flb_obj->lock);
+ idx = reserve_obj_ser((struct iommu_objs_ser **)&flb_obj->iommu_domains,
+ MAX_IOMMU_DOMAIN_SERS);
+ if (idx < 0)
+ return idx;
+
+ domain_ser = &flb_obj->iommu_domains->iommu_domains[idx];
+ idx = flb_obj->ser->nr_domains++;
+ domain_ser->obj.idx = idx;
+ domain_ser->obj.ref_count = 1;
+
+ ret = domain->ops->preserve(domain, domain_ser);
+ if (ret) {
+ domain_ser->obj.deleted = true;
+ return ret;
+ }
+
+ domain->preserved_state = domain_ser;
+ *ser = domain_ser;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_domain_preserve);
+
+int iommu_domain_unpreserve(struct iommu_domain *domain)
+{
+ struct iommu_domain_ser *domain_ser;
+ struct iommu_lu_flb_obj *flb_obj;
+ int ret;
+
+ if (!domain->ops->unpreserve)
+ return -EOPNOTSUPP;
+
+ ret = liveupdate_flb_get_outgoing(&iommu_flb, (void **)&flb_obj);
+ if (ret)
+ return ret;
+
+ guard(mutex)(&flb_obj->lock);
+ domain_ser = domain->preserved_state;
+ if (domain_ser->attach_count)
+ ret = -EBUSY;
+
+ domain->ops->unpreserve(domain, domain_ser);
+ domain_ser->obj.deleted = true;
+ domain->preserved_state = NULL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_domain_unpreserve);
diff --git a/include/linux/iommu-lu.h b/include/linux/iommu-lu.h
index 59095d2f1bb2..2c8e5ac746ad 100644
--- a/include/linux/iommu-lu.h
+++ b/include/linux/iommu-lu.h
@@ -11,6 +11,8 @@
#include <linux/liveupdate.h>
#include <linux/kho/abi/iommu.h>
+int iommu_domain_preserve(struct iommu_domain *domain, struct iommu_domain_ser **ser);
+int iommu_domain_unpreserve(struct iommu_domain *domain);
int iommu_liveupdate_register_flb(struct liveupdate_file_handler *handler);
int iommu_liveupdate_unregister_flb(struct liveupdate_file_handler *handler);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index f681d4d27d6e..17e1f3c29958 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -249,6 +249,10 @@ struct iommu_domain {
struct list_head next;
};
};
+
+#ifdef CONFIG_LIVEUPDATE
+ struct iommu_domain_ser *preserved_state;
+#endif
};
static inline bool iommu_is_dma_domain(struct iommu_domain *domain)
--
2.52.0.158.g65b55ccf14-goog
Powered by blists - more mailing lists