According to the VFIO migration specifications, userspace must issue a VFIO_DEVICE_RESET ioctl if a vfio device enters an error state or fails a state transition to recover the device and return its migration state to RUNNING. This patch adds a function that is called when a VFIO_DEVICE_RESET is issued that releases any open migration file buffers and resets the migration state to RUNNING. Signed-off-by: Anthony Krowiak --- drivers/s390/crypto/vfio_ap_migration.c | 20 ++++++++++++++++++++ drivers/s390/crypto/vfio_ap_ops.c | 11 +++++++++++ drivers/s390/crypto/vfio_ap_private.h | 1 + 3 files changed, 32 insertions(+) diff --git a/drivers/s390/crypto/vfio_ap_migration.c b/drivers/s390/crypto/vfio_ap_migration.c index ba86a1afbb33..5d898be0d058 100644 --- a/drivers/s390/crypto/vfio_ap_migration.c +++ b/drivers/s390/crypto/vfio_ap_migration.c @@ -216,3 +216,23 @@ void vfio_ap_release_migration_data(struct ap_matrix_mdev *matrix_mdev) kfree(matrix_mdev->mig_data); matrix_mdev->mig_data = NULL; } + +/** + * vfio_ap_reset_migration_state - Reset the vfio-ap migration state + * + * @matrix_mdev: pointer to the object maintaining the vfio-ap device state + * + * Called during VFIO_DEVICE_RESET to clean up any active migration + * state and reset the device to RUNNING state as required by the VFIO + * migration specification. + */ +void vfio_ap_reset_migration_state(struct ap_matrix_mdev *matrix_mdev) +{ + lockdep_assert_held(&matrix_dev->mdevs_lock); + + if (!matrix_mdev->mig_data) + return; + + vfio_ap_release_mig_files(matrix_mdev); + matrix_mdev->mig_data->mig_state = VFIO_DEVICE_STATE_RUNNING; +} diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 9cbc5ecb19d5..635c8a20af86 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -2320,6 +2320,17 @@ static ssize_t vfio_ap_mdev_ioctl(struct vfio_device *vdev, break; case VFIO_DEVICE_RESET: ret = vfio_ap_mdev_reset_queues(matrix_mdev); + /* + * Reset the migration state unconditionally, regardless of + * whether the hardware queue reset succeeded. The migration + * state tracks the AP configuration transfer lifecycle and is + * independent of the hardware queue reset outcome. The VFIO + * migration spec designates VFIO_DEVICE_RESET as the mechanism + * to return device_state to RUNNING (e.g. to recover from + * ERROR), so the migration state must be cleaned up even when + * one or more queues fail to reset. + */ + vfio_ap_reset_migration_state(matrix_mdev); break; case VFIO_DEVICE_GET_IRQ_INFO: ret = vfio_ap_get_irq_info(arg); diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h index aa8a22585204..c6e577064e7e 100644 --- a/drivers/s390/crypto/vfio_ap_private.h +++ b/drivers/s390/crypto/vfio_ap_private.h @@ -174,5 +174,6 @@ void vfio_ap_on_scan_complete(struct ap_config_info *new_config_info, int vfio_ap_init_migration_data(struct ap_matrix_mdev *matrix_mdev); void vfio_ap_release_migration_data(struct ap_matrix_mdev *matrix_mdev); +void vfio_ap_reset_migration_state(struct ap_matrix_mdev *matrix_mdev); #endif /* _VFIO_AP_PRIVATE_H_ */ -- 2.53.0