1 /* 2 * Copyright (c) 2024-2025 Oracle and/or its affiliates. 3 * 4 * SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #include "qemu/osdep.h" 8 #include "qapi/error.h" 9 #include "hw/vfio/vfio-cpr.h" 10 #include "migration/blocker.h" 11 #include "migration/cpr.h" 12 #include "migration/migration.h" 13 #include "migration/vmstate.h" 14 #include "system/iommufd.h" 15 #include "vfio-iommufd.h" 16 17 static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp) 18 { 19 if (!iommufd_change_process_capable(be)) { 20 if (errp) { 21 error_setg(errp, "vfio iommufd backend does not support " 22 "IOMMU_IOAS_CHANGE_PROCESS"); 23 } 24 return false; 25 } 26 return true; 27 } 28 29 static const VMStateDescription iommufd_cpr_vmstate = { 30 .name = "iommufd", 31 .version_id = 0, 32 .minimum_version_id = 0, 33 .needed = cpr_incoming_needed, 34 .fields = (VMStateField[]) { 35 VMSTATE_END_OF_LIST() 36 } 37 }; 38 39 bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend *be, Error **errp) 40 { 41 Error **cpr_blocker = &be->cpr_blocker; 42 43 if (!vfio_cpr_supported(be, cpr_blocker)) { 44 return migrate_add_blocker_modes(cpr_blocker, errp, 45 MIG_MODE_CPR_TRANSFER, -1) == 0; 46 } 47 48 vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be); 49 50 return true; 51 } 52 53 void vfio_iommufd_cpr_unregister_iommufd(IOMMUFDBackend *be) 54 { 55 vmstate_unregister(NULL, &iommufd_cpr_vmstate, be); 56 migrate_del_blocker(&be->cpr_blocker); 57 } 58 59 bool vfio_iommufd_cpr_register_container(VFIOIOMMUFDContainer *container, 60 Error **errp) 61 { 62 VFIOContainerBase *bcontainer = &container->bcontainer; 63 64 migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier, 65 vfio_cpr_reboot_notifier, 66 MIG_MODE_CPR_REBOOT); 67 68 vfio_cpr_add_kvm_notifier(); 69 70 return true; 71 } 72 73 void vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container) 74 { 75 VFIOContainerBase *bcontainer = &container->bcontainer; 76 77 migration_remove_notifier(&bcontainer->cpr_reboot_notifier); 78 } 79 80 void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev) 81 { 82 } 83 84 void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev) 85 { 86 } 87