[PATCH V2 6/7] staging: vchiq_arm: Add compat ioctl for get config

Michael Zoran mzoran at crowfest.net
Sat Jan 21 09:48:15 PST 2017


Add compat ioctl for get config

Signed-off-by: Michael Zoran <mzoran at crowfest.net>
---
 .../vc04_services/interface/vchiq_arm/vchiq_arm.c  | 97 +++++++++++++++++-----
 1 file changed, 74 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 961a10eee525..7d83503dc89c 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -1486,6 +1486,74 @@ vchiq_ioctl_compat_dequeue_message(struct vchiq_ioctl_ctxt *ctxt)
 
 #endif
 
+static long
+vchiq_ioctl_get_config(struct vchiq_ioctl_ctxt *ctxt)
+{
+	VCHIQ_GET_CONFIG_T __user *puargs =
+		(VCHIQ_GET_CONFIG_T __user *)ctxt->arg;
+	VCHIQ_GET_CONFIG_T args;
+	VCHIQ_CONFIG_T config;
+	VCHIQ_INSTANCE_T instance = ctxt->instance;
+
+	if (copy_from_user(&args, puargs, sizeof(args)))
+		return -EFAULT;
+
+	if (args.config_size > sizeof(config))
+		return -EINVAL;
+
+	ctxt->status = vchiq_get_config(instance, args.config_size, &config);
+
+	if (ctxt->status != VCHIQ_SUCCESS)
+		return vchiq_map_status(ctxt->status);
+
+	if (copy_to_user(args.pconfig,
+			 &config,
+			 args.config_size))
+		return -EFAULT;
+
+	return 0;
+}
+
+#if defined(CONFIG_COMPAT)
+
+struct vchiq_get_config32 {
+	unsigned int config_size;
+	compat_uptr_t pconfig;
+};
+
+#define VCHIQ_IOC_GET_CONFIG32 \
+	_IOWR(VCHIQ_IOC_MAGIC, 10, struct vchiq_get_config32)
+
+static long
+vchiq_ioctl_compat_get_config(struct vchiq_ioctl_ctxt *ctxt)
+{
+	struct vchiq_get_config32 __user *puargs32 =
+		(struct vchiq_get_config32 __user *)ctxt->arg;
+	struct vchiq_get_config32 args32;
+	VCHIQ_CONFIG_T config;
+	VCHIQ_INSTANCE_T instance = ctxt->instance;
+
+	if (copy_from_user(&args32, puargs32, sizeof(args32)))
+		return -EFAULT;
+
+	if (args32.config_size > sizeof(config))
+		return -EINVAL;
+
+	ctxt->status = vchiq_get_config(instance, args32.config_size, &config);
+
+	if (ctxt->status != VCHIQ_SUCCESS)
+		return vchiq_map_status(ctxt->status);
+
+	if (copy_to_user(compat_ptr(args32.pconfig),
+			 &config,
+			 args32.config_size))
+		return -EFAULT;
+
+	return 0;
+}
+
+#endif
+
 /****************************************************************************
 *
 *   vchiq_ioctl
@@ -1517,6 +1585,9 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case VCHIQ_IOC_DEQUEUE_MESSAGE:
 		return vchiq_dispatch_ioctl(vchiq_ioctl_dequeue_message,
 					    file, cmd, arg);
+	case VCHIQ_IOC_GET_CONFIG:
+		return vchiq_dispatch_ioctl(vchiq_ioctl_get_config,
+					    file, cmd, arg);
 	default:
 		break;
 	}
@@ -1661,29 +1732,6 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		ret = vchiq_get_client_id(handle);
 	} break;
 
-	case VCHIQ_IOC_GET_CONFIG: {
-		VCHIQ_GET_CONFIG_T args;
-		VCHIQ_CONFIG_T config;
-
-		if (copy_from_user(&args, (const void __user *)arg,
-			sizeof(args)) != 0) {
-			ret = -EFAULT;
-			break;
-		}
-		if (args.config_size > sizeof(config)) {
-			ret = -EINVAL;
-			break;
-		}
-		status = vchiq_get_config(instance, args.config_size, &config);
-		if (status == VCHIQ_SUCCESS) {
-			if (copy_to_user((void __user *)args.pconfig,
-				    &config, args.config_size) != 0) {
-				ret = -EFAULT;
-				break;
-			}
-		}
-	} break;
-
 	case VCHIQ_IOC_SET_SERVICE_OPTION: {
 		VCHIQ_SET_SERVICE_OPTION_T args;
 
@@ -1796,6 +1844,9 @@ vchiq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 	case VCHIQ_IOC_DEQUEUE_MESSAGE32:
 		return vchiq_dispatch_ioctl(vchiq_ioctl_compat_dequeue_message,
 					    file, cmd, arg);
+	case VCHIQ_IOC_GET_CONFIG32:
+		return vchiq_dispatch_ioctl(vchiq_ioctl_compat_get_config,
+					    file, cmd, arg);
 	default:
 		return vchiq_ioctl(file, cmd, arg);
 	}
-- 
2.11.0




More information about the linux-rpi-kernel mailing list