Module: xenomai-rpm Branch: for-upstream Commit: 4f30d401be83bb7754b018c82f6f8791c75da06f URL: http://git.xenomai.org/?p=xenomai-rpm.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-c...@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