diff options
| -rw-r--r-- | drivers/uio/uio.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 3a6934bf713..4f28f4bf836 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
| @@ -47,6 +47,9 @@ static struct uio_class { | |||
| 47 | struct class *class; | 47 | struct class *class; |
| 48 | } *uio_class; | 48 | } *uio_class; |
| 49 | 49 | ||
| 50 | /* Protect idr accesses */ | ||
| 51 | static DEFINE_MUTEX(minor_lock); | ||
| 52 | |||
| 50 | /* | 53 | /* |
| 51 | * attributes | 54 | * attributes |
| 52 | */ | 55 | */ |
| @@ -231,7 +234,6 @@ static void uio_dev_del_attributes(struct uio_device *idev) | |||
| 231 | 234 | ||
| 232 | static int uio_get_minor(struct uio_device *idev) | 235 | static int uio_get_minor(struct uio_device *idev) |
| 233 | { | 236 | { |
| 234 | static DEFINE_MUTEX(minor_lock); | ||
| 235 | int retval = -ENOMEM; | 237 | int retval = -ENOMEM; |
| 236 | int id; | 238 | int id; |
| 237 | 239 | ||
| @@ -253,7 +255,9 @@ exit: | |||
| 253 | 255 | ||
| 254 | static void uio_free_minor(struct uio_device *idev) | 256 | static void uio_free_minor(struct uio_device *idev) |
| 255 | { | 257 | { |
| 258 | mutex_lock(&minor_lock); | ||
| 256 | idr_remove(&uio_idr, idev->minor); | 259 | idr_remove(&uio_idr, idev->minor); |
| 260 | mutex_unlock(&minor_lock); | ||
| 257 | } | 261 | } |
| 258 | 262 | ||
| 259 | /** | 263 | /** |
| @@ -297,8 +301,9 @@ static int uio_open(struct inode *inode, struct file *filep) | |||
| 297 | struct uio_listener *listener; | 301 | struct uio_listener *listener; |
| 298 | int ret = 0; | 302 | int ret = 0; |
| 299 | 303 | ||
| 300 | lock_kernel(); | 304 | mutex_lock(&minor_lock); |
| 301 | idev = idr_find(&uio_idr, iminor(inode)); | 305 | idev = idr_find(&uio_idr, iminor(inode)); |
| 306 | mutex_unlock(&minor_lock); | ||
| 302 | if (!idev) { | 307 | if (!idev) { |
| 303 | ret = -ENODEV; | 308 | ret = -ENODEV; |
| 304 | goto out; | 309 | goto out; |
| @@ -324,18 +329,15 @@ static int uio_open(struct inode *inode, struct file *filep) | |||
| 324 | if (ret) | 329 | if (ret) |
| 325 | goto err_infoopen; | 330 | goto err_infoopen; |
| 326 | } | 331 | } |
| 327 | unlock_kernel(); | ||
| 328 | return 0; | 332 | return 0; |
| 329 | 333 | ||
| 330 | err_infoopen: | 334 | err_infoopen: |
| 331 | |||
| 332 | kfree(listener); | 335 | kfree(listener); |
| 333 | err_alloc_listener: | ||
| 334 | 336 | ||
| 337 | err_alloc_listener: | ||
| 335 | module_put(idev->owner); | 338 | module_put(idev->owner); |
| 336 | 339 | ||
| 337 | out: | 340 | out: |
| 338 | unlock_kernel(); | ||
| 339 | return ret; | 341 | return ret; |
| 340 | } | 342 | } |
| 341 | 343 | ||
