@@ -591,7 +591,7 @@ static int qaic_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc
591591 struct qaic_bo * bo = to_qaic_bo (obj );
592592 unsigned long offset = 0 ;
593593 struct scatterlist * sg ;
594- int ret ;
594+ int ret = 0 ;
595595
596596 if (obj -> import_attach )
597597 return - EINVAL ;
@@ -663,6 +663,10 @@ int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *fi
663663 if (args -> pad )
664664 return - EINVAL ;
665665
666+ size = PAGE_ALIGN (args -> size );
667+ if (size == 0 )
668+ return - EINVAL ;
669+
666670 usr = file_priv -> driver_priv ;
667671 usr_rcu_id = srcu_read_lock (& usr -> qddev_lock );
668672 if (!usr -> qddev ) {
@@ -677,12 +681,6 @@ int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *fi
677681 goto unlock_dev_srcu ;
678682 }
679683
680- size = PAGE_ALIGN (args -> size );
681- if (size == 0 ) {
682- ret = - EINVAL ;
683- goto unlock_dev_srcu ;
684- }
685-
686684 bo = qaic_alloc_init_bo ();
687685 if (IS_ERR (bo )) {
688686 ret = PTR_ERR (bo );
@@ -926,8 +924,8 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
926924{
927925 struct qaic_attach_slice_entry * slice_ent ;
928926 struct qaic_attach_slice * args = data ;
927+ int rcu_id , usr_rcu_id , qdev_rcu_id ;
929928 struct dma_bridge_chan * dbc ;
930- int usr_rcu_id , qdev_rcu_id ;
931929 struct drm_gem_object * obj ;
932930 struct qaic_device * qdev ;
933931 unsigned long arg_size ;
@@ -936,6 +934,22 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
936934 struct qaic_bo * bo ;
937935 int ret ;
938936
937+ if (args -> hdr .count == 0 )
938+ return - EINVAL ;
939+
940+ arg_size = args -> hdr .count * sizeof (* slice_ent );
941+ if (arg_size / args -> hdr .count != sizeof (* slice_ent ))
942+ return - EINVAL ;
943+
944+ if (args -> hdr .size == 0 )
945+ return - EINVAL ;
946+
947+ if (!(args -> hdr .dir == DMA_TO_DEVICE || args -> hdr .dir == DMA_FROM_DEVICE ))
948+ return - EINVAL ;
949+
950+ if (args -> data == 0 )
951+ return - EINVAL ;
952+
939953 usr = file_priv -> driver_priv ;
940954 usr_rcu_id = srcu_read_lock (& usr -> qddev_lock );
941955 if (!usr -> qddev ) {
@@ -950,43 +964,11 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
950964 goto unlock_dev_srcu ;
951965 }
952966
953- if (args -> hdr .count == 0 ) {
954- ret = - EINVAL ;
955- goto unlock_dev_srcu ;
956- }
957-
958- arg_size = args -> hdr .count * sizeof (* slice_ent );
959- if (arg_size / args -> hdr .count != sizeof (* slice_ent )) {
960- ret = - EINVAL ;
961- goto unlock_dev_srcu ;
962- }
963-
964967 if (args -> hdr .dbc_id >= qdev -> num_dbc ) {
965968 ret = - EINVAL ;
966969 goto unlock_dev_srcu ;
967970 }
968971
969- if (args -> hdr .size == 0 ) {
970- ret = - EINVAL ;
971- goto unlock_dev_srcu ;
972- }
973-
974- if (!(args -> hdr .dir == DMA_TO_DEVICE || args -> hdr .dir == DMA_FROM_DEVICE )) {
975- ret = - EINVAL ;
976- goto unlock_dev_srcu ;
977- }
978-
979- dbc = & qdev -> dbc [args -> hdr .dbc_id ];
980- if (dbc -> usr != usr ) {
981- ret = - EINVAL ;
982- goto unlock_dev_srcu ;
983- }
984-
985- if (args -> data == 0 ) {
986- ret = - EINVAL ;
987- goto unlock_dev_srcu ;
988- }
989-
990972 user_data = u64_to_user_ptr (args -> data );
991973
992974 slice_ent = kzalloc (arg_size , GFP_KERNEL );
@@ -1013,9 +995,21 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
1013995
1014996 bo = to_qaic_bo (obj );
1015997
998+ if (bo -> sliced ) {
999+ ret = - EINVAL ;
1000+ goto put_bo ;
1001+ }
1002+
1003+ dbc = & qdev -> dbc [args -> hdr .dbc_id ];
1004+ rcu_id = srcu_read_lock (& dbc -> ch_lock );
1005+ if (dbc -> usr != usr ) {
1006+ ret = - EINVAL ;
1007+ goto unlock_ch_srcu ;
1008+ }
1009+
10161010 ret = qaic_prepare_bo (qdev , bo , & args -> hdr );
10171011 if (ret )
1018- goto put_bo ;
1012+ goto unlock_ch_srcu ;
10191013
10201014 ret = qaic_attach_slicing_bo (qdev , bo , & args -> hdr , slice_ent );
10211015 if (ret )
@@ -1025,6 +1019,7 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
10251019 dma_sync_sgtable_for_cpu (& qdev -> pdev -> dev , bo -> sgt , args -> hdr .dir );
10261020
10271021 bo -> dbc = dbc ;
1022+ srcu_read_unlock (& dbc -> ch_lock , rcu_id );
10281023 drm_gem_object_put (obj );
10291024 srcu_read_unlock (& qdev -> dev_lock , qdev_rcu_id );
10301025 srcu_read_unlock (& usr -> qddev_lock , usr_rcu_id );
@@ -1033,6 +1028,8 @@ int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_fi
10331028
10341029unprepare_bo :
10351030 qaic_unprepare_bo (qdev , bo );
1031+ unlock_ch_srcu :
1032+ srcu_read_unlock (& dbc -> ch_lock , rcu_id );
10361033put_bo :
10371034 drm_gem_object_put (obj );
10381035free_slice_ent :
@@ -1316,7 +1313,6 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr
13161313 received_ts = ktime_get_ns ();
13171314
13181315 size = is_partial ? sizeof (* pexec ) : sizeof (* exec );
1319-
13201316 n = (unsigned long )size * args -> hdr .count ;
13211317 if (args -> hdr .count == 0 || n / args -> hdr .count != size )
13221318 return - EINVAL ;
@@ -1665,6 +1661,9 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file
16651661 int rcu_id ;
16661662 int ret ;
16671663
1664+ if (args -> pad != 0 )
1665+ return - EINVAL ;
1666+
16681667 usr = file_priv -> driver_priv ;
16691668 usr_rcu_id = srcu_read_lock (& usr -> qddev_lock );
16701669 if (!usr -> qddev ) {
@@ -1679,11 +1678,6 @@ int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file
16791678 goto unlock_dev_srcu ;
16801679 }
16811680
1682- if (args -> pad != 0 ) {
1683- ret = - EINVAL ;
1684- goto unlock_dev_srcu ;
1685- }
1686-
16871681 if (args -> dbc_id >= qdev -> num_dbc ) {
16881682 ret = - EINVAL ;
16891683 goto unlock_dev_srcu ;
@@ -1855,6 +1849,11 @@ void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id)
18551849 dbc -> usr = NULL ;
18561850 empty_xfer_list (qdev , dbc );
18571851 synchronize_srcu (& dbc -> ch_lock );
1852+ /*
1853+ * Threads holding channel lock, may add more elements in the xfer_list.
1854+ * Flush out these elements from xfer_list.
1855+ */
1856+ empty_xfer_list (qdev , dbc );
18581857}
18591858
18601859void release_dbc (struct qaic_device * qdev , u32 dbc_id )
0 commit comments