[PATCH v6 26/27] vfio: selftests: Verify that opening VFIO device fails during Live Update

From: Vipin Sharma

Date: Mon Nov 02 2026 - 12:48:07 EST


Verify that opening a VFIO device through its cdev file and via
VFIO_GROUP_GET_DEVICE_FD both fail with -EBUSY if the device was
preserved across a Live Update. When a device file is preserved across a
Live Update, the file must be retrieved from /dev/liveupdate, not from
VFIO directly.

Co-developed-by: David Matlack <dmatlack@xxxxxxxxxx>
Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
Signed-off-by: Vipin Sharma <vipinsh@xxxxxxxxxx>
---
.../vfio/vfio_pci_liveupdate_kexec_test.c | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
index 4919175c1173..9610fe593cf6 100644
--- a/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
+++ b/tools/testing/selftests/vfio/vfio_pci_liveupdate_kexec_test.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only

#include <fcntl.h>
+#include <limits.h>
+#include <sys/ioctl.h>
+#include <linux/vfio.h>
#include <libliveupdate.h>
#include <libvfio.h>

@@ -56,6 +59,39 @@ static void before_kexec(int luo_fd)
daemonize_and_wait();
}

+static void check_open_vfio_device_fails(void)
+{
+ const char *cdev_path = __vfio_pci_get_cdev_path(device_bdf, true);
+ char group_path[PATH_MAX];
+ int group_fd;
+ int group;
+ int ret;
+
+ VFIO_ASSERT_NOT_NULL(cdev_path);
+
+ ret = open(cdev_path, O_RDWR);
+ VFIO_ASSERT_EQ(ret, -1);
+ VFIO_ASSERT_EQ(errno, EBUSY);
+ free((void *)cdev_path);
+
+ if (__sysfs_iommu_group_get(device_bdf, &group))
+ return;
+
+ snprintf_assert(group_path, sizeof(group_path), "/dev/vfio/noiommu-%d",
+ group);
+ group_fd = open(group_path, O_RDWR);
+ if (group_fd < 0) {
+ VFIO_ASSERT_EQ(errno, ENOENT);
+ return;
+ }
+
+ ret = ioctl(group_fd, VFIO_GROUP_GET_DEVICE_FD, device_bdf);
+ VFIO_ASSERT_EQ(ret, -1);
+ VFIO_ASSERT_EQ(errno, EBUSY);
+
+ VFIO_ASSERT_EQ(close(group_fd), 0);
+}
+
static void after_kexec(int luo_fd, int state_session_fd)
{
struct vfio_pci_device *device;
@@ -64,6 +100,8 @@ static void after_kexec(int luo_fd, int state_session_fd)
int device_fd;
int stage;

+ check_open_vfio_device_fails();
+
restore_and_read_stage(state_session_fd, STATE_TOKEN, &stage);
VFIO_ASSERT_EQ(stage, 2);

--
2.56.0.317.g454f8302e1-goog