Module: xenomai-head
Branch: master
Commit: 4f30d401be83bb7754b018c82f6f8791c75da06f
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=4f30d401be83bb7754b018c82f6f8791c75da06f

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Nov 15 11:15:21 2010 +0100

psos: fix task argument passing

This patch plugs the hole described here, with respect to passing the
argument array to a starting pSOS task:

http://www.mail-archive.com/xenomai-core@gna.org/msg04470.html

---

 include/psos+/syscall.h    |    1 +
 ksrc/skins/psos+/syscall.c |   45 +++++++++++++++++++++++++++++++++++++++++--
 ksrc/skins/psos+/task.c    |   26 +++++++++---------------
 src/skins/psos+/task.c     |   17 +++++++++------
 4 files changed, 63 insertions(+), 26 deletions(-)

diff --git a/include/psos+/syscall.h b/include/psos+/syscall.h
index a3507d0..ac5e4d1 100644
--- a/include/psos+/syscall.h
+++ b/include/psos+/syscall.h
@@ -77,6 +77,7 @@
 #define __psos_t_getpth     47
 #define __psos_t_setreg     48
 #define __psos_t_getreg     49
+#define __psos_t_getargs    50
 
 struct psos_arg_bulk {
     u_long a1;
diff --git a/ksrc/skins/psos+/syscall.c b/ksrc/skins/psos+/syscall.c
index 2990fef..e064b42 100644
--- a/ksrc/skins/psos+/syscall.c
+++ b/ksrc/skins/psos+/syscall.c
@@ -142,7 +142,7 @@ out:
 static int __t_start(struct pt_regs *regs)
 {
        void (*startaddr) (u_long, u_long, u_long, u_long);
-       u_long mode, *argp;
+       u_long mode, targs[4] = { 0, 0, 0, 0 };
        xnhandle_t handle;
        psostask_t *task;
 
@@ -162,9 +162,13 @@ static int __t_start(struct pt_regs *regs)
 
        mode = __xn_reg_arg2(regs);
        startaddr = (typeof(startaddr)) __xn_reg_arg3(regs);
-       argp = (u_long *)__xn_reg_arg4(regs);   /* May be NULL. */
 
-       return t_start((u_long)task, mode, startaddr, argp);
+       if (__xn_reg_arg4(regs) &&
+           __xn_safe_copy_from_user(targs, (u_long __user 
*)__xn_reg_arg4(regs),
+                                    sizeof(targs)))
+               return -EFAULT;
+
+       return t_start((u_long)task, mode, startaddr, targs);
 }
 
 /*
@@ -1433,6 +1437,40 @@ static int __t_getpth(struct pt_regs *regs)
 
        return SUCCESS;
 }
+/*
+ * int __t_getargs(u_long tid, u_long targs[4])
+ */
+static int __t_getargs(struct pt_regs *regs)
+{
+       xnhandle_t handle;
+       psostask_t *task;
+       u_long targs[4];
+       spl_t s;
+
+       handle = __xn_reg_arg1(regs);
+
+       xnlock_get_irqsave(&nklock, s);
+
+       if (handle)
+               task = __psos_task_lookup(handle);
+       else
+               task = __psos_task_current(current);
+
+       if (task == NULL) {
+               xnlock_put_irqrestore(&nklock, s);
+               return ERR_OBJID;
+       }
+
+       memcpy(targs, task->args, sizeof(targs));
+
+       xnlock_put_irqrestore(&nklock, s);
+
+       if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs),
+                                  targs, sizeof(targs)))
+               return -EFAULT;
+
+       return SUCCESS;
+}
 
 static void *psos_shadow_eventcb(int event, void *data)
 {
@@ -1519,6 +1557,7 @@ static xnsysent_t __systab[] = {
        [__psos_as_send] = {&__as_send, __xn_exec_conforming},
        [__psos_tm_getc] = {&__tm_getc, __xn_exec_any},
        [__psos_t_getpth] = {&__t_getpth, __xn_exec_any},
+       [__psos_t_getargs] = {&__t_getargs, __xn_exec_any},
 };
 
 extern xntbase_t *psos_tbase;
diff --git a/ksrc/skins/psos+/task.c b/ksrc/skins/psos+/task.c
index 1572903..0f05410 100644
--- a/ksrc/skins/psos+/task.c
+++ b/ksrc/skins/psos+/task.c
@@ -192,7 +192,6 @@ u_long t_start(u_long tid,
        xnflags_t xnmode;
        psostask_t *task;
        spl_t s;
-       int n;
 
        /* We have no error case here: just clear out any unwanted bit. */
        mode &= ~T_START_MASK;
@@ -222,30 +221,25 @@ u_long t_start(u_long tid,
        attr.mode = xnmode;
        attr.imask = (int)((mode >> 8) & 0x7);
        attr.affinity = XNPOD_ALL_CPUS;
+
+       if (targs)
+               memcpy(task->args, targs, sizeof(task->args));
+       else
+               memset(task->args, 0, sizeof(task->args));
+
 #ifdef CONFIG_XENO_OPT_PERVASIVE
        if (xnthread_test_state(&task->threadbase, XNSHADOW)) {
-               memset(task->args, 0, sizeof(task->args));
                attr.entry = (void (*)(void *))startaddr;
-               attr.cookie = targs;
-               /*
-                * The shadow will be returned the exact values passed
-                * to t_start(), since the trampoline is performed at
-                * user-space level. We just relay the information
-                * from t_create() to t_start() here.
-                */
-               xnpod_start_thread(&task->threadbase, &attr);
+               attr.cookie = (void *)xnthread_handle(&task->threadbase);
        }
-       else
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
-       {
-               for (n = 0; n < 4; n++)
-                       task->args[n] = targs ? targs[n] : 0;
-
+       else {
                attr.entry = psostask_trampoline;
                attr.cookie = task;
-               xnpod_start_thread(&task->threadbase, &attr);
        }
 
+       xnpod_start_thread(&task->threadbase, &attr);
+
 unlock_and_exit:
 
        xnlock_put_irqrestore(&nklock, s);
diff --git a/src/skins/psos+/task.c b/src/skins/psos+/task.c
index 98d16f6..da3c0d5 100644
--- a/src/skins/psos+/task.c
+++ b/src/skins/psos+/task.c
@@ -62,8 +62,8 @@ static void *psos_task_trampoline(void *cookie)
 {
        struct psos_task_iargs *iargs = (struct psos_task_iargs *)cookie;
        void (*entry)(u_long, u_long, u_long, u_long);
-       u_long dummy_args[4] = { 0, 0, 0, 0 }, *targs;
        struct psos_arg_bulk bulk;
+       u_long handle, targs[4];
        long err;
 
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
@@ -93,14 +93,17 @@ static void *psos_task_trampoline(void *cookie)
           Xenomai shadow is still dormant; in such a case, resume wait. */
 
        do
-               err = XENOMAI_SYSCALL2(__xn_sys_barrier, &entry, &targs);
+               err = XENOMAI_SYSCALL2(__xn_sys_barrier, &entry, &handle);
        while (err == -EINTR);
+       if (err)
+               goto fail;
 
-       if (!err) {
-               if (targs == NULL)
-                       targs = dummy_args;
-               entry(targs[0], targs[1], targs[2], targs[3]);
-       }
+       err = XENOMAI_SKINCALL2(__psos_muxid,
+                               __psos_t_getargs, handle, targs);
+       if (err)
+               goto fail;
+
+       entry(targs[0], targs[1], targs[2], targs[3]);
 
       fail:
 


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

Reply via email to