From aa57a1f515e63594a63613aa1ddecb94323482c3 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 26 May 2008 11:25:20 +0200 Subject: [PATCH] --- yaml --- r: 104969 b: refs/heads/master c: 7961df16819085b8a357720d89d0239036e6af2a h: refs/heads/master i: 104967: 22252553ad3731dd9df946cdc0a7a0023a2f8993 v: v3 --- [refs] | 2 +- trunk/drivers/hid/usbhid/hiddev.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 27db329af065..0454f5f8aac4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6f0168d2dacd7972d887e1ca27943ef8af7512a5 +refs/heads/master: 7961df16819085b8a357720d89d0239036e6af2a diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c index 95cc192bc7af..fe4f36472cb7 100644 --- a/trunk/drivers/hid/usbhid/hiddev.c +++ b/trunk/drivers/hid/usbhid/hiddev.c @@ -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); if (!uref_multi) return -ENOMEM; + lock_kernel(); uref = &uref_multi->uref; if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { if (copy_from_user(uref_multi, user_arg, @@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, } goodreturn: + unlock_kernel(); kfree(uref_multi); return 0; fault: + unlock_kernel(); kfree(uref_multi); return -EFAULT; inval: + unlock_kernel(); kfree(uref_multi); return -EINVAL; } @@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, 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 *hiddev = list->hiddev; @@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct usbhid_device *usbhid = hid->driver_data; void __user *user_arg = (void __user *)arg; 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) return -EIO; @@ -768,7 +775,7 @@ static const struct file_operations hiddev_fops = { .poll = hiddev_poll, .open = hiddev_open, .release = hiddev_release, - .ioctl = hiddev_ioctl, + .unlocked_ioctl = hiddev_ioctl, .fasync = hiddev_fasync, #ifdef CONFIG_COMPAT .compat_ioctl = hiddev_compat_ioctl,