Module: xenomai-2.5
Branch: master
Commit: 1a312e0d731a95ef4be6698006da3fccef59a4f2
URL:    
http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=1a312e0d731a95ef4be6698006da3fccef59a4f2

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Mon Mar  8 22:41:10 2010 +0100

common: do not let u_mode exceptional cases leak out of current.[ch]

---

 include/asm-generic/bits/current.h |   23 +++++++----------------
 ksrc/nucleus/shadow.c              |   16 +++++++++-------
 src/rtdk/assert_context.c          |    9 +++------
 src/skins/common/current.c         |   23 +++++++++++++++++++++++
 4 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/include/asm-generic/bits/current.h 
b/include/asm-generic/bits/current.h
index f0e569c..b9ac680 100644
--- a/include/asm-generic/bits/current.h
+++ b/include/asm-generic/bits/current.h
@@ -6,6 +6,9 @@
 
 extern pthread_key_t xeno_current_mode_key;
 
+xnhandle_t xeno_slow_get_current(void);
+unsigned long xeno_slow_get_current_mode(void);
+
 #ifdef HAVE___THREAD
 extern __thread xnhandle_t xeno_current __attribute__ ((tls_model 
("initial-exec")));
 extern __thread unsigned long
@@ -18,12 +21,9 @@ static inline xnhandle_t xeno_get_current(void)
 
 static inline unsigned long xeno_get_current_mode(void)
 {
-       return xeno_current_mode;
-}
+       unsigned long mode = xeno_current_mode;
 
-static inline int xeno_primary_mode(void)
-{
-       return xeno_current_mode & XNRELAX;
+       return mode == -1 ? xeno_slow_get_current_mode() : mode;
 }
 
 #else /* ! HAVE___THREAD */
@@ -33,25 +33,16 @@ static inline xnhandle_t xeno_get_current(void)
 {
        void *val = pthread_getspecific(xeno_current_key);
 
-       if (!val)
-               return XN_NO_HANDLE;
-
-       return (xnhandle_t)val;
+       return (xnhandle_t)val ?: xeno_slow_get_current();
 }
 
 static inline unsigned long xeno_get_current_mode(void)
 {
        unsigned long *mode = pthread_getspecific(xeno_current_mode_key);
 
-       return mode ? *mode : -1;
+       return mode ? (*mode) : xeno_slow_get_current_mode();
 }
 
-static inline int xeno_primary_mode(void)
-{
-       unsigned long *mode = pthread_getspecific(xeno_current_mode_key);
-
-       return mode ? (*mode & XNRELAX) : 0;
-}
 #endif /* ! HAVE___THREAD */
 
 void xeno_set_current(void);
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index c80d6dc..1968d79 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -2051,8 +2051,9 @@ static struct xnskin_props __props = {
        .module = NULL
 };
 
-static void handle_shadow_exit(xnthread_t *thread)
+static void handle_shadow_exit(void)
 {
+       xnthread_t *thread = xnshadow_thread(current);
        static int warned;
 
        /*
@@ -2063,17 +2064,18 @@ static void handle_shadow_exit(xnthread_t *thread)
        if (thread->u_mode && !warned) {
                warned = 1;
                printk(KERN_WARNING
-                      "Xenomai: old Xenomai libs detected which may crash "
-                      "on thread termination\n");
+                      "Xenomai: User-space support anterior to 2.5.2"
+                      " detected, may corrupt memory upon\n"
+                      "thread termination. Upgrade is recommended\n");
        }
        thread->u_mode = NULL;
 }
 
 static inline int
-substitute_linux_syscall(xnthread_t *thread, struct pt_regs *regs)
+substitute_linux_syscall(struct pt_regs *regs)
 {
        if (unlikely(__xn_linux_mux_p(regs, __NR_exit)))
-               handle_shadow_exit(thread);
+               handle_shadow_exit();
 
        /* No real-time replacement for now -- let Linux handle this call. */
        return 0;
@@ -2243,7 +2245,7 @@ static inline int do_hisyscall_event(unsigned event, 
unsigned domid, void *data)
         * From now on, we know that we have a valid shadow thread
         * pointer.
         */
-       if (substitute_linux_syscall(thread, regs))
+       if (substitute_linux_syscall(regs))
                /*
                 * This is a Linux syscall issued on behalf of a
                 * shadow thread running inside the Xenomai
@@ -2304,7 +2306,7 @@ static inline int do_losyscall_event(unsigned event, 
unsigned domid, void *data)
        if (__xn_reg_mux_p(regs))
                goto xenomai_syscall;
 
-       if (!thread || !substitute_linux_syscall(thread, regs))
+       if (!thread || !substitute_linux_syscall(regs))
                /* Fall back to Linux syscall handling. */
                return RTHAL_EVENT_PROPAGATE;
 
diff --git a/src/rtdk/assert_context.c b/src/rtdk/assert_context.c
index bad19f3..f67bcd8 100644
--- a/src/rtdk/assert_context.c
+++ b/src/rtdk/assert_context.c
@@ -30,12 +30,9 @@ void assert_nrt(void)
        xnthread_info_t info;
        int err;
 
-       if (xeno_get_current() != XN_NO_HANDLE)
-               return;
+       if (unlikely(xeno_get_current() != XN_NO_HANDLE &&
+                    !(xeno_get_current_mode() & XNRELAX))) {
 
-       info.state = xeno_get_current_mode();
-
-       if (unlikely(!(info.state & XNRELAX) || info.state == -1)) {
                err = XENOMAI_SYSCALL1(__xn_sys_current_info, &info);
 
                if (err) {
@@ -44,7 +41,7 @@ void assert_nrt(void)
                        return;
                }
 
-               if ((info.state & (XNRELAX | XNTRAPSW)) == XNTRAPSW)
+               if (info.state & XNTRAPSW)
                        pthread_kill(pthread_self(), SIGXCPU);
        }
 }
diff --git a/src/skins/common/current.c b/src/skins/common/current.c
index 7db66c0..7277189 100644
--- a/src/skins/common/current.c
+++ b/src/skins/common/current.c
@@ -5,6 +5,7 @@
 
 #include <asm/xenomai/syscall.h>
 #include <nucleus/types.h>
+#include <nucleus/thread.h>
 
 pthread_key_t xeno_current_mode_key;
 
@@ -107,6 +108,16 @@ void xeno_init_current_keys(void)
        pthread_once(&xeno_init_current_keys_once, init_current_keys);
 }
 
+xnhandle_t xeno_slow_get_current(void)
+{
+       xnhandle_t current;
+       int err;
+
+       err = XENOMAI_SYSCALL1(__xn_sys_current, &current);
+
+       return err ? XN_NO_HANDLE : current;
+}
+
 void xeno_set_current(void)
 {
        xnhandle_t current;
@@ -128,3 +139,15 @@ unsigned long *xeno_init_current_mode(void)
        pthread_setspecific(xeno_current_mode_key, mode);
        return mode;
 }
+
+unsigned long xeno_slow_get_current_mode(void)
+{
+       xnthread_info_t info;
+       int err;
+
+       err = XENOMAI_SYSCALL1(__xn_sys_current_info, &info);
+       if (err < 0)
+               return XNRELAX;
+
+       return info.state & XNRELAX;
+}


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to