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