From: Vipin Sharma vipinsh@google.com
Register a live update file handler for vfio-pci device files. Add stub implementations of all required callbacks so that registration does not fail (i.e. to avoid breaking git-bisect).
This file handler will be extended in subsequent commits to enable a device bound to vfio-pci to run without interruption while the host is going through a kexec Live Update.
Signed-off-by: Vipin Sharma vipinsh@google.com Co-Developed-by: David Matlack dmatlack@google.com Signed-off-by: David Matlack dmatlack@google.com --- MAINTAINERS | 1 + drivers/vfio/pci/Makefile | 1 + drivers/vfio/pci/vfio_pci.c | 9 +++- drivers/vfio/pci/vfio_pci_liveupdate.c | 69 ++++++++++++++++++++++++++ drivers/vfio/pci/vfio_pci_priv.h | 14 ++++++ include/linux/kho/abi/vfio_pci.h | 28 +++++++++++ 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 drivers/vfio/pci/vfio_pci_liveupdate.c create mode 100644 include/linux/kho/abi/vfio_pci.h
diff --git a/MAINTAINERS b/MAINTAINERS index 2722f98d0ed7..ff50977277c4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -26933,6 +26933,7 @@ F: Documentation/ABI/testing/debugfs-vfio F: Documentation/ABI/testing/sysfs-devices-vfio-dev F: Documentation/driver-api/vfio.rst F: drivers/vfio/ +F: include/linux/kho/abi/vfio_pci.h F: include/linux/vfio.h F: include/linux/vfio_pci_core.h F: include/uapi/linux/vfio.h diff --git a/drivers/vfio/pci/Makefile b/drivers/vfio/pci/Makefile index cf00c0a7e55c..929df22c079b 100644 --- a/drivers/vfio/pci/Makefile +++ b/drivers/vfio/pci/Makefile @@ -2,6 +2,7 @@
vfio-pci-core-y := vfio_pci_core.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o vfio-pci-core-$(CONFIG_VFIO_PCI_ZDEV_KVM) += vfio_pci_zdev.o +vfio-pci-core-$(CONFIG_LIVEUPDATE) += vfio_pci_liveupdate.o obj-$(CONFIG_VFIO_PCI_CORE) += vfio-pci-core.o
vfio-pci-y := vfio_pci.o diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index ac10f14417f2..c2fe34a830d8 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -252,6 +252,10 @@ static int __init vfio_pci_init(void) int ret; bool is_disable_vga = true;
+ ret = vfio_pci_liveupdate_init(); + if (ret) + return ret; + #ifdef CONFIG_VFIO_PCI_VGA is_disable_vga = disable_vga; #endif @@ -260,8 +264,10 @@ static int __init vfio_pci_init(void)
/* Register and scan for devices */ ret = pci_register_driver(&vfio_pci_driver); - if (ret) + if (ret) { + vfio_pci_liveupdate_cleanup(); return ret; + }
vfio_pci_fill_ids();
@@ -275,6 +281,7 @@ module_init(vfio_pci_init); static void __exit vfio_pci_cleanup(void) { pci_unregister_driver(&vfio_pci_driver); + vfio_pci_liveupdate_cleanup(); } module_exit(vfio_pci_cleanup);
diff --git a/drivers/vfio/pci/vfio_pci_liveupdate.c b/drivers/vfio/pci/vfio_pci_liveupdate.c new file mode 100644 index 000000000000..b84e63c0357b --- /dev/null +++ b/drivers/vfio/pci/vfio_pci_liveupdate.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright (c) 2025, Google LLC. + * Vipin Sharma vipinsh@google.com + * David Matlack dmatlack@google.com + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/kho/abi/vfio_pci.h> +#include <linux/liveupdate.h> +#include <linux/errno.h> + +#include "vfio_pci_priv.h" + +static bool vfio_pci_liveupdate_can_preserve(struct liveupdate_file_handler *handler, + struct file *file) +{ + return false; +} + +static int vfio_pci_liveupdate_preserve(struct liveupdate_file_op_args *args) +{ + return -EOPNOTSUPP; +} + +static void vfio_pci_liveupdate_unpreserve(struct liveupdate_file_op_args *args) +{ +} + +static int vfio_pci_liveupdate_retrieve(struct liveupdate_file_op_args *args) +{ + return -EOPNOTSUPP; +} + +static void vfio_pci_liveupdate_finish(struct liveupdate_file_op_args *args) +{ +} + +static const struct liveupdate_file_ops vfio_pci_liveupdate_file_ops = { + .can_preserve = vfio_pci_liveupdate_can_preserve, + .preserve = vfio_pci_liveupdate_preserve, + .unpreserve = vfio_pci_liveupdate_unpreserve, + .retrieve = vfio_pci_liveupdate_retrieve, + .finish = vfio_pci_liveupdate_finish, + .owner = THIS_MODULE, +}; + +static struct liveupdate_file_handler vfio_pci_liveupdate_fh = { + .ops = &vfio_pci_liveupdate_file_ops, + .compatible = VFIO_PCI_LUO_FH_COMPATIBLE, +}; + +int __init vfio_pci_liveupdate_init(void) +{ + if (!liveupdate_enabled()) + return 0; + + return liveupdate_register_file_handler(&vfio_pci_liveupdate_fh); +} + +void vfio_pci_liveupdate_cleanup(void) +{ + if (!liveupdate_enabled()) + return; + + liveupdate_unregister_file_handler(&vfio_pci_liveupdate_fh); +} diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h index a9972eacb293..b9f7c4e2b4df 100644 --- a/drivers/vfio/pci/vfio_pci_priv.h +++ b/drivers/vfio/pci/vfio_pci_priv.h @@ -107,4 +107,18 @@ static inline bool vfio_pci_is_vga(struct pci_dev *pdev) return (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; }
+#ifdef CONFIG_LIVEUPDATE +int __init vfio_pci_liveupdate_init(void); +void vfio_pci_liveupdate_cleanup(void); +#else +static inline int vfio_pci_liveupdate_init(void) +{ + return 0; +} + +static inline void vfio_pci_liveupdate_cleanup(void) +{ +} +#endif /* CONFIG_LIVEUPDATE */ + #endif diff --git a/include/linux/kho/abi/vfio_pci.h b/include/linux/kho/abi/vfio_pci.h new file mode 100644 index 000000000000..37a845eed972 --- /dev/null +++ b/include/linux/kho/abi/vfio_pci.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (c) 2025, Google LLC. + * Vipin Sharma vipinsh@google.com + * David Matlack dmatlack@google.com + */ + +#ifndef _LINUX_LIVEUPDATE_ABI_VFIO_PCI_H +#define _LINUX_LIVEUPDATE_ABI_VFIO_PCI_H + +/** + * DOC: VFIO PCI Live Update ABI + * + * This header defines the ABI for preserving the state of a VFIO PCI device + * files across a kexec reboot using LUO. + * + * Device metadata is serialized into memory which is then handed to the next + * kernel via KHO. + * + * This interface is a contract. Any modification to any of the serialization + * structs defined here constitutes a breaking change. Such changes require + * incrementing the version number in the VFIO_PCI_LUO_FH_COMPATIBLE string. + */ + +#define VFIO_PCI_LUO_FH_COMPATIBLE "vfio-pci-v1" + +#endif /* _LINUX_LIVEUPDATE_ABI_VFIO_PCI_H */