[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251202230303.1017519-26-skhawaja@google.com>
Date: Tue, 2 Dec 2025 23:02:55 +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 25/32] iommu: Add helper APIs to fetch preserved device state
Add two APIs to fetch state of the preserved devices. An API to iterate
through state of all preserved devices and another API to fetch the
state of a single preserved device. Note that these APIs only fetch the
preserved state from the previous kernel.
Signed-off-by: Samiullah Khawaja <skhawaja@...gle.com>
---
drivers/iommu/liveupdate.c | 68 ++++++++++++++++++++++++++++++++++++++
include/linux/iommu-lu.h | 2 ++
2 files changed, 70 insertions(+)
diff --git a/drivers/iommu/liveupdate.c b/drivers/iommu/liveupdate.c
index e7ecf2e9aa4e..1ca97612c501 100644
--- a/drivers/iommu/liveupdate.c
+++ b/drivers/iommu/liveupdate.c
@@ -175,6 +175,74 @@ int iommu_liveupdate_unregister_flb(struct liveupdate_file_handler *handler)
}
EXPORT_SYMBOL(iommu_liveupdate_unregister_flb);
+int iommu_for_each_preserved_device(int (*fn)(struct device_ser *ser, void *arg), void *arg)
+{
+ struct iommu_lu_flb_obj *obj;
+ struct devices_ser *devices;
+ int ret, i, idx;
+
+ ret = liveupdate_flb_get_incoming(&iommu_flb, (void **)&obj);
+ if (ret)
+ return -ENOENT;
+
+ devices = __va(obj->ser->devices_phys);
+ for (i = 0, idx = 0; i < obj->ser->nr_devices; ++i, ++idx) {
+ if (idx >= MAX_DEVICE_SERS) {
+ devices = __va(devices->objs.next_objs);
+ idx = 0;
+ }
+
+ if (devices->devices[idx].obj.deleted)
+ continue;
+
+ ret = fn(&devices->devices[idx], arg);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(iommu_for_each_preserved_device);
+
+static inline bool device_ser_match(struct device_ser *match,
+ struct pci_dev *pdev)
+{
+ return match->devid == pci_dev_id(pdev) && match->pci_domain == pci_domain_nr(pdev->bus);
+}
+
+struct device_ser *iommu_get_device_preserved_data(struct device *dev)
+{
+ struct iommu_lu_flb_obj *obj;
+ struct devices_ser *devices;
+ int ret, i, idx;
+
+ if (!dev_is_pci(dev))
+ return NULL;
+
+ ret = liveupdate_flb_get_incoming(&iommu_flb, (void **)&obj);
+ if (ret)
+ return NULL;
+
+ devices = __va(obj->ser->devices_phys);
+ for (i = 0, idx = 0; i < obj->ser->nr_devices; ++i, ++idx) {
+ if (idx >= MAX_DEVICE_SERS) {
+ devices = __va(devices->objs.next_objs);
+ idx = 0;
+ }
+
+ if (devices->devices[idx].obj.deleted)
+ continue;
+
+ if (device_ser_match(&devices->devices[idx], to_pci_dev(dev))) {
+ devices->devices[idx].obj.incoming = true;
+ return &devices->devices[idx];
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(iommu_get_device_preserved_data);
+
struct iommu_ser *iommu_get_preserved_data(u64 token, enum iommu_lu_type type)
{
struct iommu_lu_flb_obj *obj;
diff --git a/include/linux/iommu-lu.h b/include/linux/iommu-lu.h
index ffce7043e997..d0226ec19b2f 100644
--- a/include/linux/iommu-lu.h
+++ b/include/linux/iommu-lu.h
@@ -78,6 +78,8 @@ static inline void *iommu_domain_restored_state(struct iommu_domain *domain)
}
#endif
+int iommu_for_each_preserved_device(int (*fn)(struct device_ser *ser, void *arg), void *arg);
+struct device_ser *iommu_get_device_preserved_data(struct device *dev);
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);
--
2.52.0.158.g65b55ccf14-goog
Powered by blists - more mailing lists