@@ -863,7 +863,7 @@ static const struct file_operations hisi_acc_vf_save_fops = {
863
863
};
864
864
865
865
static struct hisi_acc_vf_migration_file *
866
- hisi_acc_vf_stop_copy (struct hisi_acc_vf_core_device * hisi_acc_vdev )
866
+ hisi_acc_open_saving_migf (struct hisi_acc_vf_core_device * hisi_acc_vdev )
867
867
{
868
868
struct hisi_acc_vf_migration_file * migf ;
869
869
int ret ;
@@ -885,7 +885,7 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
885
885
mutex_init (& migf -> lock );
886
886
migf -> hisi_acc_vdev = hisi_acc_vdev ;
887
887
888
- ret = vf_qm_state_save (hisi_acc_vdev , migf );
888
+ ret = vf_qm_get_match_data (hisi_acc_vdev , & migf -> vf_data );
889
889
if (ret ) {
890
890
fput (migf -> filp );
891
891
return ERR_PTR (ret );
@@ -894,6 +894,44 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
894
894
return migf ;
895
895
}
896
896
897
+ static struct hisi_acc_vf_migration_file *
898
+ hisi_acc_vf_pre_copy (struct hisi_acc_vf_core_device * hisi_acc_vdev )
899
+ {
900
+ struct hisi_acc_vf_migration_file * migf ;
901
+
902
+ migf = hisi_acc_open_saving_migf (hisi_acc_vdev );
903
+ if (IS_ERR (migf ))
904
+ return migf ;
905
+
906
+ migf -> total_length = QM_MATCH_SIZE ;
907
+ return migf ;
908
+ }
909
+
910
+ static struct hisi_acc_vf_migration_file *
911
+ hisi_acc_vf_stop_copy (struct hisi_acc_vf_core_device * hisi_acc_vdev , bool open )
912
+ {
913
+ int ret ;
914
+ struct hisi_acc_vf_migration_file * migf = NULL ;
915
+
916
+ if (open ) {
917
+ /*
918
+ * Userspace didn't use PRECOPY support. Hence saving_migf
919
+ * is not opened yet.
920
+ */
921
+ migf = hisi_acc_open_saving_migf (hisi_acc_vdev );
922
+ if (IS_ERR (migf ))
923
+ return migf ;
924
+ } else {
925
+ migf = hisi_acc_vdev -> saving_migf ;
926
+ }
927
+
928
+ ret = vf_qm_state_save (hisi_acc_vdev , migf );
929
+ if (ret )
930
+ return ERR_PTR (ret );
931
+
932
+ return open ? migf : NULL ;
933
+ }
934
+
897
935
static int hisi_acc_vf_stop_device (struct hisi_acc_vf_core_device * hisi_acc_vdev )
898
936
{
899
937
struct device * dev = & hisi_acc_vdev -> vf_dev -> dev ;
@@ -921,6 +959,31 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
921
959
u32 cur = hisi_acc_vdev -> mig_state ;
922
960
int ret ;
923
961
962
+ if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_PRE_COPY ) {
963
+ struct hisi_acc_vf_migration_file * migf ;
964
+
965
+ migf = hisi_acc_vf_pre_copy (hisi_acc_vdev );
966
+ if (IS_ERR (migf ))
967
+ return ERR_CAST (migf );
968
+ get_file (migf -> filp );
969
+ hisi_acc_vdev -> saving_migf = migf ;
970
+ return migf -> filp ;
971
+ }
972
+
973
+ if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_STOP_COPY ) {
974
+ struct hisi_acc_vf_migration_file * migf ;
975
+
976
+ ret = hisi_acc_vf_stop_device (hisi_acc_vdev );
977
+ if (ret )
978
+ return ERR_PTR (ret );
979
+
980
+ migf = hisi_acc_vf_stop_copy (hisi_acc_vdev , false);
981
+ if (IS_ERR (migf ))
982
+ return ERR_CAST (migf );
983
+
984
+ return NULL ;
985
+ }
986
+
924
987
if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_STOP ) {
925
988
ret = hisi_acc_vf_stop_device (hisi_acc_vdev );
926
989
if (ret )
@@ -931,7 +994,7 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
931
994
if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_STOP_COPY ) {
932
995
struct hisi_acc_vf_migration_file * migf ;
933
996
934
- migf = hisi_acc_vf_stop_copy (hisi_acc_vdev );
997
+ migf = hisi_acc_vf_stop_copy (hisi_acc_vdev , true );
935
998
if (IS_ERR (migf ))
936
999
return ERR_CAST (migf );
937
1000
get_file (migf -> filp );
@@ -963,6 +1026,11 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
963
1026
return NULL ;
964
1027
}
965
1028
1029
+ if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING ) {
1030
+ hisi_acc_vf_disable_fds (hisi_acc_vdev );
1031
+ return NULL ;
1032
+ }
1033
+
966
1034
if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_RUNNING ) {
967
1035
hisi_acc_vf_start_device (hisi_acc_vdev );
968
1036
return NULL ;
0 commit comments