Commit 7961df16 authored by Alan Cox's avatar Alan Cox Committed by Jiri Kosina

HID: Switch hiddev to unlocked_ioctl

Push down the BKL. In some cases compat_ioctl already doesn't take the
BKL so we don't either. Some of the locking here seems already dubious
and object lifetimes want documenting
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 6f0168d2
...@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, ...@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
if (!uref_multi) if (!uref_multi)
return -ENOMEM; return -ENOMEM;
lock_kernel();
uref = &uref_multi->uref; uref = &uref_multi->uref;
if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
if (copy_from_user(uref_multi, user_arg, if (copy_from_user(uref_multi, user_arg,
...@@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, ...@@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
} }
goodreturn: goodreturn:
unlock_kernel();
kfree(uref_multi); kfree(uref_multi);
return 0; return 0;
fault: fault:
unlock_kernel();
kfree(uref_multi); kfree(uref_multi);
return -EFAULT; return -EFAULT;
inval: inval:
unlock_kernel();
kfree(uref_multi); kfree(uref_multi);
return -EINVAL; return -EINVAL;
} }
...@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, ...@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd,
return len; return len;
} }
static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct hiddev_list *list = file->private_data; struct hiddev_list *list = file->private_data;
struct hiddev *hiddev = list->hiddev; struct hiddev *hiddev = list->hiddev;
...@@ -556,6 +560,9 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -556,6 +560,9 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
void __user *user_arg = (void __user *)arg; void __user *user_arg = (void __user *)arg;
int i; int i;
/* Called without BKL by compat methods so no BKL taken */
/* FIXME: Who or what stop this racing with a disconnect ?? */
if (!hiddev->exist) if (!hiddev->exist)
return -EIO; return -EIO;
...@@ -768,7 +775,7 @@ static const struct file_operations hiddev_fops = { ...@@ -768,7 +775,7 @@ static const struct file_operations hiddev_fops = {
.poll = hiddev_poll, .poll = hiddev_poll,
.open = hiddev_open, .open = hiddev_open,
.release = hiddev_release, .release = hiddev_release,
.ioctl = hiddev_ioctl, .unlocked_ioctl = hiddev_ioctl,
.fasync = hiddev_fasync, .fasync = hiddev_fasync,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = hiddev_compat_ioctl, .compat_ioctl = hiddev_compat_ioctl,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment