@@ -813,7 +813,13 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
813813 num_buffers = max_t (unsigned int , * count , q -> min_buffers_needed );
814814 num_buffers = min_t (unsigned int , num_buffers , VB2_MAX_FRAME );
815815 memset (q -> alloc_devs , 0 , sizeof (q -> alloc_devs ));
816+ /*
817+ * Set this now to ensure that drivers see the correct q->memory value
818+ * in the queue_setup op.
819+ */
820+ mutex_lock (& q -> mmap_lock );
816821 q -> memory = memory ;
822+ mutex_unlock (& q -> mmap_lock );
817823 set_queue_coherency (q , non_coherent_mem );
818824
819825 /*
@@ -823,22 +829,27 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
823829 ret = call_qop (q , queue_setup , q , & num_buffers , & num_planes ,
824830 plane_sizes , q -> alloc_devs );
825831 if (ret )
826- return ret ;
832+ goto error ;
827833
828834 /* Check that driver has set sane values */
829- if (WARN_ON (!num_planes ))
830- return - EINVAL ;
835+ if (WARN_ON (!num_planes )) {
836+ ret = - EINVAL ;
837+ goto error ;
838+ }
831839
832840 for (i = 0 ; i < num_planes ; i ++ )
833- if (WARN_ON (!plane_sizes [i ]))
834- return - EINVAL ;
841+ if (WARN_ON (!plane_sizes [i ])) {
842+ ret = - EINVAL ;
843+ goto error ;
844+ }
835845
836846 /* Finally, allocate buffers and video memory */
837847 allocated_buffers =
838848 __vb2_queue_alloc (q , memory , num_buffers , num_planes , plane_sizes );
839849 if (allocated_buffers == 0 ) {
840850 dprintk (q , 1 , "memory allocation failed\n" );
841- return - ENOMEM ;
851+ ret = - ENOMEM ;
852+ goto error ;
842853 }
843854
844855 /*
@@ -879,7 +890,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
879890 if (ret < 0 ) {
880891 /*
881892 * Note: __vb2_queue_free() will subtract 'allocated_buffers'
882- * from q->num_buffers.
893+ * from q->num_buffers and it will reset q->memory to
894+ * VB2_MEMORY_UNKNOWN.
883895 */
884896 __vb2_queue_free (q , allocated_buffers );
885897 mutex_unlock (& q -> mmap_lock );
@@ -895,6 +907,12 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
895907 q -> waiting_for_buffers = !q -> is_output ;
896908
897909 return 0 ;
910+
911+ error :
912+ mutex_lock (& q -> mmap_lock );
913+ q -> memory = VB2_MEMORY_UNKNOWN ;
914+ mutex_unlock (& q -> mmap_lock );
915+ return ret ;
898916}
899917EXPORT_SYMBOL_GPL (vb2_core_reqbufs );
900918
@@ -906,20 +924,27 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
906924 unsigned int num_planes = 0 , num_buffers , allocated_buffers ;
907925 unsigned plane_sizes [VB2_MAX_PLANES ] = { };
908926 bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT ;
927+ bool no_previous_buffers = !q -> num_buffers ;
909928 int ret ;
910929
911930 if (q -> num_buffers == VB2_MAX_FRAME ) {
912931 dprintk (q , 1 , "maximum number of buffers already allocated\n" );
913932 return - ENOBUFS ;
914933 }
915934
916- if (! q -> num_buffers ) {
935+ if (no_previous_buffers ) {
917936 if (q -> waiting_in_dqbuf && * count ) {
918937 dprintk (q , 1 , "another dup()ped fd is waiting for a buffer\n" );
919938 return - EBUSY ;
920939 }
921940 memset (q -> alloc_devs , 0 , sizeof (q -> alloc_devs ));
941+ /*
942+ * Set this now to ensure that drivers see the correct q->memory
943+ * value in the queue_setup op.
944+ */
945+ mutex_lock (& q -> mmap_lock );
922946 q -> memory = memory ;
947+ mutex_unlock (& q -> mmap_lock );
923948 q -> waiting_for_buffers = !q -> is_output ;
924949 set_queue_coherency (q , non_coherent_mem );
925950 } else {
@@ -945,14 +970,15 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
945970 ret = call_qop (q , queue_setup , q , & num_buffers ,
946971 & num_planes , plane_sizes , q -> alloc_devs );
947972 if (ret )
948- return ret ;
973+ goto error ;
949974
950975 /* Finally, allocate buffers and video memory */
951976 allocated_buffers = __vb2_queue_alloc (q , memory , num_buffers ,
952977 num_planes , plane_sizes );
953978 if (allocated_buffers == 0 ) {
954979 dprintk (q , 1 , "memory allocation failed\n" );
955- return - ENOMEM ;
980+ ret = - ENOMEM ;
981+ goto error ;
956982 }
957983
958984 /*
@@ -983,7 +1009,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
9831009 if (ret < 0 ) {
9841010 /*
9851011 * Note: __vb2_queue_free() will subtract 'allocated_buffers'
986- * from q->num_buffers.
1012+ * from q->num_buffers and it will reset q->memory to
1013+ * VB2_MEMORY_UNKNOWN.
9871014 */
9881015 __vb2_queue_free (q , allocated_buffers );
9891016 mutex_unlock (& q -> mmap_lock );
@@ -998,6 +1025,14 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
9981025 * count = allocated_buffers ;
9991026
10001027 return 0 ;
1028+
1029+ error :
1030+ if (no_previous_buffers ) {
1031+ mutex_lock (& q -> mmap_lock );
1032+ q -> memory = VB2_MEMORY_UNKNOWN ;
1033+ mutex_unlock (& q -> mmap_lock );
1034+ }
1035+ return ret ;
10011036}
10021037EXPORT_SYMBOL_GPL (vb2_core_create_bufs );
10031038
@@ -2164,6 +2199,22 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
21642199 struct vb2_buffer * vb ;
21652200 unsigned int buffer , plane ;
21662201
2202+ /*
2203+ * Sanity checks to ensure the lock is held, MEMORY_MMAP is
2204+ * used and fileio isn't active.
2205+ */
2206+ lockdep_assert_held (& q -> mmap_lock );
2207+
2208+ if (q -> memory != VB2_MEMORY_MMAP ) {
2209+ dprintk (q , 1 , "queue is not currently set up for mmap\n" );
2210+ return - EINVAL ;
2211+ }
2212+
2213+ if (vb2_fileio_is_active (q )) {
2214+ dprintk (q , 1 , "file io in progress\n" );
2215+ return - EBUSY ;
2216+ }
2217+
21672218 /*
21682219 * Go over all buffers and their planes, comparing the given offset
21692220 * with an offset assigned to each plane. If a match is found,
@@ -2265,11 +2316,6 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
22652316 int ret ;
22662317 unsigned long length ;
22672318
2268- if (q -> memory != VB2_MEMORY_MMAP ) {
2269- dprintk (q , 1 , "queue is not currently set up for mmap\n" );
2270- return - EINVAL ;
2271- }
2272-
22732319 /*
22742320 * Check memory area access mode.
22752321 */
@@ -2291,14 +2337,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
22912337
22922338 mutex_lock (& q -> mmap_lock );
22932339
2294- if (vb2_fileio_is_active (q )) {
2295- dprintk (q , 1 , "mmap: file io in progress\n" );
2296- ret = - EBUSY ;
2297- goto unlock ;
2298- }
2299-
23002340 /*
2301- * Find the plane corresponding to the offset passed by userspace.
2341+ * Find the plane corresponding to the offset passed by userspace. This
2342+ * will return an error if not MEMORY_MMAP or file I/O is in progress.
23022343 */
23032344 ret = __find_plane_by_offset (q , off , & buffer , & plane );
23042345 if (ret )
@@ -2351,22 +2392,25 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
23512392 void * vaddr ;
23522393 int ret ;
23532394
2354- if (q -> memory != VB2_MEMORY_MMAP ) {
2355- dprintk (q , 1 , "queue is not currently set up for mmap\n" );
2356- return - EINVAL ;
2357- }
2395+ mutex_lock (& q -> mmap_lock );
23582396
23592397 /*
2360- * Find the plane corresponding to the offset passed by userspace.
2398+ * Find the plane corresponding to the offset passed by userspace. This
2399+ * will return an error if not MEMORY_MMAP or file I/O is in progress.
23612400 */
23622401 ret = __find_plane_by_offset (q , off , & buffer , & plane );
23632402 if (ret )
2364- return ret ;
2403+ goto unlock ;
23652404
23662405 vb = q -> bufs [buffer ];
23672406
23682407 vaddr = vb2_plane_vaddr (vb , plane );
2408+ mutex_unlock (& q -> mmap_lock );
23692409 return vaddr ? (unsigned long )vaddr : - EINVAL ;
2410+
2411+ unlock :
2412+ mutex_unlock (& q -> mmap_lock );
2413+ return ret ;
23702414}
23712415EXPORT_SYMBOL_GPL (vb2_get_unmapped_area );
23722416#endif
0 commit comments