[PATCH v3 6/6] vfio/pci: Expose latched module parameter policy in debugfs
From: Alex Williamson
Date: Mon Jun 15 2026 - 15:15:32 EST
The nointxmask and disable_idle_d3 module parameters remain writable,
but vfio-pci now latches their values into each device at init. Once a
device is registered, changing the module parameter only affects future
devices, leaving no direct way to confirm the effective policy for an
existing device.
Add a pci debugfs directory under the VFIO device debugfs root and
report the per-device nointxmask and disable_idle_d3 values. These are
read-only debugfs views and use the same Y/N bool output convention as
the module parameters.
Read-only vfio-pci parameters, such as disable_vga, are not exposed here
because they cannot drift from the latched device value, therefore the
existing module parameter exposure via sysfs is sufficient.
Note that while only vfio-pci currently provides these options, the
implementation is in vfio-pci-core and therefore properly reflects the
device policy in the core, regardless of driver.
Assisted-by: OpenAI Codex:gpt-5
Cc: Guixin Liu <kanie@xxxxxxxxxxxxxxxxx>
Signed-off-by: Alex Williamson <alex.williamson@xxxxxxxxxx>
---
Documentation/ABI/testing/debugfs-vfio | 26 ++++++++++++
drivers/vfio/pci/vfio_pci_core.c | 59 ++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/Documentation/ABI/testing/debugfs-vfio b/Documentation/ABI/testing/debugfs-vfio
index 70ec2d454686..ed2f29c3a9b4 100644
--- a/Documentation/ABI/testing/debugfs-vfio
+++ b/Documentation/ABI/testing/debugfs-vfio
@@ -29,3 +29,29 @@ Date: Oct 2025
KernelVersion: 6.18
Contact: Cédric Le Goater <clg@xxxxxxxxxx>
Description: Read the migration features of the vfio device.
+
+What: /sys/kernel/debug/vfio/<device>/pci
+Date: June 2026
+KernelVersion: 7.2
+Contact: Alex Williamson <alex.williamson@xxxxxxxxxx>
+Description: This debugfs file directory is used for debugging
+ VFIO PCI devices.
+
+What: /sys/kernel/debug/vfio/<device>/pci/nointxmask
+Date: June 2026
+KernelVersion: 7.2
+Contact: Alex Williamson <alex.williamson@xxxxxxxxxx>
+Description: Read the nointxmask policy latched for this device. This
+ policy governs whether the device may use PCI 2.3 style
+ INTx masking when supported, reporting a value of "N", or
+ requires APIC level INTx masking, reporting a value of "Y".
+
+What: /sys/kernel/debug/vfio/<device>/pci/disable_idle_d3
+Date: June 2026
+KernelVersion: 7.2
+Contact: Alex Williamson <alex.williamson@xxxxxxxxxx>
+Description: Read the disable_idle_d3 policy latched for this device. This
+ policy governs whether the device PM runtime usage count is
+ kept elevated while the device is bound to the driver and
+ unused, reporting a value of "Y", or decremented to allow the
+ device to enter a low power state, reporting a value of "N".
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index db36d903dcd4..3f11a9624b9c 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/aperture.h>
+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/eventfd.h>
#include <linux/file.h>
@@ -29,6 +30,7 @@
#include <linux/sched/mm.h>
#include <linux/iommufd.h>
#include <linux/pci-p2pdma.h>
+#include <linux/seq_file.h>
#if IS_ENABLED(CONFIG_EEH)
#include <asm/eeh.h>
#endif
@@ -97,6 +99,60 @@ static inline bool vfio_vga_disabled(struct vfio_pci_core_device *vdev)
#endif
}
+#ifdef CONFIG_VFIO_DEBUGFS
+static struct vfio_pci_core_device *
+vfio_pci_core_debugfs_private(struct seq_file *seq)
+{
+ struct device *dev = seq->private;
+ struct vfio_device *core_vdev = container_of(dev, struct vfio_device,
+ device);
+
+ return container_of(core_vdev, struct vfio_pci_core_device, vdev);
+}
+
+static int vfio_pci_core_debugfs_nointxmask(struct seq_file *seq, void *data)
+{
+ struct vfio_pci_core_device *vdev = vfio_pci_core_debugfs_private(seq);
+
+ seq_puts(seq, vdev->nointxmask ? "Y\n" : "N\n");
+ return 0;
+}
+
+static int vfio_pci_core_debugfs_disable_idle_d3(struct seq_file *seq,
+ void *data)
+{
+ struct vfio_pci_core_device *vdev = vfio_pci_core_debugfs_private(seq);
+
+ seq_puts(seq, vdev->disable_idle_d3 ? "Y\n" : "N\n");
+ return 0;
+}
+
+/*
+ * disable_idle_d3 and nointxmask are writable module parameters latched
+ * per device at init, so a device's effective value can differ from the
+ * current parameter setting. Expose the per-device (read-only) values
+ * here for visibility; read-only parameters can't drift and are omitted.
+ */
+static void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
+{
+ struct device *dev = &vdev->vdev.device;
+ struct dentry *pci_dir;
+
+ if (IS_ERR_OR_NULL(vdev->vdev.debug_root))
+ return;
+
+ pci_dir = debugfs_create_dir("pci", vdev->vdev.debug_root);
+ debugfs_create_devm_seqfile(dev, "nointxmask", pci_dir,
+ vfio_pci_core_debugfs_nointxmask);
+ debugfs_create_devm_seqfile(dev, "disable_idle_d3", pci_dir,
+ vfio_pci_core_debugfs_disable_idle_d3);
+}
+#else
+static inline void vfio_pci_core_debugfs_init(struct vfio_pci_core_device *vdev)
+{
+}
+#endif /* CONFIG_VFIO_DEBUGFS */
+
/*
* Our VGA arbiter participation is limited since we don't know anything
* about the device itself. However, if the device is the only VGA device
@@ -2242,6 +2298,9 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
ret = vfio_register_group_dev(&vdev->vdev);
if (ret)
goto out_power;
+
+ vfio_pci_core_debugfs_init(vdev);
+
return 0;
out_power:
--
2.53.0