To support serialising persistent iommufd objects to KHO, and to be able to restore the persisted data it is necessary to have a serialise hook on the KHO active path as well as a deserialise hook on module init. This commit adds those hooks and the new serialise.c file which will hold the logic here; for now it's just empty functions. --- drivers/iommu/iommufd/Makefile | 1 + drivers/iommu/iommufd/iommufd_private.h | 22 +++++++++++++++++++++ drivers/iommu/iommufd/main.c | 24 ++++++++++++++++++++++- drivers/iommu/iommufd/serialise.c | 26 +++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 drivers/iommu/iommufd/serialise.c diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile index cf4605962bea..80bc775c170d 100644 --- a/drivers/iommu/iommufd/Makefile +++ b/drivers/iommu/iommufd/Makefile @@ -13,3 +13,4 @@ iommufd-$(CONFIG_IOMMUFD_TEST) += selftest.o obj-$(CONFIG_IOMMUFD) += iommufd.o obj-$(CONFIG_IOMMUFD_DRIVER) += iova_bitmap.o +obj-$(CONFIG_KEXEC_KHO) += serialise.o diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index b23f7766066c..a26728646a22 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -497,6 +497,28 @@ static inline void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt, iommu_detach_group(hwpt->domain, idev->igroup->group); } +/* + * Serialise is invoked as a callback by KHO when changing KHO active state, + * it stores current iommufd state into KHO's persistent store. + * Deserialise is run by the iommufd module when loaded to re-hydrate state + * carried across from the previous kernel. + */ +#ifdef CONFIG_KEXEC_KHO +int iommufd_serialise_kho(struct notifier_block *self, unsigned long cmd, + void *fdt); +int __init iommufd_deserialise_kho(void); +#else +int iommufd_serialise_kho(struct notifier_block *self, unsigned long cmd, + void *fdt) +{ + return 0; +} +int __init iommufd_deserialise_kho(void) +{ + return 0; +} +#endif + static inline int iommufd_hwpt_replace_device(struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt, struct iommufd_hw_pagetable *old) diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 6708ad629b1e..fa4f0fe336ad 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -10,6 +10,7 @@ #include <linux/file.h> #include <linux/fs.h> +#include <linux/kexec.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/miscdevice.h> @@ -590,6 +591,10 @@ static struct miscdevice vfio_misc_dev = { .mode = 0666, }; +static struct notifier_block serialise_kho_nb = { + .notifier_call = iommufd_serialise_kho, +}; + static int __init iommufd_init(void) { int ret; @@ -603,11 +608,26 @@ static int __init iommufd_init(void) if (ret) goto err_misc; } + + if (IS_ENABLED(CONFIG_KEXEC_KHO)) { + ret = register_kho_notifier(&serialise_kho_nb); + if (ret) + goto err_vfio_misc; + } + + ret = iommufd_deserialise_kho(); + if (ret) + goto err_kho; + ret = iommufd_test_init(); + if (ret) - goto err_vfio_misc; + goto err_kho; return 0; +err_kho: + if (IS_ENABLED(CONFIG_KEXEC_KHO)) + unregister_kho_notifier(&serialise_kho_nb); err_vfio_misc: if (IS_ENABLED(CONFIG_IOMMUFD_VFIO_CONTAINER)) misc_deregister(&vfio_misc_dev); @@ -621,6 +641,8 @@ static void __exit iommufd_exit(void) iommufd_test_exit(); if (IS_ENABLED(CONFIG_IOMMUFD_VFIO_CONTAINER)) misc_deregister(&vfio_misc_dev); + if (IS_ENABLED(CONFIG_FTRACE_KHO)) + unregister_kho_notifier(&serialise_kho_nb); misc_deregister(&iommu_misc_dev); } diff --git a/drivers/iommu/iommufd/serialise.c b/drivers/iommu/iommufd/serialise.c new file mode 100644 index 000000000000..6e8bcc384771 --- /dev/null +++ b/drivers/iommu/iommufd/serialise.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <linux/kexec.h> +#include "iommufd_private.h" + +int iommufd_serialise_kho(struct notifier_block *self, unsigned long cmd, + void *fdt) +{ + pr_info("would serialise here\n"); + 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; + default: + return NOTIFY_BAD; + } +} + +int __init iommufd_deserialise_kho(void) +{ + pr_info("would deserialise here\n"); + return 0; +} -- 2.34.1