vfio: Introduce vfio_listener_un/register() routines

This hides the MemoryListener implementation and makes the code common
to both IOMMU backends, legacy and IOMMUFD.

Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: John Levon <john.levon@nutanix.com>
Link: https://lore.kernel.org/qemu-devel/20250326075122.1299361-35-clg@redhat.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
Cédric Le Goater 2025-03-26 08:51:19 +01:00
parent 74d376378e
commit a9183378f5
4 changed files with 28 additions and 17 deletions

View file

@ -616,12 +616,7 @@ static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as,
group->container = container; group->container = container;
QLIST_INSERT_HEAD(&container->group_list, group, container_next); QLIST_INSERT_HEAD(&container->group_list, group, container_next);
bcontainer->listener = vfio_memory_listener; if (!vfio_listener_register(bcontainer, errp)) {
memory_listener_register(&bcontainer->listener, bcontainer->space->as);
if (bcontainer->error) {
error_propagate_prepend(errp, bcontainer->error,
"memory listener initialization failed: ");
goto listener_release_exit; goto listener_release_exit;
} }
@ -631,7 +626,7 @@ static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as,
listener_release_exit: listener_release_exit:
QLIST_REMOVE(group, container_next); QLIST_REMOVE(group, container_next);
vfio_kvm_device_del_group(group); vfio_kvm_device_del_group(group);
memory_listener_unregister(&bcontainer->listener); vfio_listener_unregister(bcontainer);
if (vioc->release) { if (vioc->release) {
vioc->release(bcontainer); vioc->release(bcontainer);
} }
@ -669,7 +664,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
* group. * group.
*/ */
if (QLIST_EMPTY(&container->group_list)) { if (QLIST_EMPTY(&container->group_list)) {
memory_listener_unregister(&bcontainer->listener); vfio_listener_unregister(bcontainer);
if (vioc->release) { if (vioc->release) {
vioc->release(bcontainer); vioc->release(bcontainer);
} }

View file

@ -410,7 +410,7 @@ static void iommufd_cdev_container_destroy(VFIOIOMMUFDContainer *container)
if (!QLIST_EMPTY(&bcontainer->device_list)) { if (!QLIST_EMPTY(&bcontainer->device_list)) {
return; return;
} }
memory_listener_unregister(&bcontainer->listener); vfio_listener_unregister(bcontainer);
iommufd_backend_free_id(container->be, container->ioas_id); iommufd_backend_free_id(container->be, container->ioas_id);
object_unref(container); object_unref(container);
} }
@ -562,12 +562,7 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
bcontainer->pgsizes = qemu_real_host_page_size(); bcontainer->pgsizes = qemu_real_host_page_size();
} }
bcontainer->listener = vfio_memory_listener; if (!vfio_listener_register(bcontainer, errp)) {
memory_listener_register(&bcontainer->listener, bcontainer->space->as);
if (bcontainer->error) {
error_propagate_prepend(errp, bcontainer->error,
"memory listener initialization failed: ");
goto err_listener_register; goto err_listener_register;
} }

View file

@ -45,6 +45,7 @@
#include "system/tpm.h" #include "system/tpm.h"
#include "vfio-migration-internal.h" #include "vfio-migration-internal.h"
#include "vfio-helpers.h" #include "vfio-helpers.h"
#include "vfio-listener.h"
/* /*
* Device state interfaces * Device state interfaces
@ -1162,7 +1163,7 @@ static void vfio_listener_log_sync(MemoryListener *listener,
} }
} }
const MemoryListener vfio_memory_listener = { static const MemoryListener vfio_memory_listener = {
.name = "vfio", .name = "vfio",
.region_add = vfio_listener_region_add, .region_add = vfio_listener_region_add,
.region_del = vfio_listener_region_del, .region_del = vfio_listener_region_del,
@ -1170,3 +1171,22 @@ const MemoryListener vfio_memory_listener = {
.log_global_stop = vfio_listener_log_global_stop, .log_global_stop = vfio_listener_log_global_stop,
.log_sync = vfio_listener_log_sync, .log_sync = vfio_listener_log_sync,
}; };
bool vfio_listener_register(VFIOContainerBase *bcontainer, Error **errp)
{
bcontainer->listener = vfio_memory_listener;
memory_listener_register(&bcontainer->listener, bcontainer->space->as);
if (bcontainer->error) {
error_propagate_prepend(errp, bcontainer->error,
"memory listener initialization failed: ");
return false;
}
return true;
}
void vfio_listener_unregister(VFIOContainerBase *bcontainer)
{
memory_listener_unregister(&bcontainer->listener);
}

View file

@ -9,6 +9,7 @@
#ifndef HW_VFIO_VFIO_LISTENER_H #ifndef HW_VFIO_VFIO_LISTENER_H
#define HW_VFIO_VFIO_LISTENER_H #define HW_VFIO_VFIO_LISTENER_H
extern const MemoryListener vfio_memory_listener; bool vfio_listener_register(VFIOContainerBase *bcontainer, Error **errp);
void vfio_listener_unregister(VFIOContainerBase *bcontainer);
#endif /* HW_VFIO_VFIO_LISTENER_H */ #endif /* HW_VFIO_VFIO_LISTENER_H */