xref: /qemu/hw/vfio/cpr-iommufd.c (revision a6f2f9c42f3a5418fc7000b1fd331b086b6133d9)
106c6a658SSteve Sistare /*
206c6a658SSteve Sistare  * Copyright (c) 2024-2025 Oracle and/or its affiliates.
306c6a658SSteve Sistare  *
406c6a658SSteve Sistare  * SPDX-License-Identifier: GPL-2.0-or-later
506c6a658SSteve Sistare  */
606c6a658SSteve Sistare 
706c6a658SSteve Sistare #include "qemu/osdep.h"
806c6a658SSteve Sistare #include "qapi/error.h"
906c6a658SSteve Sistare #include "hw/vfio/vfio-cpr.h"
1006c6a658SSteve Sistare #include "migration/blocker.h"
1106c6a658SSteve Sistare #include "migration/cpr.h"
1206c6a658SSteve Sistare #include "migration/migration.h"
1306c6a658SSteve Sistare #include "migration/vmstate.h"
1406c6a658SSteve Sistare #include "system/iommufd.h"
1506c6a658SSteve Sistare #include "vfio-iommufd.h"
1606c6a658SSteve Sistare 
17*a6f2f9c4SSteve Sistare const VMStateDescription vmstate_cpr_vfio_devices;  /* TBD in a later patch */
18*a6f2f9c4SSteve Sistare 
1906c6a658SSteve Sistare static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp)
2006c6a658SSteve Sistare {
2106c6a658SSteve Sistare     if (!iommufd_change_process_capable(be)) {
2206c6a658SSteve Sistare         if (errp) {
2306c6a658SSteve Sistare             error_setg(errp, "vfio iommufd backend does not support "
2406c6a658SSteve Sistare                        "IOMMU_IOAS_CHANGE_PROCESS");
2506c6a658SSteve Sistare         }
2606c6a658SSteve Sistare         return false;
2706c6a658SSteve Sistare     }
2806c6a658SSteve Sistare     return true;
2906c6a658SSteve Sistare }
3006c6a658SSteve Sistare 
3106c6a658SSteve Sistare static const VMStateDescription iommufd_cpr_vmstate = {
3206c6a658SSteve Sistare     .name = "iommufd",
3306c6a658SSteve Sistare     .version_id = 0,
3406c6a658SSteve Sistare     .minimum_version_id = 0,
3506c6a658SSteve Sistare     .needed = cpr_incoming_needed,
3606c6a658SSteve Sistare     .fields = (VMStateField[]) {
3706c6a658SSteve Sistare         VMSTATE_END_OF_LIST()
3806c6a658SSteve Sistare     }
3906c6a658SSteve Sistare };
4006c6a658SSteve Sistare 
4106c6a658SSteve Sistare bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend *be, Error **errp)
4206c6a658SSteve Sistare {
4306c6a658SSteve Sistare     Error **cpr_blocker = &be->cpr_blocker;
4406c6a658SSteve Sistare 
4506c6a658SSteve Sistare     if (!vfio_cpr_supported(be, cpr_blocker)) {
4606c6a658SSteve Sistare         return migrate_add_blocker_modes(cpr_blocker, errp,
4706c6a658SSteve Sistare                                          MIG_MODE_CPR_TRANSFER, -1) == 0;
4806c6a658SSteve Sistare     }
4906c6a658SSteve Sistare 
5006c6a658SSteve Sistare     vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be);
5106c6a658SSteve Sistare 
5206c6a658SSteve Sistare     return true;
5306c6a658SSteve Sistare }
5406c6a658SSteve Sistare 
5506c6a658SSteve Sistare void vfio_iommufd_cpr_unregister_iommufd(IOMMUFDBackend *be)
5606c6a658SSteve Sistare {
5706c6a658SSteve Sistare     vmstate_unregister(NULL, &iommufd_cpr_vmstate, be);
5806c6a658SSteve Sistare     migrate_del_blocker(&be->cpr_blocker);
5906c6a658SSteve Sistare }
6006c6a658SSteve Sistare 
6106c6a658SSteve Sistare bool vfio_iommufd_cpr_register_container(VFIOIOMMUFDContainer *container,
6206c6a658SSteve Sistare                                          Error **errp)
6306c6a658SSteve Sistare {
6406c6a658SSteve Sistare     VFIOContainerBase *bcontainer = &container->bcontainer;
6506c6a658SSteve Sistare 
6606c6a658SSteve Sistare     migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
6706c6a658SSteve Sistare                                 vfio_cpr_reboot_notifier,
6806c6a658SSteve Sistare                                 MIG_MODE_CPR_REBOOT);
6906c6a658SSteve Sistare 
7006c6a658SSteve Sistare     vfio_cpr_add_kvm_notifier();
7106c6a658SSteve Sistare 
7206c6a658SSteve Sistare     return true;
7306c6a658SSteve Sistare }
7406c6a658SSteve Sistare 
7506c6a658SSteve Sistare void vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container)
7606c6a658SSteve Sistare {
7706c6a658SSteve Sistare     VFIOContainerBase *bcontainer = &container->bcontainer;
7806c6a658SSteve Sistare 
7906c6a658SSteve Sistare     migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
8006c6a658SSteve Sistare }
8106c6a658SSteve Sistare 
8206c6a658SSteve Sistare void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev)
8306c6a658SSteve Sistare {
8406c6a658SSteve Sistare }
8506c6a658SSteve Sistare 
8606c6a658SSteve Sistare void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev)
8706c6a658SSteve Sistare {
8806c6a658SSteve Sistare }
89