[4] staging: vchiq_arm: make do_ioctl_create_service() a separate function

Dan Carpenter dan.carpenter at oracle.com
Mon Jan 23 03:42:36 PST 2017


We want to implement a COMPAT version of this function so let's abstract
away all the copy_to/from_user bits.

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 5caf53942604..0ffe4bf8d826 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -506,25 +506,23 @@ vchiq_ioc_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
 				   &context, total_size);
 }
 
-static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
-				      VCHIQ_CREATE_SERVICE_T __user *uargs)
+static int
+do_ioctl_create_service(struct file *file,
+			VCHIQ_CREATE_SERVICE_T *args,
+			int __user *handle)
 {
 	VCHIQ_INSTANCE_T instance = file->private_data;
 	VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
 	VCHIQ_SERVICE_T *service = NULL;
-	VCHIQ_CREATE_SERVICE_T args;
 	USER_SERVICE_T *user_service = NULL;
 	void *userdata;
 	int srvstate;
 
-	if (copy_from_user(&args, uargs, sizeof(args)))
-		return -EFAULT;
-
 	user_service = kmalloc(sizeof(*user_service), GFP_KERNEL);
 	if (!user_service)
 		return -ENOMEM;
 
-	if (args.is_open) {
+	if (args->is_open) {
 		if (!instance->connected) {
 			kfree(user_service);
 			return -ENOTCONN;
@@ -536,11 +534,11 @@ static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
 				VCHIQ_SRVSTATE_HIDDEN;
 	}
 
-	userdata = args.params.userdata;
-	args.params.callback = service_callback;
-	args.params.userdata = user_service;
+	userdata = args->params.userdata;
+	args->params.callback = service_callback;
+	args->params.userdata = user_service;
 	service = vchiq_add_service_internal(instance->state,
-					     &args.params, srvstate,
+					     &args->params, srvstate,
 					     instance, user_service_free);
 	if (!service) {
 		kfree(user_service);
@@ -550,7 +548,7 @@ static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
 	user_service->service = service;
 	user_service->userdata = userdata;
 	user_service->instance = instance;
-	user_service->is_vchi = (args.is_vchi != 0);
+	user_service->is_vchi = (args->is_vchi != 0);
 	user_service->dequeue_pending = 0;
 	user_service->close_pending = 0;
 	user_service->message_available_pos = instance->completion_remove - 1;
@@ -559,7 +557,7 @@ static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
 	sema_init(&user_service->insert_event, 0);
 	sema_init(&user_service->remove_event, 0);
 	sema_init(&user_service->close_event, 0);
-	if (args.is_open) {
+	if (args->is_open) {
 		status = vchiq_open_service_internal(service, instance->pid);
 		if (status != VCHIQ_SUCCESS) {
 			vchiq_remove_service(service->handle);
@@ -569,8 +567,7 @@ static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
 		}
 	}
 
-	if (copy_to_user(&uargs->handle, &service->handle,
-			 sizeof(service->handle))) {
+	if (copy_to_user(handle, &service->handle, sizeof(service->handle))) {
 		vchiq_remove_service(service->handle);
 		return -EFAULT;
 	}
@@ -578,6 +575,18 @@ static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
 	return 0;
 }
 
+static int
+vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
+			   VCHIQ_CREATE_SERVICE_T __user *uargs)
+{
+	VCHIQ_CREATE_SERVICE_T args;
+
+	if (copy_from_user(&args, uargs, sizeof(args)))
+		return -EFAULT;
+
+	return do_ioctl_create_service(file, &args, &uargs->handle);
+}
+
 /****************************************************************************
 *
 *   vchiq_ioctl



More information about the linux-rpi-kernel mailing list