if (vbasedev->mdev) {
error_setg(&vbasedev->cpr.mdev_blocker,
"CPR does not support vfio mdev %s", vbasedev->name);
- if (migrate_add_blocker_modes(&vbasedev->cpr.mdev_blocker, errp,
- MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC,
- -1) < 0) {
+ if (migrate_add_blocker_modes(&vbasedev->cpr.mdev_blocker,
+ BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC),
+ errp) < 0) {
goto hiod_unref_exit;
}
}
Error **cpr_blocker = &be->cpr_blocker;
if (!vfio_cpr_supported(be, cpr_blocker)) {
- return migrate_add_blocker_modes(cpr_blocker, errp,
- MIG_MODE_CPR_TRANSFER,
- MIG_MODE_CPR_EXEC, -1) == 0;
+ return migrate_add_blocker_modes(cpr_blocker,
+ BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_TRANSFER),
+ errp);
}
vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be);
MIG_MODE_CPR_REBOOT);
if (!vfio_cpr_supported(container, cpr_blocker)) {
- return migrate_add_blocker_modes(cpr_blocker, errp,
- MIG_MODE_CPR_TRANSFER,
- MIG_MODE_CPR_EXEC, -1) == 0;
+ return migrate_add_blocker_modes(cpr_blocker,
+ BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC),
+ errp) == 0;
}
vfio_cpr_add_kvm_notifier();
migration_add_notifier_modes(&container->cpr.transfer_notifier,
vfio_cpr_fail_notifier,
- MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC, -1);
+ BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC));
return true;
}
if (!kvm_close_notifier.notify) {
migration_add_notifier_modes(&kvm_close_notifier,
vfio_cpr_kvm_close_notifier,
- MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC,
- -1);
+ BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC));
}
}
{
migration_add_notifier_modes(&vdev->cpr.transfer_notifier,
vfio_cpr_pci_notifier,
- MIG_MODE_CPR_TRANSFER, MIG_MODE_CPR_EXEC, -1);
+ BIT(MIG_MODE_CPR_TRANSFER) | BIT(MIG_MODE_CPR_EXEC));
}
void vfio_cpr_pci_unregister_device(VFIOPCIDevice *vdev)
"vfio device with fd=%d needs an id property",
vbasedev->fd);
return migrate_add_blocker_modes(&vbasedev->cpr.id_blocker,
- errp, MIG_MODE_CPR_TRANSFER,
- -1) == 0;
+ BIT(MIG_MODE_CPR_TRANSFER),
+ errp) == 0;
}
}
}
#include "qapi/qapi-types-migration.h"
-#define MIG_MODE_ALL MIG_MODE__MAX
-
/**
* @migrate_add_blocker - prevent all modes of migration from proceeding
*
*
* @reasonp - address of an error to be returned whenever migration is attempted
*
- * @errp - [out] The reason (if any) we cannot block migration right now.
+ * @modes - the migration modes to be blocked, a bit set of MigMode
*
- * @mode - one or more migration modes to be blocked. The list is terminated
- * by -1 or MIG_MODE_ALL. For the latter, all modes are blocked.
+ * @errp - [out] The reason (if any) we cannot block migration right now.
*
* @returns - 0 on success, -EBUSY/-EACCES on failure, with errp set.
*
* *@reasonp is freed and set to NULL if failure is returned.
* On success, the caller must not free *@reasonp before the blocker is removed.
*/
-int migrate_add_blocker_modes(Error **reasonp, Error **errp, MigMode mode, ...);
+int migrate_add_blocker_modes(Error **reasonp, unsigned modes, Error **errp);
#endif
MigrationNotifyFunc func);
/*
- * Same as migration_add_notifier, but applies to be specified @mode.
+ * Same as migration_add_notifier, but applies to the specified @mode
+ * instead of MIG_MODE_NORMAL.
*/
void migration_add_notifier_mode(NotifierWithReturn *notify,
MigrationNotifyFunc func, MigMode mode);
/*
- * Same as migration_add_notifier, but applies to all @mode in the argument
- * list. The list is terminated by -1 or MIG_MODE_ALL. For the latter,
- * the notifier is added for all modes.
+ * Same as migration_add_notifier, but applies to the specified @modes
+ * (a bitset of MigMode).
*/
void migration_add_notifier_modes(NotifierWithReturn *notify,
- MigrationNotifyFunc func, MigMode mode, ...);
+ MigrationNotifyFunc func, unsigned modes);
/*
* Remove a notifier from all modes.
}
}
-static unsigned get_modes(MigMode mode, va_list ap);
-
static void add_notifiers(NotifierWithReturn *notify, unsigned modes)
{
for (MigMode mode = 0; mode < MIG_MODE__MAX; mode++) {
}
void migration_add_notifier_modes(NotifierWithReturn *notify,
- MigrationNotifyFunc func, MigMode mode, ...)
+ MigrationNotifyFunc func, unsigned modes)
{
- unsigned modes;
- va_list ap;
-
- va_start(ap, mode);
- modes = get_modes(mode, ap);
- va_end(ap);
-
notify->notify = (NotifierWithReturnFunc)func;
add_notifiers(notify, modes);
}
void migration_add_notifier_mode(NotifierWithReturn *notify,
MigrationNotifyFunc func, MigMode mode)
{
- migration_add_notifier_modes(notify, func, mode, -1);
+ migration_add_notifier_modes(notify, func, BIT(mode));
}
void migration_add_notifier(NotifierWithReturn *notify,
MigrationNotifyFunc func)
{
- migration_add_notifier_modes(notify, func, MIG_MODE_NORMAL, -1);
+ migration_add_notifier_mode(notify, func, MIG_MODE_NORMAL);
}
void migration_remove_notifier(NotifierWithReturn *notify)
return false;
}
-static unsigned get_modes(MigMode mode, va_list ap)
-{
- unsigned modes = 0;
-
- while (mode != -1 && mode != MIG_MODE_ALL) {
- assert(mode >= MIG_MODE_NORMAL && mode < MIG_MODE__MAX);
- modes |= BIT(mode);
- mode = va_arg(ap, MigMode);
- }
- if (mode == MIG_MODE_ALL) {
- modes = BIT(MIG_MODE__MAX) - 1;
- }
- return modes;
-}
-
static int add_blockers(Error **reasonp, Error **errp, unsigned modes)
{
for (MigMode mode = 0; mode < MIG_MODE__MAX; mode++) {
int migrate_add_blocker(Error **reasonp, Error **errp)
{
- return migrate_add_blocker_modes(reasonp, errp, MIG_MODE_ALL);
+ return migrate_add_blocker_modes(reasonp, -1u, errp);
}
int migrate_add_blocker_normal(Error **reasonp, Error **errp)
{
- return migrate_add_blocker_modes(reasonp, errp, MIG_MODE_NORMAL, -1);
+ return migrate_add_blocker_modes(reasonp, BIT(MIG_MODE_NORMAL), errp);
}
-int migrate_add_blocker_modes(Error **reasonp, Error **errp, MigMode mode, ...)
+int migrate_add_blocker_modes(Error **reasonp, unsigned modes, Error **errp)
{
- unsigned modes;
- va_list ap;
-
- va_start(ap, mode);
- modes = get_modes(mode, ap);
- va_end(ap);
-
if (is_only_migratable(reasonp, errp, modes)) {
return -EACCES;
} else if (is_busy(reasonp, errp)) {
return 0;
}
-int migrate_add_blocker_modes(Error **reasonp, Error **errp, MigMode mode, ...)
+int migrate_add_blocker_modes(Error **reasonp, unsigned modes, Error **errp)
{
return 0;
}
"Memory region %s uses guest_memfd, "
"which is not supported with CPR.",
memory_region_name(new_block->mr));
- migrate_add_blocker_modes(&new_block->cpr_blocker, errp,
- MIG_MODE_CPR_TRANSFER, -1);
+ migrate_add_blocker_modes(&new_block->cpr_blocker,
+ BIT(MIG_MODE_CPR_TRANSFER), errp);
}
}
"Memory region %s is not compatible with CPR. share=on is "
"required for memory-backend objects, and aux-ram-share=on is "
"required.", memory_region_name(rb->mr));
- migrate_add_blocker_modes(&rb->cpr_blocker, errp, MIG_MODE_CPR_TRANSFER,
- -1);
+ migrate_add_blocker_modes(&rb->cpr_blocker, BIT(MIG_MODE_CPR_TRANSFER),
+ errp);
}
void ram_block_del_cpr_blocker(RAMBlock *rb)