[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240916113102.710522-6-jgowans@amazon.com>
Date: Mon, 16 Sep 2024 13:30:54 +0200
From: James Gowans <jgowans@...zon.com>
To: <linux-kernel@...r.kernel.org>
CC: Jason Gunthorpe <jgg@...pe.ca>, Kevin Tian <kevin.tian@...el.com>, "Joerg
Roedel" <joro@...tes.org>, Krzysztof WilczyĆski
<kw@...ux.com>, Will Deacon <will@...nel.org>, Robin Murphy
<robin.murphy@....com>, Mike Rapoport <rppt@...nel.org>, "Madhavan T.
Venkataraman" <madvenka@...ux.microsoft.com>, <iommu@...ts.linux.dev>, "Sean
Christopherson" <seanjc@...gle.com>, Paolo Bonzini <pbonzini@...hat.com>,
<kvm@...r.kernel.org>, David Woodhouse <dwmw2@...radead.org>, Lu Baolu
<baolu.lu@...ux.intel.com>, Alexander Graf <graf@...zon.de>,
<anthony.yznaga@...cle.com>, <steven.sistare@...cle.com>,
<nh-open-source@...zon.com>, "Saenz Julienne, Nicolas" <nsaenz@...zon.es>
Subject: [RFC PATCH 05/13] iommufd: Serialise persisted iommufds and ioas
Now actually implementing the serialise callback for iommufd.
On KHO activate, iterate through all persisted domains and write their
metadata to the device tree format. For now just a few fields are
serialised to demonstrate the concept. To actually make this useful a
lot more field and related objects will need to be serialised too.
---
drivers/iommu/iommufd/iommufd_private.h | 2 +
drivers/iommu/iommufd/main.c | 2 +-
drivers/iommu/iommufd/serialise.c | 81 ++++++++++++++++++++++++-
3 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index a26728646a22..ad8d180269bd 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -18,6 +18,8 @@ struct iommu_group;
struct iommu_option;
struct iommufd_device;
+extern struct xarray persistent_iommufds;
+
struct iommufd_ctx {
struct file *file;
struct xarray objects;
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index fa4f0fe336ad..21a7e1ad40d1 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -30,7 +30,7 @@ struct iommufd_object_ops {
static const struct iommufd_object_ops iommufd_object_ops[];
static struct miscdevice vfio_misc_dev;
-static DEFINE_XARRAY_ALLOC(persistent_iommufds);
+DEFINE_XARRAY_ALLOC(persistent_iommufds);
struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
size_t size,
diff --git a/drivers/iommu/iommufd/serialise.c b/drivers/iommu/iommufd/serialise.c
index 6e8bcc384771..6b4c306dce40 100644
--- a/drivers/iommu/iommufd/serialise.c
+++ b/drivers/iommu/iommufd/serialise.c
@@ -1,19 +1,94 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kexec.h>
+#include <linux/libfdt.h>
#include "iommufd_private.h"
+#include "io_pagetable.h"
+
+/**
+ * Serialised format:
+ * /iommufd
+ * compatible = "iommufd-v0",
+ * iommufds = [
+ * persistent_id = {
+ * account_mode = u8
+ * ioases = [
+ * {
+ * areas = [
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ */
+static int serialise_iommufd(void *fdt, struct iommufd_ctx *ictx)
+{
+ int err = 0;
+ char name[24];
+ struct iommufd_object *obj;
+ unsigned long obj_idx;
+
+ snprintf(name, sizeof(name), "%lu", ictx->persistent_id);
+ err |= fdt_begin_node(fdt, name);
+ err |= fdt_begin_node(fdt, "ioases");
+ xa_for_each(&ictx->objects, obj_idx, obj) {
+ struct iommufd_ioas *ioas;
+ struct iopt_area *area;
+ int area_idx = 0;
+
+ if (obj->type != IOMMUFD_OBJ_IOAS)
+ continue;
+
+ ioas = (struct iommufd_ioas *) obj;
+ snprintf(name, sizeof(name), "%lu", obj_idx);
+ err |= fdt_begin_node(fdt, name);
+
+ for (area = iopt_area_iter_first(&ioas->iopt, 0, ULONG_MAX); area;
+ area = iopt_area_iter_next(area, 0, ULONG_MAX)) {
+ unsigned long iova_start, iova_len;
+
+ snprintf(name, sizeof(name), "%i", area_idx);
+ err |= fdt_begin_node(fdt, name);
+ iova_start = iopt_area_iova(area);
+ iova_len = iopt_area_length(area);
+ err |= fdt_property(fdt, "iova-start",
+ &iova_start, sizeof(iova_start));
+ err |= fdt_property(fdt, "iova-len",
+ &iova_len, sizeof(iova_len));
+ err |= fdt_property(fdt, "iommu-prot",
+ &area->iommu_prot, sizeof(area->iommu_prot));
+ err |= fdt_end_node(fdt); /* area_idx */
+ ++area_idx;
+ }
+ err |= fdt_end_node(fdt); /* ioas obj_idx */
+ }
+ err |= fdt_end_node(fdt); /* ioases*/
+ err |= fdt_end_node(fdt); /* ictx->persistent_id */
+ return 0;
+}
int iommufd_serialise_kho(struct notifier_block *self, unsigned long cmd,
void *fdt)
{
- pr_info("would serialise here\n");
+ static const char compatible[] = "iommufd-v0";
+ struct iommufd_ctx *ictx;
+ unsigned long xa_idx;
+ int err = 0;
+
switch (cmd) {
case KEXEC_KHO_ABORT:
/* Would do serialise rollback here. */
return NOTIFY_DONE;
case KEXEC_KHO_DUMP:
- /* Would do serialise here. */
- return NOTIFY_DONE;
+ err |= fdt_begin_node(fdt, "iommufd");
+ fdt_property(fdt, "compatible", compatible, sizeof(compatible));
+ err |= fdt_begin_node(fdt, "iommufds");
+ xa_for_each(&persistent_iommufds, xa_idx, ictx) {
+ err |= serialise_iommufd(fdt, ictx);
+ }
+ err |= fdt_end_node(fdt); /* iommufds */
+ err |= fdt_end_node(fdt); /* iommufd */
+ return err? NOTIFY_BAD : NOTIFY_DONE;
default:
return NOTIFY_BAD;
}
--
2.34.1
Powered by blists - more mailing lists