diff --git a/backends/iommufd.c b/backends/iommufd.c
index 15f2a513501..45fd2e44c7f 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -85,7 +85,9 @@ static void iommufd_backend_complete(UserCreatable *uc, Error
**errp)
if (cpr_is_incoming()) {
be->fd = cpr_find_fd(name, 0);
} else {
- cpr_save_fd(name, 0, be->fd);
+ if (!cpr_save_fd(name, 0, be->fd, errp)) {
+ return;
+ }
}
} else if (!g_file_test("/dev/iommu", G_FILE_TEST_EXISTS)) {
error_setg(errp, "/dev/iommu does not exist"
diff --git a/hw/vfio/container-legacy.c b/hw/vfio/container-legacy.c
index 7ac7b372145..50ca5a3a7ea 100644
--- a/hw/vfio/container-legacy.c
+++ b/hw/vfio/container-legacy.c
@@ -847,13 +847,8 @@ static bool vfio_device_get(VFIOGroup *group, const char
*name,
g_autofree struct vfio_device_info *info = NULL;
int fd;
- fd = vfio_cpr_group_get_device_fd(group->fd, name);
+ fd = vfio_cpr_group_get_device_fd(group, name, errp);
if (fd < 0) {
- error_setg_errno(errp, errno, "error getting device from group %d",
- group->groupid);
- error_append_hint(errp,
- "Verify all devices in group %d are bound to vfio-<bus> "
- "or pci-stub and not already in use\n", group->groupid);
return false;
}
diff --git a/hw/vfio/cpr-legacy.c b/hw/vfio/cpr-legacy.c
index 2d40d8baeaf..807ffacdbc9 100644
--- a/hw/vfio/cpr-legacy.c
+++ b/hw/vfio/cpr-legacy.c
@@ -254,17 +254,33 @@ bool vfio_cpr_ram_discard_replay_populated(VFIOContainer
*bcontainer,
&vrdl->listener) == 0;
}
-int vfio_cpr_group_get_device_fd(int d, const char *name)
+int vfio_cpr_group_get_device_fd(VFIOGroup *group, const char *name,
+ Error **errp)
{
+ ERRP_GUARD();
const int id = 0;
int fd = cpr_find_fd(name, id);
+ if (fd >= 0) {
+ return fd;
+ }
+
+ fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name);
if (fd < 0) {
- fd = ioctl(d, VFIO_GROUP_GET_DEVICE_FD, name);
- if (fd >= 0) {
- cpr_save_fd(name, id, fd);
- }
+ error_setg_errno(errp, errno, "error getting device from group %d",
+ group->groupid);
+ error_append_hint(errp,
+ "Verify all devices in group %d are bound to "
+ "vfio-<bus> or pci-stub and not already in use\n",
+ group->groupid);
+ return -1;
}
+
+ if (!cpr_save_fd(name, id, fd, errp)) {
+ close(fd);
+ return -1;
+ }
+
return fd;
}
@@ -291,6 +307,7 @@ bool vfio_cpr_container_match(VFIOLegacyContainer *container, VFIOGroup *group,
*/
cpr_delete_fd("vfio_container_for_group", group->groupid);
close(fd);
- cpr_save_fd("vfio_container_for_group", group->groupid, container->fd);
+ cpr_save_fd("vfio_container_for_group", group->groupid, container->fd,
+ &error_abort);
return true;
}
diff --git a/hw/vfio/cpr.c b/hw/vfio/cpr.c
index ffa4f8e099d..6e1659dcddc 100644
--- a/hw/vfio/cpr.c
+++ b/hw/vfio/cpr.c
@@ -32,11 +32,11 @@ int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier,
#define STRDUP_VECTOR_FD_NAME(vdev, name) \
g_strdup_printf("%s_%s", (vdev)->vbasedev.name, (name))
-void vfio_cpr_save_vector_fd(VFIOPCIDevice *vdev, const char *name, int nr,
- int fd)
+bool vfio_cpr_save_vector_fd(VFIOPCIDevice *vdev, const char *name, int nr,
+ int fd, Error **errp)
{
g_autofree char *fdname = STRDUP_VECTOR_FD_NAME(vdev, name);
- cpr_save_fd(fdname, nr, fd);
+ return cpr_save_fd(fdname, nr, fd, errp);
}
int vfio_cpr_load_vector_fd(VFIOPCIDevice *vdev, const char *name, int nr)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 428ab2f0698..ad13f2306f1 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -76,7 +76,10 @@ static bool vfio_notifier_init(VFIOPCIDevice *vdev,
EventNotifier *e,
}
fd = event_notifier_get_fd(e);
- vfio_cpr_save_vector_fd(vdev, name, nr, fd);
+ if (!vfio_cpr_save_vector_fd(vdev, name, nr, fd, errp)) {
+ event_notifier_cleanup(e);
+ return false;
+ }
return true;
}
diff --git a/include/hw/vfio/vfio-cpr.h b/include/hw/vfio/vfio-cpr.h
index ecabe0c747d..9157a4ac649 100644
--- a/include/hw/vfio/vfio-cpr.h
+++ b/include/hw/vfio/vfio-cpr.h
@@ -60,7 +60,8 @@ void vfio_iommufd_cpr_register_device(struct VFIODevice
*vbasedev);
void vfio_iommufd_cpr_unregister_device(struct VFIODevice *vbasedev);
void vfio_cpr_load_device(struct VFIODevice *vbasedev);
-int vfio_cpr_group_get_device_fd(int d, const char *name);
+int vfio_cpr_group_get_device_fd(struct VFIOGroup *group, const char *name,
+ Error **errp);
bool vfio_cpr_container_match(struct VFIOLegacyContainer *container,
struct VFIOGroup *group, int fd);
@@ -71,8 +72,8 @@ void vfio_cpr_giommu_remap(struct VFIOContainer *bcontainer,
bool vfio_cpr_ram_discard_replay_populated(
struct VFIOContainer *bcontainer, const MemoryRegionSection *section);
-void vfio_cpr_save_vector_fd(struct VFIOPCIDevice *vdev, const char *name,
- int nr, int fd);
+bool vfio_cpr_save_vector_fd(struct VFIOPCIDevice *vdev, const char *name,
+ int nr, int fd, Error **errp);
int vfio_cpr_load_vector_fd(struct VFIOPCIDevice *vdev, const char *name,
int nr);
void vfio_cpr_delete_vector_fd(struct VFIOPCIDevice *vdev, const char *name,