On Tue, 25 Nov 2025 00:08:40 +0100 Michał Winiarski <[email protected]> wrote: > +/** > + * xe_sriov_vfio_wait_flr_done() - Wait for VF FLR completion. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * This function will wait until VF FLR is processed by PF on all tiles (or > + * until timeout occurs). > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_wait_flr_done(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_wait_flr(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_wait_flr_done, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_suspend_device() - Suspend VF. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * This function will pause VF on all tiles/GTs. > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_suspend_device(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_pause_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_suspend_device, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_resume_device() - Resume VF. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * This function will resume VF on all tiles. > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_resume_device(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_resume_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_resume_device, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_stop_copy_enter() - Initiate a VF device migration data > save. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_stop_copy_enter(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_trigger_save_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop_copy_enter, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_stop_copy_exit() - Finish a VF device migration data save. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_stop_copy_exit(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_finish_save_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop_copy_exit, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_resume_data_enter() - Initiate a VF device migration data > restore. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_resume_data_enter(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_trigger_restore_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_resume_data_enter, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_resume_data_exit() - Finish a VF device migration data > restore. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_resume_data_exit(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_finish_restore_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_resume_data_exit, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_error() - Move VF device to error state. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * Reset is needed to move it out of error state. > + * > + * Return: 0 on success or a negative error code on failure. > + */ > +int xe_sriov_vfio_error(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_control_stop_vf(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_error, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_data_read() - Read migration data from the VF device. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * @buf: start address of userspace buffer > + * @len: requested read size from userspace > + * > + * Return: number of bytes that has been successfully read, > + * 0 if no more migration data is available, -errno on failure. > + */ > +ssize_t xe_sriov_vfio_data_read(struct xe_device *xe, unsigned int vfid, > + char __user *buf, size_t len) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_migration_read(xe, vfid, buf, len); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_data_read, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_data_write() - Write migration data to the VF device. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * @buf: start address of userspace buffer > + * @len: requested write size from userspace > + * > + * Return: number of bytes that has been successfully written, -errno on > failure. > + */ > +ssize_t xe_sriov_vfio_data_write(struct xe_device *xe, unsigned int vfid, > + const char __user *buf, size_t len) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_migration_write(xe, vfid, buf, len); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_data_write, "xe-vfio-pci"); > + > +/** > + * xe_sriov_vfio_stop_copy_size() - Get a size estimate of VF device > migration data. > + * @xe: the PF &xe_device obtained by calling xe_sriov_vfio_get_pf() > + * @vfid: the VF identifier (can't be 0) > + * > + * Return: migration data size in bytes or a negative error code on failure. > + */ > +ssize_t xe_sriov_vfio_stop_copy_size(struct xe_device *xe, unsigned int vfid) > +{ > + if (!IS_SRIOV_PF(xe)) > + return -EPERM; > + if (vfid == PFID || vfid > xe_sriov_pf_num_vfs(xe)) > + return -EINVAL; > + > + guard(xe_pm_runtime_noresume)(xe); > + > + return xe_sriov_pf_migration_size(xe, vfid); > +} > +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop_copy_size, "xe-vfio-pci");
The duplicated testing and identical structure of most of the above functions suggests a helper, if not full on definition by macro. Thanks, Alex
