Merge "v4l2-compat-ioctl32: Add support for private buffers"
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 8618eba..2e50546 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -30,6 +30,13 @@
 	get_user(__assign_tmp, from) || put_user(__assign_tmp, to);	\
 })
 
+#define convert_in_user(srcptr, dstptr)					\
+({									\
+	typeof(*srcptr) val;						\
+									\
+	get_user(val, srcptr) || put_user(val, dstptr);			\
+})
+
 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	long ret = -ENOIOCTLCMD;
@@ -513,6 +520,15 @@
 				   &up->timestamp.tv_usec))
 			return -EFAULT;
 
+	if (type == V4L2_BUF_TYPE_PRIVATE) {
+		compat_long_t tmp;
+
+		if (get_user(tmp, &up->m.userptr) ||
+				put_user((unsigned long) compat_ptr(tmp),
+					&kp->m.userptr))
+			return -EFAULT;
+	}
+
 	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
 		u32 num_planes = length;
 
@@ -611,6 +627,10 @@
 	    put_user(length, &up->length))
 		return -EFAULT;
 
+	if (type == V4L2_BUF_TYPE_PRIVATE)
+		if (convert_in_user(&kp->m.userptr, &up->m.userptr))
+			return -EFAULT;
+
 	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
 		u32 num_planes = length;
 
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 839cfde..824eee7 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -161,6 +161,9 @@
 	 || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT		\
 	 || (type) == V4L2_BUF_TYPE_SDR_OUTPUT)
 
+#define V4L2_TYPE_IS_PRIVATE(type)				\
+	((type) == V4L2_BUF_TYPE_PRIVATE)
+
 enum v4l2_tuner_type {
 	V4L2_TUNER_RADIO	     = 1,
 	V4L2_TUNER_ANALOG_TV	     = 2,