diff --git a/Documentation/ABI/testing/debugfs-vfio b/Documentation/ABI/testing/debugfs-vfio new file mode 100644 index 0000000000000000000000000000000000000000..90f7c262f591306bdb99295ab4e857ca0e0b537a --- /dev/null +++ b/Documentation/ABI/testing/debugfs-vfio @@ -0,0 +1,25 @@ +What: /sys/kernel/debug/vfio +Date: December 2023 +KernelVersion: 6.8 +Contact: Longfang Liu +Description: This debugfs file directory is used for debugging + of vfio devices, it's a common directory for all vfio devices. + Vfio core will create a device subdirectory under this + directory. + +What: /sys/kernel/debug/vfio//migration +Date: December 2023 +KernelVersion: 6.8 +Contact: Longfang Liu +Description: This debugfs file directory is used for debugging + of vfio devices that support live migration. + The debugfs of each vfio device that supports live migration + could be created under this directory. + +What: /sys/kernel/debug/vfio//migration/state +Date: December 2023 +KernelVersion: 6.8 +Contact: Longfang Liu +Description: Read the live migration status of the vfio device. + The contents of the state file reflects the migration state + relative to those defined in the vfio_device_mig_state enum diff --git a/MAINTAINERS b/MAINTAINERS index 2243c96227456a21e73f2f63361805cd3116ff80..7cb2846a6e2410336a03f9ad575268bfe0f45d7c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22888,6 +22888,7 @@ M: Alex Williamson L: kvm@vger.kernel.org S: Maintained T: git https://github.com/awilliam/linux-vfio.git +F: Documentation/ABI/testing/debugfs-vfio F: Documentation/ABI/testing/sysfs-devices-vfio-dev F: Documentation/driver-api/vfio.rst F: Documentation/driver-api/vfio_pci_liveupdate.rst diff --git a/anolis/configs/L1-RECOMMEND/arm64/CONFIG_VFIO_DEBUGFS b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_VFIO_DEBUGFS new file mode 100644 index 0000000000000000000000000000000000000000..1815bec0629348d93890224f998b8fa4200939c8 --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/arm64/CONFIG_VFIO_DEBUGFS @@ -0,0 +1 @@ +CONFIG_VFIO_DEBUGFS=y diff --git a/anolis/configs/L1-RECOMMEND/loongarch/CONFIG_VFIO_DEBUGFS b/anolis/configs/L1-RECOMMEND/loongarch/CONFIG_VFIO_DEBUGFS new file mode 100644 index 0000000000000000000000000000000000000000..eba9d074c6a3cd2ec01b701f3b3818f5ff20a82c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/loongarch/CONFIG_VFIO_DEBUGFS @@ -0,0 +1 @@ +# CONFIG_VFIO_DEBUGFS is not set diff --git a/anolis/configs/L1-RECOMMEND/riscv/CONFIG_VFIO_DEBUGFS b/anolis/configs/L1-RECOMMEND/riscv/CONFIG_VFIO_DEBUGFS new file mode 100644 index 0000000000000000000000000000000000000000..eba9d074c6a3cd2ec01b701f3b3818f5ff20a82c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/riscv/CONFIG_VFIO_DEBUGFS @@ -0,0 +1 @@ +# CONFIG_VFIO_DEBUGFS is not set diff --git a/anolis/configs/L1-RECOMMEND/sw_64-6b/CONFIG_VFIO_DEBUGFS b/anolis/configs/L1-RECOMMEND/sw_64-6b/CONFIG_VFIO_DEBUGFS new file mode 100644 index 0000000000000000000000000000000000000000..eba9d074c6a3cd2ec01b701f3b3818f5ff20a82c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/sw_64-6b/CONFIG_VFIO_DEBUGFS @@ -0,0 +1 @@ +# CONFIG_VFIO_DEBUGFS is not set diff --git a/anolis/configs/L1-RECOMMEND/sw_64-8a/CONFIG_VFIO_DEBUGFS b/anolis/configs/L1-RECOMMEND/sw_64-8a/CONFIG_VFIO_DEBUGFS new file mode 100644 index 0000000000000000000000000000000000000000..eba9d074c6a3cd2ec01b701f3b3818f5ff20a82c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/sw_64-8a/CONFIG_VFIO_DEBUGFS @@ -0,0 +1 @@ +# CONFIG_VFIO_DEBUGFS is not set diff --git a/anolis/configs/L1-RECOMMEND/x86/CONFIG_VFIO_DEBUGFS b/anolis/configs/L1-RECOMMEND/x86/CONFIG_VFIO_DEBUGFS new file mode 100644 index 0000000000000000000000000000000000000000..eba9d074c6a3cd2ec01b701f3b3818f5ff20a82c --- /dev/null +++ b/anolis/configs/L1-RECOMMEND/x86/CONFIG_VFIO_DEBUGFS @@ -0,0 +1 @@ +# CONFIG_VFIO_DEBUGFS is not set diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index b9b459d9b07331ef8ca83aa8f4e793aeddce2c57..d9984ee13c9330c3777a73d79232043f53ac3b2a 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -80,6 +80,16 @@ config VFIO_VIRQFD select EVENTFD default n +config VFIO_DEBUGFS + bool "Export VFIO internals in DebugFS" + depends on DEBUG_FS + help + Allows exposure of VFIO device internals. This option enables + the use of debugfs by VFIO drivers as required. The device can + cause the VFIO code create a top-level debug/vfio directory + during initialization, and then populate a subdirectory with + entries as required. + source "drivers/vfio/pci/Kconfig" source "drivers/vfio/platform/Kconfig" source "drivers/vfio/mdev/Kconfig" diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index 68c05705200fce8fc9824a8521bbe554e5c130f7..b2fc9fb499d8690cf7d75e32bdf9bbb02efdf9f7 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -7,6 +7,7 @@ vfio-$(CONFIG_VFIO_GROUP) += group.o vfio-$(CONFIG_IOMMUFD) += iommufd.o vfio-$(CONFIG_VFIO_CONTAINER) += container.o vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o +vfio-$(CONFIG_VFIO_DEBUGFS) += debugfs.o obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o diff --git a/drivers/vfio/debugfs.c b/drivers/vfio/debugfs.c new file mode 100644 index 0000000000000000000000000000000000000000..9f02ae15e084edbcdba466f56b82d86010222185 --- /dev/null +++ b/drivers/vfio/debugfs.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023, HiSilicon Ltd. + */ + +#include +#include +#include +#include +#include "vfio.h" + +static struct dentry *vfio_debugfs_root; + +static int vfio_device_state_read(struct seq_file *seq, void *data) +{ + struct device *vf_dev = seq->private; + struct vfio_device *vdev = container_of(vf_dev, struct vfio_device, device); + enum vfio_device_mig_state state; + int ret; + + BUILD_BUG_ON(VFIO_DEVICE_STATE_NR != + VFIO_DEVICE_STATE_PRE_COPY_P2P + 1); + + ret = vdev->mig_ops->migration_get_state(vdev, &state); + if (ret) + return -EINVAL; + + switch (state) { + case VFIO_DEVICE_STATE_ERROR: + seq_puts(seq, "ERROR\n"); + break; + case VFIO_DEVICE_STATE_STOP: + seq_puts(seq, "STOP\n"); + break; + case VFIO_DEVICE_STATE_RUNNING: + seq_puts(seq, "RUNNING\n"); + break; + case VFIO_DEVICE_STATE_STOP_COPY: + seq_puts(seq, "STOP_COPY\n"); + break; + case VFIO_DEVICE_STATE_RESUMING: + seq_puts(seq, "RESUMING\n"); + break; + case VFIO_DEVICE_STATE_RUNNING_P2P: + seq_puts(seq, "RUNNING_P2P\n"); + break; + case VFIO_DEVICE_STATE_PRE_COPY: + seq_puts(seq, "PRE_COPY\n"); + break; + case VFIO_DEVICE_STATE_PRE_COPY_P2P: + seq_puts(seq, "PRE_COPY_P2P\n"); + break; + default: + seq_puts(seq, "Invalid\n"); + } + + return 0; +} + +void vfio_device_debugfs_init(struct vfio_device *vdev) +{ + struct device *dev = &vdev->device; + + vdev->debug_root = debugfs_create_dir(dev_name(vdev->dev), vfio_debugfs_root); + + if (vdev->mig_ops) { + struct dentry *vfio_dev_migration = NULL; + + vfio_dev_migration = debugfs_create_dir("migration", vdev->debug_root); + debugfs_create_devm_seqfile(dev, "state", vfio_dev_migration, + vfio_device_state_read); + } +} + +void vfio_device_debugfs_exit(struct vfio_device *vdev) +{ + debugfs_remove_recursive(vdev->debug_root); +} + +void vfio_debugfs_create_root(void) +{ + vfio_debugfs_root = debugfs_create_dir("vfio", NULL); +} + +void vfio_debugfs_remove_root(void) +{ + debugfs_remove_recursive(vfio_debugfs_root); + vfio_debugfs_root = NULL; +} + diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h index 954b21e06f6a8fb996b9d166f0dea2cd369682f9..4d016547bcb85ea6fb95f0ae98cde9bba2b3cc9b 100644 --- a/drivers/vfio/vfio.h +++ b/drivers/vfio/vfio.h @@ -466,4 +466,18 @@ static inline bool vfio_liveupdate_incoming_is_preserved(struct vfio_device *dev } #endif /* CONFIG_PCI_LIVEUPDATE */ +#ifdef CONFIG_VFIO_DEBUGFS +void vfio_debugfs_create_root(void); +void vfio_debugfs_remove_root(void); + +void vfio_device_debugfs_init(struct vfio_device *vdev); +void vfio_device_debugfs_exit(struct vfio_device *vdev); +#else +static inline void vfio_debugfs_create_root(void) { } +static inline void vfio_debugfs_remove_root(void) { } + +static inline void vfio_device_debugfs_init(struct vfio_device *vdev) { } +static inline void vfio_device_debugfs_exit(struct vfio_device *vdev) { } +#endif /* CONFIG_VFIO_DEBUGFS */ + #endif diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 274f0d906c253458f65a0f1ef71d4f3a6f3b8030..a113dc47c08e839356ab6a92fec65d182014cae4 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -358,6 +358,7 @@ static int __vfio_register_dev(struct vfio_device *device, refcount_set(&device->refcount, 1); vfio_device_group_register(device); + vfio_device_debugfs_init(device); return 0; err_out: @@ -425,6 +426,7 @@ void vfio_unregister_group_dev(struct vfio_device *device) } } + vfio_device_debugfs_exit(device); /* Balances vfio_device_set_group in register path */ vfio_device_remove_group(device); } @@ -1727,6 +1729,7 @@ static int __init vfio_init(void) if (ret) goto err_alloc_dev_chrdev; + vfio_debugfs_create_root(); pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); return 0; @@ -1742,6 +1745,7 @@ static int __init vfio_init(void) static void __exit vfio_cleanup(void) { + vfio_debugfs_remove_root(); ida_destroy(&vfio.device_ida); vfio_cdev_cleanup(); class_destroy(vfio.device_class); diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 17a2968341f79e4044baa045cb677a497af193b9..c2d8cb2810746861a1f8ed8c6ecca48307966285 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -73,6 +73,13 @@ struct vfio_device { #ifdef CONFIG_IOMMU_LIVEUPDATE u32 preserved_iommufd_token; #endif +#ifdef CONFIG_DEBUG_FS + /* + * debug_root is a static property of the vfio_device + * which must be set prior to registering the vfio_device. + */ + struct dentry *debug_root; +#endif }; struct vfio_device *vfio_device_from_file(struct file *file); diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index f0db98ae91fd26d9f9046e67d46b3edb5965768a..adb3f4f1e5fe1c4dec9e585eaa3fed85da87c7e5 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -1261,6 +1261,7 @@ enum vfio_device_mig_state { VFIO_DEVICE_STATE_RUNNING_P2P = 5, VFIO_DEVICE_STATE_PRE_COPY = 6, VFIO_DEVICE_STATE_PRE_COPY_P2P = 7, + VFIO_DEVICE_STATE_NR, }; /**