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