[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