[Xenomai-git] Philippe Gerum : cobalt/rtdm: sanitize handling of exclusive context

2014-09-21 Thread git repository hosting
Module: xenomai-forge
Branch: next
Commit: fbafe724267062d2c0e2db9193c8908be711a17a
URL:
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=fbafe724267062d2c0e2db9193c8908be711a17a

Author: Philippe Gerum 
Date:   Fri Sep 19 16:38:25 2014 +0200

cobalt/rtdm: sanitize handling of exclusive context

---

 include/cobalt/kernel/rtdm/driver.h |1 -
 kernel/cobalt/posix/io.c|   11 
 kernel/cobalt/rtdm/core.c   |   49 +--
 kernel/cobalt/rtdm/device.c |   19 --
 4 files changed, 23 insertions(+), 57 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 9db9e1b..5b566f2 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -346,7 +346,6 @@ struct rtdm_device {
dev_t rdev;
struct device *kdev;
atomic_t refcount;
-   struct rtdm_dev_context *exclusive_context;
struct rtdm_fd_ops ops;
wait_queue_head_t putwq;
};
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 8038bd3..be58bd6 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -50,13 +50,15 @@ COBALT_SYSCALL(open, lostage,
device = __rtdm_get_namedev(filename->name);
if (device == NULL) {
ret = -ENODEV;
-   goto fail_lookup;
+   goto fail;
}
+   /* __rt_dev_open() will revalidate. */
+   __rtdm_put_device(device);
 
ufd = get_unused_fd_flags(oflag);
if (ufd < 0) {
ret = ufd;
-   goto fail_ufd;
+   goto fail;
}
 
filp = filp_open(filename->name, oflag, 0);
@@ -70,7 +72,6 @@ COBALT_SYSCALL(open, lostage,
if (ret < 0)
goto fail_devopen;
 
-   __rtdm_put_device(device);
fd_install(ufd, filp);
putname(filename);
 
@@ -79,9 +80,7 @@ fail_devopen:
filp_close(filp, current->files);
 fail_fopen:
put_unused_fd(ufd);
-fail_ufd:
-   __rtdm_put_device(device);
-fail_lookup:
+fail:
putname(filename);
 
return ret;
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 2baf664..5e05b30 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -41,12 +41,8 @@ DEFINE_XNLOCK(rt_fildes_lock);
 static void cleanup_instance(struct rtdm_device *device,
 struct rtdm_dev_context *context)
 {
-   if (context) {
-   if (device->exclusive_context)
-   context->device = NULL;
-   else
-   kfree(context);
-   }
+   if (context)
+   kfree(context);
 
__rtdm_put_device(device);
 }
@@ -80,9 +76,10 @@ static int create_instance(struct xnsys_ppd *p, int fd,
   struct rtdm_device *device,
   struct rtdm_dev_context **context_ptr)
 {
+   struct rtdm_device_class *class = device->class;
struct rtdm_dev_context *context;
spl_t s;
-   int err;
+   int ret;
 
/*
 * Reset to NULL so that we can always use cleanup_files/instance to
@@ -105,34 +102,24 @@ static int create_instance(struct xnsys_ppd *p, int fd,
xnlock_put_irqrestore(&rt_fildes_lock, s);
}
 
-   context = device->exclusive_context;
-   if (context) {
-   xnlock_get_irqsave(&rt_dev_lock, s);
-
-   if (unlikely(context->device != NULL)) {
-   xnlock_put_irqrestore(&rt_dev_lock, s);
-   err = -EBUSY;
-   goto fail;
-   }
-
-   context->device = device;
-
-   xnlock_put_irqrestore(&rt_dev_lock, s);
-   } else {
-   context = kmalloc(sizeof(struct rtdm_dev_context) +
-   device->class->context_size, GFP_KERNEL);
-   if (unlikely(context == NULL)) {
-   err = -ENOMEM;
-   goto fail;
-   }
+   if ((class->device_flags & RTDM_EXCLUSIVE) != 0 &&
+   atomic_read(&device->refcount) > 1) {
+   ret = -EBUSY;
+   goto fail;
+   }
 
-   context->device = device;
+   context = kmalloc(sizeof(struct rtdm_dev_context) +
+ class->context_size, GFP_KERNEL);
+   if (unlikely(context == NULL)) {
+   ret = -ENOMEM;
+   goto fail;
}
 
+   context->device = device;
*context_ptr = context;
 
-   err = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
-   if (err < 0)
+   ret = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
+   if (ret < 0)
goto fail;
 
return fd;
@@ -144,7 +131,7 @@ fail:
xnlock_put_irqrestore(&rt_fi

[Xenomai-git] Philippe Gerum : cobalt/rtdm: sanitize handling of exclusive context

2014-09-19 Thread git repository hosting
Module: xenomai-forge
Branch: next
Commit: 0a6d1fc0e758407e307e9f0107c2bb416f816553
URL:
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=0a6d1fc0e758407e307e9f0107c2bb416f816553

Author: Philippe Gerum 
Date:   Fri Sep 19 16:38:25 2014 +0200

cobalt/rtdm: sanitize handling of exclusive context

---

 include/cobalt/kernel/rtdm/driver.h |1 -
 kernel/cobalt/posix/io.c|   11 
 kernel/cobalt/rtdm/core.c   |   49 +--
 kernel/cobalt/rtdm/device.c |   19 --
 4 files changed, 23 insertions(+), 57 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 9db9e1b..5b566f2 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -346,7 +346,6 @@ struct rtdm_device {
dev_t rdev;
struct device *kdev;
atomic_t refcount;
-   struct rtdm_dev_context *exclusive_context;
struct rtdm_fd_ops ops;
wait_queue_head_t putwq;
};
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 8038bd3..be58bd6 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -50,13 +50,15 @@ COBALT_SYSCALL(open, lostage,
device = __rtdm_get_namedev(filename->name);
if (device == NULL) {
ret = -ENODEV;
-   goto fail_lookup;
+   goto fail;
}
+   /* __rt_dev_open() will revalidate. */
+   __rtdm_put_device(device);
 
ufd = get_unused_fd_flags(oflag);
if (ufd < 0) {
ret = ufd;
-   goto fail_ufd;
+   goto fail;
}
 
filp = filp_open(filename->name, oflag, 0);
@@ -70,7 +72,6 @@ COBALT_SYSCALL(open, lostage,
if (ret < 0)
goto fail_devopen;
 
-   __rtdm_put_device(device);
fd_install(ufd, filp);
putname(filename);
 
@@ -79,9 +80,7 @@ fail_devopen:
filp_close(filp, current->files);
 fail_fopen:
put_unused_fd(ufd);
-fail_ufd:
-   __rtdm_put_device(device);
-fail_lookup:
+fail:
putname(filename);
 
return ret;
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 2baf664..5e05b30 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -41,12 +41,8 @@ DEFINE_XNLOCK(rt_fildes_lock);
 static void cleanup_instance(struct rtdm_device *device,
 struct rtdm_dev_context *context)
 {
-   if (context) {
-   if (device->exclusive_context)
-   context->device = NULL;
-   else
-   kfree(context);
-   }
+   if (context)
+   kfree(context);
 
__rtdm_put_device(device);
 }
@@ -80,9 +76,10 @@ static int create_instance(struct xnsys_ppd *p, int fd,
   struct rtdm_device *device,
   struct rtdm_dev_context **context_ptr)
 {
+   struct rtdm_device_class *class = device->class;
struct rtdm_dev_context *context;
spl_t s;
-   int err;
+   int ret;
 
/*
 * Reset to NULL so that we can always use cleanup_files/instance to
@@ -105,34 +102,24 @@ static int create_instance(struct xnsys_ppd *p, int fd,
xnlock_put_irqrestore(&rt_fildes_lock, s);
}
 
-   context = device->exclusive_context;
-   if (context) {
-   xnlock_get_irqsave(&rt_dev_lock, s);
-
-   if (unlikely(context->device != NULL)) {
-   xnlock_put_irqrestore(&rt_dev_lock, s);
-   err = -EBUSY;
-   goto fail;
-   }
-
-   context->device = device;
-
-   xnlock_put_irqrestore(&rt_dev_lock, s);
-   } else {
-   context = kmalloc(sizeof(struct rtdm_dev_context) +
-   device->class->context_size, GFP_KERNEL);
-   if (unlikely(context == NULL)) {
-   err = -ENOMEM;
-   goto fail;
-   }
+   if ((class->device_flags & RTDM_EXCLUSIVE) != 0 &&
+   atomic_read(&device->refcount) > 1) {
+   ret = -EBUSY;
+   goto fail;
+   }
 
-   context->device = device;
+   context = kmalloc(sizeof(struct rtdm_dev_context) +
+ class->context_size, GFP_KERNEL);
+   if (unlikely(context == NULL)) {
+   ret = -ENOMEM;
+   goto fail;
}
 
+   context->device = device;
*context_ptr = context;
 
-   err = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
-   if (err < 0)
+   ret = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
+   if (ret < 0)
goto fail;
 
return fd;
@@ -144,7 +131,7 @@ fail:
xnlock_put_irqrestore(&rt_fi

[Xenomai-git] Philippe Gerum : cobalt/rtdm: sanitize handling of exclusive context

2014-09-19 Thread git repository hosting
Module: xenomai-forge
Branch: next
Commit: fa349055d4aeff2c05cdabac0da450a09e78ff89
URL:
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=fa349055d4aeff2c05cdabac0da450a09e78ff89

Author: Philippe Gerum 
Date:   Fri Sep 19 16:38:25 2014 +0200

cobalt/rtdm: sanitize handling of exclusive context

---

 include/cobalt/kernel/rtdm/driver.h |1 -
 kernel/cobalt/posix/io.c|   11 
 kernel/cobalt/rtdm/core.c   |   49 +--
 kernel/cobalt/rtdm/device.c |   19 --
 4 files changed, 23 insertions(+), 57 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 9db9e1b..5b566f2 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -346,7 +346,6 @@ struct rtdm_device {
dev_t rdev;
struct device *kdev;
atomic_t refcount;
-   struct rtdm_dev_context *exclusive_context;
struct rtdm_fd_ops ops;
wait_queue_head_t putwq;
};
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 8038bd3..be58bd6 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -50,13 +50,15 @@ COBALT_SYSCALL(open, lostage,
device = __rtdm_get_namedev(filename->name);
if (device == NULL) {
ret = -ENODEV;
-   goto fail_lookup;
+   goto fail;
}
+   /* __rt_dev_open() will revalidate. */
+   __rtdm_put_device(device);
 
ufd = get_unused_fd_flags(oflag);
if (ufd < 0) {
ret = ufd;
-   goto fail_ufd;
+   goto fail;
}
 
filp = filp_open(filename->name, oflag, 0);
@@ -70,7 +72,6 @@ COBALT_SYSCALL(open, lostage,
if (ret < 0)
goto fail_devopen;
 
-   __rtdm_put_device(device);
fd_install(ufd, filp);
putname(filename);
 
@@ -79,9 +80,7 @@ fail_devopen:
filp_close(filp, current->files);
 fail_fopen:
put_unused_fd(ufd);
-fail_ufd:
-   __rtdm_put_device(device);
-fail_lookup:
+fail:
putname(filename);
 
return ret;
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 2ce7d8f..d18a242 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -43,12 +43,8 @@ DEFINE_XNLOCK(rt_fildes_lock);
 static void cleanup_instance(struct rtdm_device *device,
 struct rtdm_dev_context *context)
 {
-   if (context) {
-   if (device->exclusive_context)
-   context->device = NULL;
-   else
-   kfree(context);
-   }
+   if (context)
+   kfree(context);
 
__rtdm_put_device(device);
 }
@@ -82,9 +78,10 @@ static int create_instance(struct xnsys_ppd *p, int fd,
   struct rtdm_device *device,
   struct rtdm_dev_context **context_ptr)
 {
+   struct rtdm_device_class *class = device->class;
struct rtdm_dev_context *context;
spl_t s;
-   int err;
+   int ret;
 
/*
 * Reset to NULL so that we can always use cleanup_files/instance to
@@ -107,34 +104,24 @@ static int create_instance(struct xnsys_ppd *p, int fd,
xnlock_put_irqrestore(&rt_fildes_lock, s);
}
 
-   context = device->exclusive_context;
-   if (context) {
-   xnlock_get_irqsave(&rt_dev_lock, s);
-
-   if (unlikely(context->device != NULL)) {
-   xnlock_put_irqrestore(&rt_dev_lock, s);
-   err = -EBUSY;
-   goto fail;
-   }
-
-   context->device = device;
-
-   xnlock_put_irqrestore(&rt_dev_lock, s);
-   } else {
-   context = kmalloc(sizeof(struct rtdm_dev_context) +
-   device->class->context_size, GFP_KERNEL);
-   if (unlikely(context == NULL)) {
-   err = -ENOMEM;
-   goto fail;
-   }
+   if ((class->device_flags & RTDM_EXCLUSIVE) != 0 &&
+   atomic_read(&device->refcount) > 1) {
+   ret = -EBUSY;
+   goto fail;
+   }
 
-   context->device = device;
+   context = kmalloc(sizeof(struct rtdm_dev_context) +
+ class->context_size, GFP_KERNEL);
+   if (unlikely(context == NULL)) {
+   ret = -ENOMEM;
+   goto fail;
}
 
+   context->device = device;
*context_ptr = context;
 
-   err = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
-   if (err < 0)
+   ret = rtdm_fd_enter(p, &context->fd, fd, RTDM_FD_MAGIC, &device->ops);
+   if (ret < 0)
goto fail;
 
return fd;
@@ -146,7 +133,7 @@ fail:
xnlock_put_irqrestore(&rt_fi