1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
4  *	Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
5  *
6  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
7  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
8  * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs
9  * Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
10  * Copyright (C) 2005       Philippe De Muyter (phdm@macqel.be)
11  * Copyright (C) 2008       Hans Verkuil <hverkuil@xs4all.nl>
12  *
13  * These routines maintain argument size conversion between 32bit and 64bit
14  * ioctls.
15  */
16 
17 #include <linux/compat.h>
18 #include <linux/module.h>
19 #include <linux/videodev2.h>
20 #include <linux/v4l2-subdev.h>
21 #include <media/v4l2-dev.h>
22 #include <media/v4l2-fh.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-ioctl.h>
25 
26 /*
27  * Per-ioctl data copy handlers.
28  *
29  * Those come in pairs, with a get_v4l2_foo() and a put_v4l2_foo() routine,
30  * where "v4l2_foo" is the name of the V4L2 struct.
31  *
32  * They basically get two __user pointers, one with a 32-bits struct that
33  * came from the userspace call and a 64-bits struct, also allocated as
34  * userspace, but filled internally by do_video_ioctl().
35  *
36  * For ioctls that have pointers inside it, the functions will also
37  * receive an ancillary buffer with extra space, used to pass extra
38  * data to the routine.
39  */
40 
41 struct v4l2_clip32 {
42 	struct v4l2_rect        c;
43 	compat_caddr_t		next;
44 };
45 
46 struct v4l2_window32 {
47 	struct v4l2_rect        w;
48 	__u32			field;	/* enum v4l2_field */
49 	__u32			chromakey;
50 	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */
51 	__u32			clipcount;
52 	compat_caddr_t		bitmap;
53 	__u8                    global_alpha;
54 };
55 
56 static int get_v4l2_window32(struct v4l2_window *p64,
57 			     struct v4l2_window32 __user *p32)
58 {
59 	struct v4l2_window32 w32;
60 
61 	if (copy_from_user(&w32, p32, sizeof(w32)))
62 		return -EFAULT;
63 
64 	*p64 = (struct v4l2_window) {
65 		.w		= w32.w,
66 		.field		= w32.field,
67 		.chromakey	= w32.chromakey,
68 		.clips		= (void __force *)compat_ptr(w32.clips),
69 		.clipcount	= w32.clipcount,
70 		.bitmap		= compat_ptr(w32.bitmap),
71 		.global_alpha	= w32.global_alpha,
72 	};
73 
74 	if (p64->clipcount > 2048)
75 		return -EINVAL;
76 	if (!p64->clipcount)
77 		p64->clips = NULL;
78 
79 	return 0;
80 }
81 
82 static int put_v4l2_window32(struct v4l2_window *p64,
83 			     struct v4l2_window32 __user *p32)
84 {
85 	struct v4l2_window32 w32;
86 
87 	memset(&w32, 0, sizeof(w32));
88 	w32 = (struct v4l2_window32) {
89 		.w		= p64->w,
90 		.field		= p64->field,
91 		.chromakey	= p64->chromakey,
92 		.clips		= (uintptr_t)p64->clips,
93 		.clipcount	= p64->clipcount,
94 		.bitmap		= ptr_to_compat(p64->bitmap),
95 		.global_alpha	= p64->global_alpha,
96 	};
97 
98 	/* copy everything except the clips pointer */
99 	if (copy_to_user(p32, &w32, offsetof(struct v4l2_window32, clips)) ||
100 	    copy_to_user(&p32->clipcount, &w32.clipcount,
101 			 sizeof(w32) - offsetof(struct v4l2_window32, clipcount)))
102 		return -EFAULT;
103 
104 	return 0;
105 }
106 
107 struct v4l2_format32 {
108 	__u32	type;	/* enum v4l2_buf_type */
109 	union {
110 		struct v4l2_pix_format	pix;
111 		struct v4l2_pix_format_mplane	pix_mp;
112 		struct v4l2_window32	win;
113 		struct v4l2_vbi_format	vbi;
114 		struct v4l2_sliced_vbi_format	sliced;
115 		struct v4l2_sdr_format	sdr;
116 		struct v4l2_meta_format	meta;
117 		__u8	raw_data[200];        /* user-defined */
118 	} fmt;
119 };
120 
121 /**
122  * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
123  * @index:	on return, index of the first created buffer
124  * @count:	entry: number of requested buffers,
125  *		return: number of created buffers
126  * @memory:	buffer memory type
127  * @format:	frame format, for which buffers are requested
128  * @capabilities: capabilities of this buffer type.
129  * @flags:	additional buffer management attributes (ignored unless the
130  *		queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability and
131  *		configured for MMAP streaming I/O).
132  * @reserved:	future extensions
133  */
134 struct v4l2_create_buffers32 {
135 	__u32			index;
136 	__u32			count;
137 	__u32			memory;	/* enum v4l2_memory */
138 	struct v4l2_format32	format;
139 	__u32			capabilities;
140 	__u32			flags;
141 	__u32			reserved[6];
142 };
143 
144 static int get_v4l2_format32(struct v4l2_format *p64,
145 			     struct v4l2_format32 __user *p32)
146 {
147 	if (get_user(p64->type, &p32->type))
148 		return -EFAULT;
149 
150 	switch (p64->type) {
151 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
152 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
153 		return copy_from_user(&p64->fmt.pix, &p32->fmt.pix,
154 				      sizeof(p64->fmt.pix)) ? -EFAULT : 0;
155 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
156 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
157 		return copy_from_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp,
158 				      sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
159 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
160 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
161 		return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
162 	case V4L2_BUF_TYPE_VBI_CAPTURE:
163 	case V4L2_BUF_TYPE_VBI_OUTPUT:
164 		return copy_from_user(&p64->fmt.vbi, &p32->fmt.vbi,
165 				      sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
166 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
167 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
168 		return copy_from_user(&p64->fmt.sliced, &p32->fmt.sliced,
169 				      sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
170 	case V4L2_BUF_TYPE_SDR_CAPTURE:
171 	case V4L2_BUF_TYPE_SDR_OUTPUT:
172 		return copy_from_user(&p64->fmt.sdr, &p32->fmt.sdr,
173 				      sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
174 	case V4L2_BUF_TYPE_META_CAPTURE:
175 	case V4L2_BUF_TYPE_META_OUTPUT:
176 		return copy_from_user(&p64->fmt.meta, &p32->fmt.meta,
177 				      sizeof(p64->fmt.meta)) ? -EFAULT : 0;
178 	default:
179 		return -EINVAL;
180 	}
181 }
182 
183 static int get_v4l2_create32(struct v4l2_create_buffers *p64,
184 			     struct v4l2_create_buffers32 __user *p32)
185 {
186 	if (copy_from_user(p64, p32,
187 			   offsetof(struct v4l2_create_buffers32, format)))
188 		return -EFAULT;
189 	if (copy_from_user(&p64->flags, &p32->flags, sizeof(p32->flags)))
190 		return -EFAULT;
191 	return get_v4l2_format32(&p64->format, &p32->format);
192 }
193 
194 static int put_v4l2_format32(struct v4l2_format *p64,
195 			     struct v4l2_format32 __user *p32)
196 {
197 	switch (p64->type) {
198 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
199 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
200 		return copy_to_user(&p32->fmt.pix, &p64->fmt.pix,
201 				    sizeof(p64->fmt.pix)) ? -EFAULT : 0;
202 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
203 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
204 		return copy_to_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp,
205 				    sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
206 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
207 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
208 		return put_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
209 	case V4L2_BUF_TYPE_VBI_CAPTURE:
210 	case V4L2_BUF_TYPE_VBI_OUTPUT:
211 		return copy_to_user(&p32->fmt.vbi, &p64->fmt.vbi,
212 				    sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
213 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
214 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
215 		return copy_to_user(&p32->fmt.sliced, &p64->fmt.sliced,
216 				    sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
217 	case V4L2_BUF_TYPE_SDR_CAPTURE:
218 	case V4L2_BUF_TYPE_SDR_OUTPUT:
219 		return copy_to_user(&p32->fmt.sdr, &p64->fmt.sdr,
220 				    sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
221 	case V4L2_BUF_TYPE_META_CAPTURE:
222 	case V4L2_BUF_TYPE_META_OUTPUT:
223 		return copy_to_user(&p32->fmt.meta, &p64->fmt.meta,
224 				    sizeof(p64->fmt.meta)) ? -EFAULT : 0;
225 	default:
226 		return -EINVAL;
227 	}
228 }
229 
230 static int put_v4l2_create32(struct v4l2_create_buffers *p64,
231 			     struct v4l2_create_buffers32 __user *p32)
232 {
233 	if (copy_to_user(p32, p64,
234 			 offsetof(struct v4l2_create_buffers32, format)) ||
235 	    put_user(p64->capabilities, &p32->capabilities) ||
236 	    put_user(p64->flags, &p32->flags) ||
237 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
238 		return -EFAULT;
239 	return put_v4l2_format32(&p64->format, &p32->format);
240 }
241 
242 struct v4l2_standard32 {
243 	__u32		     index;
244 	compat_u64	     id;
245 	__u8		     name[24];
246 	struct v4l2_fract    frameperiod; /* Frames, not fields */
247 	__u32		     framelines;
248 	__u32		     reserved[4];
249 };
250 
251 static int get_v4l2_standard32(struct v4l2_standard *p64,
252 			       struct v4l2_standard32 __user *p32)
253 {
254 	/* other fields are not set by the user, nor used by the driver */
255 	return get_user(p64->index, &p32->index);
256 }
257 
258 static int put_v4l2_standard32(struct v4l2_standard *p64,
259 			       struct v4l2_standard32 __user *p32)
260 {
261 	if (put_user(p64->index, &p32->index) ||
262 	    put_user(p64->id, &p32->id) ||
263 	    copy_to_user(p32->name, p64->name, sizeof(p32->name)) ||
264 	    copy_to_user(&p32->frameperiod, &p64->frameperiod,
265 			 sizeof(p32->frameperiod)) ||
266 	    put_user(p64->framelines, &p32->framelines) ||
267 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
268 		return -EFAULT;
269 	return 0;
270 }
271 
272 struct v4l2_plane32 {
273 	__u32			bytesused;
274 	__u32			length;
275 	union {
276 		__u32		mem_offset;
277 		compat_long_t	userptr;
278 		__s32		fd;
279 	} m;
280 	__u32			data_offset;
281 	__u32			reserved[11];
282 };
283 
284 /*
285  * This is correct for all architectures including i386, but not x32,
286  * which has different alignment requirements for timestamp
287  */
288 struct v4l2_buffer32 {
289 	__u32			index;
290 	__u32			type;	/* enum v4l2_buf_type */
291 	__u32			bytesused;
292 	__u32			flags;
293 	__u32			field;	/* enum v4l2_field */
294 	struct {
295 		compat_s64	tv_sec;
296 		compat_s64	tv_usec;
297 	}			timestamp;
298 	struct v4l2_timecode	timecode;
299 	__u32			sequence;
300 
301 	/* memory location */
302 	__u32			memory;	/* enum v4l2_memory */
303 	union {
304 		__u32           offset;
305 		compat_long_t   userptr;
306 		compat_caddr_t  planes;
307 		__s32		fd;
308 	} m;
309 	__u32			length;
310 	__u32			reserved2;
311 	__s32			request_fd;
312 };
313 
314 #ifdef CONFIG_COMPAT_32BIT_TIME
315 struct v4l2_buffer32_time32 {
316 	__u32			index;
317 	__u32			type;	/* enum v4l2_buf_type */
318 	__u32			bytesused;
319 	__u32			flags;
320 	__u32			field;	/* enum v4l2_field */
321 	struct old_timeval32	timestamp;
322 	struct v4l2_timecode	timecode;
323 	__u32			sequence;
324 
325 	/* memory location */
326 	__u32			memory;	/* enum v4l2_memory */
327 	union {
328 		__u32           offset;
329 		compat_long_t   userptr;
330 		compat_caddr_t  planes;
331 		__s32		fd;
332 	} m;
333 	__u32			length;
334 	__u32			reserved2;
335 	__s32			request_fd;
336 };
337 #endif
338 
339 static int get_v4l2_plane32(struct v4l2_plane *p64,
340 			    struct v4l2_plane32 __user *p32,
341 			    enum v4l2_memory memory)
342 {
343 	struct v4l2_plane32 plane32;
344 	typeof(p64->m) m = {};
345 
346 	if (copy_from_user(&plane32, p32, sizeof(plane32)))
347 		return -EFAULT;
348 
349 	switch (memory) {
350 	case V4L2_MEMORY_MMAP:
351 	case V4L2_MEMORY_OVERLAY:
352 		m.mem_offset = plane32.m.mem_offset;
353 		break;
354 	case V4L2_MEMORY_USERPTR:
355 		m.userptr = (unsigned long)compat_ptr(plane32.m.userptr);
356 		break;
357 	case V4L2_MEMORY_DMABUF:
358 		m.fd = plane32.m.fd;
359 		break;
360 	}
361 
362 	memset(p64, 0, sizeof(*p64));
363 	*p64 = (struct v4l2_plane) {
364 		.bytesused	= plane32.bytesused,
365 		.length		= plane32.length,
366 		.m		= m,
367 		.data_offset	= plane32.data_offset,
368 	};
369 
370 	return 0;
371 }
372 
373 static int put_v4l2_plane32(struct v4l2_plane *p64,
374 			    struct v4l2_plane32 __user *p32,
375 			    enum v4l2_memory memory)
376 {
377 	struct v4l2_plane32 plane32;
378 
379 	memset(&plane32, 0, sizeof(plane32));
380 	plane32 = (struct v4l2_plane32) {
381 		.bytesused	= p64->bytesused,
382 		.length		= p64->length,
383 		.data_offset	= p64->data_offset,
384 	};
385 
386 	switch (memory) {
387 	case V4L2_MEMORY_MMAP:
388 	case V4L2_MEMORY_OVERLAY:
389 		plane32.m.mem_offset = p64->m.mem_offset;
390 		break;
391 	case V4L2_MEMORY_USERPTR:
392 		plane32.m.userptr = (uintptr_t)(p64->m.userptr);
393 		break;
394 	case V4L2_MEMORY_DMABUF:
395 		plane32.m.fd = p64->m.fd;
396 		break;
397 	}
398 
399 	if (copy_to_user(p32, &plane32, sizeof(plane32)))
400 		return -EFAULT;
401 
402 	return 0;
403 }
404 
405 static int get_v4l2_buffer32(struct v4l2_buffer *vb,
406 			     struct v4l2_buffer32 __user *arg)
407 {
408 	struct v4l2_buffer32 vb32;
409 
410 	if (copy_from_user(&vb32, arg, sizeof(vb32)))
411 		return -EFAULT;
412 
413 	memset(vb, 0, sizeof(*vb));
414 	*vb = (struct v4l2_buffer) {
415 		.index		= vb32.index,
416 		.type		= vb32.type,
417 		.bytesused	= vb32.bytesused,
418 		.flags		= vb32.flags,
419 		.field		= vb32.field,
420 		.timestamp.tv_sec	= vb32.timestamp.tv_sec,
421 		.timestamp.tv_usec	= vb32.timestamp.tv_usec,
422 		.timecode	= vb32.timecode,
423 		.sequence	= vb32.sequence,
424 		.memory		= vb32.memory,
425 		.m.offset	= vb32.m.offset,
426 		.length		= vb32.length,
427 		.request_fd	= vb32.request_fd,
428 	};
429 
430 	switch (vb->memory) {
431 	case V4L2_MEMORY_MMAP:
432 	case V4L2_MEMORY_OVERLAY:
433 		vb->m.offset = vb32.m.offset;
434 		break;
435 	case V4L2_MEMORY_USERPTR:
436 		vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr);
437 		break;
438 	case V4L2_MEMORY_DMABUF:
439 		vb->m.fd = vb32.m.fd;
440 		break;
441 	}
442 
443 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
444 		vb->m.planes = (void __force *)
445 				compat_ptr(vb32.m.planes);
446 
447 	return 0;
448 }
449 
450 #ifdef CONFIG_COMPAT_32BIT_TIME
451 static int get_v4l2_buffer32_time32(struct v4l2_buffer *vb,
452 				    struct v4l2_buffer32_time32 __user *arg)
453 {
454 	struct v4l2_buffer32_time32 vb32;
455 
456 	if (copy_from_user(&vb32, arg, sizeof(vb32)))
457 		return -EFAULT;
458 
459 	*vb = (struct v4l2_buffer) {
460 		.index		= vb32.index,
461 		.type		= vb32.type,
462 		.bytesused	= vb32.bytesused,
463 		.flags		= vb32.flags,
464 		.field		= vb32.field,
465 		.timestamp.tv_sec	= vb32.timestamp.tv_sec,
466 		.timestamp.tv_usec	= vb32.timestamp.tv_usec,
467 		.timecode	= vb32.timecode,
468 		.sequence	= vb32.sequence,
469 		.memory		= vb32.memory,
470 		.m.offset	= vb32.m.offset,
471 		.length		= vb32.length,
472 		.request_fd	= vb32.request_fd,
473 	};
474 	switch (vb->memory) {
475 	case V4L2_MEMORY_MMAP:
476 	case V4L2_MEMORY_OVERLAY:
477 		vb->m.offset = vb32.m.offset;
478 		break;
479 	case V4L2_MEMORY_USERPTR:
480 		vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr);
481 		break;
482 	case V4L2_MEMORY_DMABUF:
483 		vb->m.fd = vb32.m.fd;
484 		break;
485 	}
486 
487 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
488 		vb->m.planes = (void __force *)
489 				compat_ptr(vb32.m.planes);
490 
491 	return 0;
492 }
493 #endif
494 
495 static int put_v4l2_buffer32(struct v4l2_buffer *vb,
496 			     struct v4l2_buffer32 __user *arg)
497 {
498 	struct v4l2_buffer32 vb32;
499 
500 	memset(&vb32, 0, sizeof(vb32));
501 	vb32 = (struct v4l2_buffer32) {
502 		.index		= vb->index,
503 		.type		= vb->type,
504 		.bytesused	= vb->bytesused,
505 		.flags		= vb->flags,
506 		.field		= vb->field,
507 		.timestamp.tv_sec	= vb->timestamp.tv_sec,
508 		.timestamp.tv_usec	= vb->timestamp.tv_usec,
509 		.timecode	= vb->timecode,
510 		.sequence	= vb->sequence,
511 		.memory		= vb->memory,
512 		.m.offset	= vb->m.offset,
513 		.length		= vb->length,
514 		.request_fd	= vb->request_fd,
515 	};
516 
517 	switch (vb->memory) {
518 	case V4L2_MEMORY_MMAP:
519 	case V4L2_MEMORY_OVERLAY:
520 		vb32.m.offset = vb->m.offset;
521 		break;
522 	case V4L2_MEMORY_USERPTR:
523 		vb32.m.userptr = (uintptr_t)(vb->m.userptr);
524 		break;
525 	case V4L2_MEMORY_DMABUF:
526 		vb32.m.fd = vb->m.fd;
527 		break;
528 	}
529 
530 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
531 		vb32.m.planes = (uintptr_t)vb->m.planes;
532 
533 	if (copy_to_user(arg, &vb32, sizeof(vb32)))
534 		return -EFAULT;
535 
536 	return 0;
537 }
538 
539 #ifdef CONFIG_COMPAT_32BIT_TIME
540 static int put_v4l2_buffer32_time32(struct v4l2_buffer *vb,
541 				    struct v4l2_buffer32_time32 __user *arg)
542 {
543 	struct v4l2_buffer32_time32 vb32;
544 
545 	memset(&vb32, 0, sizeof(vb32));
546 	vb32 = (struct v4l2_buffer32_time32) {
547 		.index		= vb->index,
548 		.type		= vb->type,
549 		.bytesused	= vb->bytesused,
550 		.flags		= vb->flags,
551 		.field		= vb->field,
552 		.timestamp.tv_sec	= vb->timestamp.tv_sec,
553 		.timestamp.tv_usec	= vb->timestamp.tv_usec,
554 		.timecode	= vb->timecode,
555 		.sequence	= vb->sequence,
556 		.memory		= vb->memory,
557 		.m.offset	= vb->m.offset,
558 		.length		= vb->length,
559 		.request_fd	= vb->request_fd,
560 	};
561 	switch (vb->memory) {
562 	case V4L2_MEMORY_MMAP:
563 	case V4L2_MEMORY_OVERLAY:
564 		vb32.m.offset = vb->m.offset;
565 		break;
566 	case V4L2_MEMORY_USERPTR:
567 		vb32.m.userptr = (uintptr_t)(vb->m.userptr);
568 		break;
569 	case V4L2_MEMORY_DMABUF:
570 		vb32.m.fd = vb->m.fd;
571 		break;
572 	}
573 
574 	if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
575 		vb32.m.planes = (uintptr_t)vb->m.planes;
576 
577 	if (copy_to_user(arg, &vb32, sizeof(vb32)))
578 		return -EFAULT;
579 
580 	return 0;
581 }
582 #endif
583 
584 struct v4l2_framebuffer32 {
585 	__u32			capability;
586 	__u32			flags;
587 	compat_caddr_t		base;
588 	struct {
589 		__u32		width;
590 		__u32		height;
591 		__u32		pixelformat;
592 		__u32		field;
593 		__u32		bytesperline;
594 		__u32		sizeimage;
595 		__u32		colorspace;
596 		__u32		priv;
597 	} fmt;
598 };
599 
600 static int get_v4l2_framebuffer32(struct v4l2_framebuffer *p64,
601 				  struct v4l2_framebuffer32 __user *p32)
602 {
603 	compat_caddr_t tmp;
604 
605 	if (get_user(tmp, &p32->base) ||
606 	    get_user(p64->capability, &p32->capability) ||
607 	    get_user(p64->flags, &p32->flags) ||
608 	    copy_from_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt)))
609 		return -EFAULT;
610 	p64->base = (void __force *)compat_ptr(tmp);
611 
612 	return 0;
613 }
614 
615 static int put_v4l2_framebuffer32(struct v4l2_framebuffer *p64,
616 				  struct v4l2_framebuffer32 __user *p32)
617 {
618 	if (put_user((uintptr_t)p64->base, &p32->base) ||
619 	    put_user(p64->capability, &p32->capability) ||
620 	    put_user(p64->flags, &p32->flags) ||
621 	    copy_to_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt)))
622 		return -EFAULT;
623 
624 	return 0;
625 }
626 
627 struct v4l2_input32 {
628 	__u32	     index;		/*  Which input */
629 	__u8	     name[32];		/*  Label */
630 	__u32	     type;		/*  Type of input */
631 	__u32	     audioset;		/*  Associated audios (bitfield) */
632 	__u32        tuner;             /*  Associated tuner */
633 	compat_u64   std;
634 	__u32	     status;
635 	__u32	     capabilities;
636 	__u32	     reserved[3];
637 };
638 
639 /*
640  * The 64-bit v4l2_input struct has extra padding at the end of the struct.
641  * Otherwise it is identical to the 32-bit version.
642  */
643 static inline int get_v4l2_input32(struct v4l2_input *p64,
644 				   struct v4l2_input32 __user *p32)
645 {
646 	if (copy_from_user(p64, p32, sizeof(*p32)))
647 		return -EFAULT;
648 	return 0;
649 }
650 
651 static inline int put_v4l2_input32(struct v4l2_input *p64,
652 				   struct v4l2_input32 __user *p32)
653 {
654 	if (copy_to_user(p32, p64, sizeof(*p32)))
655 		return -EFAULT;
656 	return 0;
657 }
658 
659 struct v4l2_ext_controls32 {
660 	__u32 which;
661 	__u32 count;
662 	__u32 error_idx;
663 	__s32 request_fd;
664 	__u32 reserved[1];
665 	compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
666 };
667 
668 struct v4l2_ext_control32 {
669 	__u32 id;
670 	__u32 size;
671 	__u32 reserved2[1];
672 	union {
673 		__s32 value;
674 		__s64 value64;
675 		compat_caddr_t string; /* actually char * */
676 	};
677 } __attribute__ ((packed));
678 
679 /* Return true if this control is a pointer type. */
680 static inline bool ctrl_is_pointer(struct file *file, u32 id)
681 {
682 	struct video_device *vdev = video_devdata(file);
683 	struct v4l2_fh *fh = NULL;
684 	struct v4l2_ctrl_handler *hdl = NULL;
685 	struct v4l2_query_ext_ctrl qec = { id };
686 	const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
687 
688 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
689 		fh = file->private_data;
690 
691 	if (fh && fh->ctrl_handler)
692 		hdl = fh->ctrl_handler;
693 	else if (vdev->ctrl_handler)
694 		hdl = vdev->ctrl_handler;
695 
696 	if (hdl) {
697 		struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
698 
699 		return ctrl && ctrl->is_ptr;
700 	}
701 
702 	if (!ops || !ops->vidioc_query_ext_ctrl)
703 		return false;
704 
705 	return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
706 		(qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
707 }
708 
709 static int get_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
710 				   struct v4l2_ext_controls32 __user *p32)
711 {
712 	struct v4l2_ext_controls32 ec32;
713 
714 	if (copy_from_user(&ec32, p32, sizeof(ec32)))
715 		return -EFAULT;
716 
717 	*p64 = (struct v4l2_ext_controls) {
718 		.which		= ec32.which,
719 		.count		= ec32.count,
720 		.error_idx	= ec32.error_idx,
721 		.request_fd	= ec32.request_fd,
722 		.reserved[0]	= ec32.reserved[0],
723 		.controls	= (void __force *)compat_ptr(ec32.controls),
724 	};
725 
726 	return 0;
727 }
728 
729 static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
730 				   struct v4l2_ext_controls32 __user *p32)
731 {
732 	struct v4l2_ext_controls32 ec32;
733 
734 	memset(&ec32, 0, sizeof(ec32));
735 	ec32 = (struct v4l2_ext_controls32) {
736 		.which		= p64->which,
737 		.count		= p64->count,
738 		.error_idx	= p64->error_idx,
739 		.request_fd	= p64->request_fd,
740 		.reserved[0]	= p64->reserved[0],
741 		.controls	= (uintptr_t)p64->controls,
742 	};
743 
744 	if (copy_to_user(p32, &ec32, sizeof(ec32)))
745 		return -EFAULT;
746 
747 	return 0;
748 }
749 
750 #ifdef CONFIG_X86_64
751 /*
752  * x86 is the only compat architecture with different struct alignment
753  * between 32-bit and 64-bit tasks.
754  *
755  * On all other architectures, v4l2_event32 and v4l2_event32_time32 are
756  * the same as v4l2_event and v4l2_event_time32, so we can use the native
757  * handlers, converting v4l2_event to v4l2_event_time32 if necessary.
758  */
759 struct v4l2_event32 {
760 	__u32				type;
761 	union {
762 		compat_s64		value64;
763 		__u8			data[64];
764 	} u;
765 	__u32				pending;
766 	__u32				sequence;
767 	struct {
768 		compat_s64		tv_sec;
769 		compat_s64		tv_nsec;
770 	} timestamp;
771 	__u32				id;
772 	__u32				reserved[8];
773 };
774 
775 #ifdef CONFIG_COMPAT_32BIT_TIME
776 struct v4l2_event32_time32 {
777 	__u32				type;
778 	union {
779 		compat_s64		value64;
780 		__u8			data[64];
781 	} u;
782 	__u32				pending;
783 	__u32				sequence;
784 	struct old_timespec32		timestamp;
785 	__u32				id;
786 	__u32				reserved[8];
787 };
788 #endif
789 
790 static int put_v4l2_event32(struct v4l2_event *p64,
791 			    struct v4l2_event32 __user *p32)
792 {
793 	if (put_user(p64->type, &p32->type) ||
794 	    copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) ||
795 	    put_user(p64->pending, &p32->pending) ||
796 	    put_user(p64->sequence, &p32->sequence) ||
797 	    put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) ||
798 	    put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) ||
799 	    put_user(p64->id, &p32->id) ||
800 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
801 		return -EFAULT;
802 	return 0;
803 }
804 
805 #ifdef CONFIG_COMPAT_32BIT_TIME
806 static int put_v4l2_event32_time32(struct v4l2_event *p64,
807 				   struct v4l2_event32_time32 __user *p32)
808 {
809 	if (put_user(p64->type, &p32->type) ||
810 	    copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) ||
811 	    put_user(p64->pending, &p32->pending) ||
812 	    put_user(p64->sequence, &p32->sequence) ||
813 	    put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) ||
814 	    put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) ||
815 	    put_user(p64->id, &p32->id) ||
816 	    copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
817 		return -EFAULT;
818 	return 0;
819 }
820 #endif
821 #endif
822 
823 struct v4l2_edid32 {
824 	__u32 pad;
825 	__u32 start_block;
826 	__u32 blocks;
827 	__u32 reserved[5];
828 	compat_caddr_t edid;
829 };
830 
831 static int get_v4l2_edid32(struct v4l2_edid *p64,
832 			   struct v4l2_edid32 __user *p32)
833 {
834 	compat_uptr_t edid;
835 
836 	if (copy_from_user(p64, p32, offsetof(struct v4l2_edid32, edid)) ||
837 	    get_user(edid, &p32->edid))
838 		return -EFAULT;
839 
840 	p64->edid = (void __force *)compat_ptr(edid);
841 	return 0;
842 }
843 
844 static int put_v4l2_edid32(struct v4l2_edid *p64,
845 			   struct v4l2_edid32 __user *p32)
846 {
847 	if (copy_to_user(p32, p64, offsetof(struct v4l2_edid32, edid)))
848 		return -EFAULT;
849 	return 0;
850 }
851 
852 /*
853  * List of ioctls that require 32-bits/64-bits conversion
854  *
855  * The V4L2 ioctls that aren't listed there don't have pointer arguments
856  * and the struct size is identical for both 32 and 64 bits versions, so
857  * they don't need translations.
858  */
859 
860 #define VIDIOC_G_FMT32		_IOWR('V',  4, struct v4l2_format32)
861 #define VIDIOC_S_FMT32		_IOWR('V',  5, struct v4l2_format32)
862 #define VIDIOC_QUERYBUF32	_IOWR('V',  9, struct v4l2_buffer32)
863 #define VIDIOC_G_FBUF32		_IOR ('V', 10, struct v4l2_framebuffer32)
864 #define VIDIOC_S_FBUF32		_IOW ('V', 11, struct v4l2_framebuffer32)
865 #define VIDIOC_QBUF32		_IOWR('V', 15, struct v4l2_buffer32)
866 #define VIDIOC_DQBUF32		_IOWR('V', 17, struct v4l2_buffer32)
867 #define VIDIOC_ENUMSTD32	_IOWR('V', 25, struct v4l2_standard32)
868 #define VIDIOC_ENUMINPUT32	_IOWR('V', 26, struct v4l2_input32)
869 #define VIDIOC_G_EDID32		_IOWR('V', 40, struct v4l2_edid32)
870 #define VIDIOC_S_EDID32		_IOWR('V', 41, struct v4l2_edid32)
871 #define VIDIOC_TRY_FMT32	_IOWR('V', 64, struct v4l2_format32)
872 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
873 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
874 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
875 #define	VIDIOC_DQEVENT32	_IOR ('V', 89, struct v4l2_event32)
876 #define VIDIOC_CREATE_BUFS32	_IOWR('V', 92, struct v4l2_create_buffers32)
877 #define VIDIOC_PREPARE_BUF32	_IOWR('V', 93, struct v4l2_buffer32)
878 
879 #ifdef CONFIG_COMPAT_32BIT_TIME
880 #define VIDIOC_QUERYBUF32_TIME32	_IOWR('V',  9, struct v4l2_buffer32_time32)
881 #define VIDIOC_QBUF32_TIME32		_IOWR('V', 15, struct v4l2_buffer32_time32)
882 #define VIDIOC_DQBUF32_TIME32		_IOWR('V', 17, struct v4l2_buffer32_time32)
883 #ifdef CONFIG_X86_64
884 #define	VIDIOC_DQEVENT32_TIME32		_IOR ('V', 89, struct v4l2_event32_time32)
885 #endif
886 #define VIDIOC_PREPARE_BUF32_TIME32	_IOWR('V', 93, struct v4l2_buffer32_time32)
887 #endif
888 
889 unsigned int v4l2_compat_translate_cmd(unsigned int cmd)
890 {
891 	switch (cmd) {
892 	case VIDIOC_G_FMT32:
893 		return VIDIOC_G_FMT;
894 	case VIDIOC_S_FMT32:
895 		return VIDIOC_S_FMT;
896 	case VIDIOC_TRY_FMT32:
897 		return VIDIOC_TRY_FMT;
898 	case VIDIOC_G_FBUF32:
899 		return VIDIOC_G_FBUF;
900 	case VIDIOC_S_FBUF32:
901 		return VIDIOC_S_FBUF;
902 #ifdef CONFIG_COMPAT_32BIT_TIME
903 	case VIDIOC_QUERYBUF32_TIME32:
904 		return VIDIOC_QUERYBUF;
905 	case VIDIOC_QBUF32_TIME32:
906 		return VIDIOC_QBUF;
907 	case VIDIOC_DQBUF32_TIME32:
908 		return VIDIOC_DQBUF;
909 	case VIDIOC_PREPARE_BUF32_TIME32:
910 		return VIDIOC_PREPARE_BUF;
911 #endif
912 	case VIDIOC_QUERYBUF32:
913 		return VIDIOC_QUERYBUF;
914 	case VIDIOC_QBUF32:
915 		return VIDIOC_QBUF;
916 	case VIDIOC_DQBUF32:
917 		return VIDIOC_DQBUF;
918 	case VIDIOC_CREATE_BUFS32:
919 		return VIDIOC_CREATE_BUFS;
920 	case VIDIOC_G_EXT_CTRLS32:
921 		return VIDIOC_G_EXT_CTRLS;
922 	case VIDIOC_S_EXT_CTRLS32:
923 		return VIDIOC_S_EXT_CTRLS;
924 	case VIDIOC_TRY_EXT_CTRLS32:
925 		return VIDIOC_TRY_EXT_CTRLS;
926 	case VIDIOC_PREPARE_BUF32:
927 		return VIDIOC_PREPARE_BUF;
928 	case VIDIOC_ENUMSTD32:
929 		return VIDIOC_ENUMSTD;
930 	case VIDIOC_ENUMINPUT32:
931 		return VIDIOC_ENUMINPUT;
932 	case VIDIOC_G_EDID32:
933 		return VIDIOC_G_EDID;
934 	case VIDIOC_S_EDID32:
935 		return VIDIOC_S_EDID;
936 #ifdef CONFIG_X86_64
937 	case VIDIOC_DQEVENT32:
938 		return VIDIOC_DQEVENT;
939 #ifdef CONFIG_COMPAT_32BIT_TIME
940 	case VIDIOC_DQEVENT32_TIME32:
941 		return VIDIOC_DQEVENT;
942 #endif
943 #endif
944 	}
945 	return cmd;
946 }
947 
948 int v4l2_compat_get_user(void __user *arg, void *parg, unsigned int cmd)
949 {
950 	switch (cmd) {
951 	case VIDIOC_G_FMT32:
952 	case VIDIOC_S_FMT32:
953 	case VIDIOC_TRY_FMT32:
954 		return get_v4l2_format32(parg, arg);
955 
956 	case VIDIOC_S_FBUF32:
957 		return get_v4l2_framebuffer32(parg, arg);
958 #ifdef CONFIG_COMPAT_32BIT_TIME
959 	case VIDIOC_QUERYBUF32_TIME32:
960 	case VIDIOC_QBUF32_TIME32:
961 	case VIDIOC_DQBUF32_TIME32:
962 	case VIDIOC_PREPARE_BUF32_TIME32:
963 		return get_v4l2_buffer32_time32(parg, arg);
964 #endif
965 	case VIDIOC_QUERYBUF32:
966 	case VIDIOC_QBUF32:
967 	case VIDIOC_DQBUF32:
968 	case VIDIOC_PREPARE_BUF32:
969 		return get_v4l2_buffer32(parg, arg);
970 
971 	case VIDIOC_G_EXT_CTRLS32:
972 	case VIDIOC_S_EXT_CTRLS32:
973 	case VIDIOC_TRY_EXT_CTRLS32:
974 		return get_v4l2_ext_controls32(parg, arg);
975 
976 	case VIDIOC_CREATE_BUFS32:
977 		return get_v4l2_create32(parg, arg);
978 
979 	case VIDIOC_ENUMSTD32:
980 		return get_v4l2_standard32(parg, arg);
981 
982 	case VIDIOC_ENUMINPUT32:
983 		return get_v4l2_input32(parg, arg);
984 
985 	case VIDIOC_G_EDID32:
986 	case VIDIOC_S_EDID32:
987 		return get_v4l2_edid32(parg, arg);
988 	}
989 	return 0;
990 }
991 
992 int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd)
993 {
994 	switch (cmd) {
995 	case VIDIOC_G_FMT32:
996 	case VIDIOC_S_FMT32:
997 	case VIDIOC_TRY_FMT32:
998 		return put_v4l2_format32(parg, arg);
999 
1000 	case VIDIOC_G_FBUF32:
1001 		return put_v4l2_framebuffer32(parg, arg);
1002 #ifdef CONFIG_COMPAT_32BIT_TIME
1003 	case VIDIOC_QUERYBUF32_TIME32:
1004 	case VIDIOC_QBUF32_TIME32:
1005 	case VIDIOC_DQBUF32_TIME32:
1006 	case VIDIOC_PREPARE_BUF32_TIME32:
1007 		return put_v4l2_buffer32_time32(parg, arg);
1008 #endif
1009 	case VIDIOC_QUERYBUF32:
1010 	case VIDIOC_QBUF32:
1011 	case VIDIOC_DQBUF32:
1012 	case VIDIOC_PREPARE_BUF32:
1013 		return put_v4l2_buffer32(parg, arg);
1014 
1015 	case VIDIOC_G_EXT_CTRLS32:
1016 	case VIDIOC_S_EXT_CTRLS32:
1017 	case VIDIOC_TRY_EXT_CTRLS32:
1018 		return put_v4l2_ext_controls32(parg, arg);
1019 
1020 	case VIDIOC_CREATE_BUFS32:
1021 		return put_v4l2_create32(parg, arg);
1022 
1023 	case VIDIOC_ENUMSTD32:
1024 		return put_v4l2_standard32(parg, arg);
1025 
1026 	case VIDIOC_ENUMINPUT32:
1027 		return put_v4l2_input32(parg, arg);
1028 
1029 	case VIDIOC_G_EDID32:
1030 	case VIDIOC_S_EDID32:
1031 		return put_v4l2_edid32(parg, arg);
1032 #ifdef CONFIG_X86_64
1033 	case VIDIOC_DQEVENT32:
1034 		return put_v4l2_event32(parg, arg);
1035 #ifdef CONFIG_COMPAT_32BIT_TIME
1036 	case VIDIOC_DQEVENT32_TIME32:
1037 		return put_v4l2_event32_time32(parg, arg);
1038 #endif
1039 #endif
1040 	}
1041 	return 0;
1042 }
1043 
1044 int v4l2_compat_get_array_args(struct file *file, void *mbuf,
1045 			       void __user *user_ptr, size_t array_size,
1046 			       unsigned int cmd, void *arg)
1047 {
1048 	int err = 0;
1049 
1050 	switch (cmd) {
1051 	case VIDIOC_G_FMT32:
1052 	case VIDIOC_S_FMT32:
1053 	case VIDIOC_TRY_FMT32: {
1054 		struct v4l2_format *f64 = arg;
1055 		struct v4l2_clip *c64 = mbuf;
1056 		struct v4l2_clip32 __user *c32 = user_ptr;
1057 		u32 clipcount = f64->fmt.win.clipcount;
1058 
1059 		if ((f64->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1060 		     f64->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) ||
1061 		    clipcount == 0)
1062 			return 0;
1063 		if (clipcount > 2048)
1064 			return -EINVAL;
1065 		while (clipcount--) {
1066 			if (copy_from_user(c64, c32, sizeof(c64->c)))
1067 				return -EFAULT;
1068 			c64->next = NULL;
1069 			c64++;
1070 			c32++;
1071 		}
1072 		break;
1073 	}
1074 #ifdef CONFIG_COMPAT_32BIT_TIME
1075 	case VIDIOC_QUERYBUF32_TIME32:
1076 	case VIDIOC_QBUF32_TIME32:
1077 	case VIDIOC_DQBUF32_TIME32:
1078 	case VIDIOC_PREPARE_BUF32_TIME32:
1079 #endif
1080 	case VIDIOC_QUERYBUF32:
1081 	case VIDIOC_QBUF32:
1082 	case VIDIOC_DQBUF32:
1083 	case VIDIOC_PREPARE_BUF32: {
1084 		struct v4l2_buffer *b64 = arg;
1085 		struct v4l2_plane *p64 = mbuf;
1086 		struct v4l2_plane32 __user *p32 = user_ptr;
1087 
1088 		if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) {
1089 			u32 num_planes = b64->length;
1090 
1091 			if (num_planes == 0)
1092 				return 0;
1093 
1094 			while (num_planes--) {
1095 				err = get_v4l2_plane32(p64, p32, b64->memory);
1096 				if (err)
1097 					return err;
1098 				++p64;
1099 				++p32;
1100 			}
1101 		}
1102 		break;
1103 	}
1104 	case VIDIOC_G_EXT_CTRLS32:
1105 	case VIDIOC_S_EXT_CTRLS32:
1106 	case VIDIOC_TRY_EXT_CTRLS32: {
1107 		struct v4l2_ext_controls *ecs64 = arg;
1108 		struct v4l2_ext_control *ec64 = mbuf;
1109 		struct v4l2_ext_control32 __user *ec32 = user_ptr;
1110 		int n;
1111 
1112 		for (n = 0; n < ecs64->count; n++) {
1113 			if (copy_from_user(ec64, ec32, sizeof(*ec32)))
1114 				return -EFAULT;
1115 
1116 			if (ctrl_is_pointer(file, ec64->id)) {
1117 				compat_uptr_t p;
1118 
1119 				if (get_user(p, &ec32->string))
1120 					return -EFAULT;
1121 				ec64->string = compat_ptr(p);
1122 			}
1123 			ec32++;
1124 			ec64++;
1125 		}
1126 		break;
1127 	}
1128 	default:
1129 		if (copy_from_user(mbuf, user_ptr, array_size))
1130 			err = -EFAULT;
1131 		break;
1132 	}
1133 
1134 	return err;
1135 }
1136 
1137 int v4l2_compat_put_array_args(struct file *file, void __user *user_ptr,
1138 			       void *mbuf, size_t array_size,
1139 			       unsigned int cmd, void *arg)
1140 {
1141 	int err = 0;
1142 
1143 	switch (cmd) {
1144 	case VIDIOC_G_FMT32:
1145 	case VIDIOC_S_FMT32:
1146 	case VIDIOC_TRY_FMT32: {
1147 		struct v4l2_format *f64 = arg;
1148 		struct v4l2_clip *c64 = mbuf;
1149 		struct v4l2_clip32 __user *c32 = user_ptr;
1150 		u32 clipcount = f64->fmt.win.clipcount;
1151 
1152 		if ((f64->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1153 		     f64->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) ||
1154 		    clipcount == 0)
1155 			return 0;
1156 		if (clipcount > 2048)
1157 			return -EINVAL;
1158 		while (clipcount--) {
1159 			if (copy_to_user(c32, c64, sizeof(c64->c)))
1160 				return -EFAULT;
1161 			c64++;
1162 			c32++;
1163 		}
1164 		break;
1165 	}
1166 #ifdef CONFIG_COMPAT_32BIT_TIME
1167 	case VIDIOC_QUERYBUF32_TIME32:
1168 	case VIDIOC_QBUF32_TIME32:
1169 	case VIDIOC_DQBUF32_TIME32:
1170 	case VIDIOC_PREPARE_BUF32_TIME32:
1171 #endif
1172 	case VIDIOC_QUERYBUF32:
1173 	case VIDIOC_QBUF32:
1174 	case VIDIOC_DQBUF32:
1175 	case VIDIOC_PREPARE_BUF32: {
1176 		struct v4l2_buffer *b64 = arg;
1177 		struct v4l2_plane *p64 = mbuf;
1178 		struct v4l2_plane32 __user *p32 = user_ptr;
1179 
1180 		if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) {
1181 			u32 num_planes = b64->length;
1182 
1183 			if (num_planes == 0)
1184 				return 0;
1185 
1186 			while (num_planes--) {
1187 				err = put_v4l2_plane32(p64, p32, b64->memory);
1188 				if (err)
1189 					return err;
1190 				++p64;
1191 				++p32;
1192 			}
1193 		}
1194 		break;
1195 	}
1196 	case VIDIOC_G_EXT_CTRLS32:
1197 	case VIDIOC_S_EXT_CTRLS32:
1198 	case VIDIOC_TRY_EXT_CTRLS32: {
1199 		struct v4l2_ext_controls *ecs64 = arg;
1200 		struct v4l2_ext_control *ec64 = mbuf;
1201 		struct v4l2_ext_control32 __user *ec32 = user_ptr;
1202 		int n;
1203 
1204 		for (n = 0; n < ecs64->count; n++) {
1205 			unsigned int size = sizeof(*ec32);
1206 			/*
1207 			 * Do not modify the pointer when copying a pointer
1208 			 * control.  The contents of the pointer was changed,
1209 			 * not the pointer itself.
1210 			 * The structures are otherwise compatible.
1211 			 */
1212 			if (ctrl_is_pointer(file, ec64->id))
1213 				size -= sizeof(ec32->value64);
1214 
1215 			if (copy_to_user(ec32, ec64, size))
1216 				return -EFAULT;
1217 
1218 			ec32++;
1219 			ec64++;
1220 		}
1221 		break;
1222 	}
1223 	default:
1224 		if (copy_to_user(user_ptr, mbuf, array_size))
1225 			err = -EFAULT;
1226 		break;
1227 	}
1228 
1229 	return err;
1230 }
1231 
1232 /**
1233  * v4l2_compat_ioctl32() - Handles a compat32 ioctl call
1234  *
1235  * @file: pointer to &struct file with the file handler
1236  * @cmd: ioctl to be called
1237  * @arg: arguments passed from/to the ioctl handler
1238  *
1239  * This function is meant to be used as .compat_ioctl fops at v4l2-dev.c
1240  * in order to deal with 32-bit calls on a 64-bits Kernel.
1241  *
1242  * This function calls do_video_ioctl() for non-private V4L2 ioctls.
1243  * If the function is a private one it calls vdev->fops->compat_ioctl32
1244  * instead.
1245  */
1246 long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1247 {
1248 	struct video_device *vdev = video_devdata(file);
1249 	long ret = -ENOIOCTLCMD;
1250 
1251 	if (!file->f_op->unlocked_ioctl)
1252 		return ret;
1253 
1254 	if (!video_is_registered(vdev))
1255 		return -ENODEV;
1256 
1257 	if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
1258 		ret = file->f_op->unlocked_ioctl(file, cmd,
1259 					(unsigned long)compat_ptr(arg));
1260 	else if (vdev->fops->compat_ioctl32)
1261 		ret = vdev->fops->compat_ioctl32(file, cmd, arg);
1262 
1263 	if (ret == -ENOIOCTLCMD)
1264 		pr_debug("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1265 			 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
1266 	return ret;
1267 }
1268 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
1269