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 const VMStateDescription vmstate_cpr_vfio_devices; /* TBD in a later patch */ 18 19 static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp) 20 { 21 if (!iommufd_change_process_capable(be)) { 22 if (errp) { 23 error_setg(errp, "vfio iommufd backend does not support " 24 "IOMMU_IOAS_CHANGE_PROCESS"); 25 } 26 return false; 27 } 28 return true; 29 } 30 31 static const VMStateDescription iommufd_cpr_vmstate = { 32 .name = "iommufd", 33 .version_id = 0, 34 .minimum_version_id = 0, 35 .needed = cpr_incoming_needed, 36 .fields = (VMStateField[]) { 37 VMSTATE_END_OF_LIST() 38 } 39 }; 40 41 bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend *be, Error **errp) 42 { 43 Error **cpr_blocker = &be->cpr_blocker; 44 45 if (!vfio_cpr_supported(be, cpr_blocker)) { 46 return migrate_add_blocker_modes(cpr_blocker, errp, 47 MIG_MODE_CPR_TRANSFER, -1) == 0; 48 } 49 50 vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be); 51 52 return true; 53 } 54 55 void vfio_iommufd_cpr_unregister_iommufd(IOMMUFDBackend *be) 56 { 57 vmstate_unregister(NULL, &iommufd_cpr_vmstate, be); 58 migrate_del_blocker(&be->cpr_blocker); 59 } 60 61 bool vfio_iommufd_cpr_register_container(VFIOIOMMUFDContainer *container, 62 Error **errp) 63 { 64 VFIOContainerBase *bcontainer = &container->bcontainer; 65 66 migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier, 67 vfio_cpr_reboot_notifier, 68 MIG_MODE_CPR_REBOOT); 69 70 vfio_cpr_add_kvm_notifier(); 71 72 return true; 73 } 74 75 void vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container) 76 { 77 VFIOContainerBase *bcontainer = &container->bcontainer; 78 79 migration_remove_notifier(&bcontainer->cpr_reboot_notifier); 80 } 81 82 void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev) 83 { 84 } 85 86 void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev) 87 { 88 } 89