All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fabrice Gasnier <fabrice.gasnier@domain.hid>
To: Philippe Gerum <rpm@xenomai.org>
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-core] [Fwd: Re: [Xenomai-help] How to fix t_delete call in psos skin?]
Date: Mon, 07 Dec 2009 10:42:42 +0100	[thread overview]
Message-ID: <4B1CCE12.4080106@domain.hid> (raw)

[-- Attachment #1: Type: text/plain, Size: 23349 bytes --]

Hello,

I come back to you to submit a slightly different patch.
I observed that __psos_t_delete sometimes returns ERR_OBJID after 
pthread_cancel has been issued, due to thread isn't found on kernel side.
The attached patch uses the same mechanism as in native API 
(rt_task_delete) where equivalent error is being filtered.

Please find attached this patch (formated with git format-patch origin).

If it's looks like ok on your side, do you think this patch can be 
integrated in xenomai project?

Best regards,

Fabrice

Philippe Gerum a écrit :
> On Fri, 2009-11-13 at 15:11 +0100, Alexandre Coffignal wrote:
>  
>> Hello,
>>
>> Please find attached a new patch that should take into account your 
>> latest remarks.
>> This patch has been created using 'git diff -p' command and applies 
>> on 2.4.10 revision.
>> I'm not sure I fully understand your remark on missing critical 
>> section. Indeed, this code is similar to __t_delete routine that 
>> doesn't seem to have critical section enforcement?
>> Should a critical section be added to it as well ?
>>     
>
> No, __t_delete() is safe because it does not directly dereference the
> task pointer fetched from the registry, but simply passes it to the
> actual t_delete() syscall, which will revalidate that pointer before
> doing anything silly with it.
>
> __t_get_pthread() on the other hand, does dereference the task pointer
> to fetch the opaque handle, which is unsafe unless this is done within a
> critical section.
>
>  
>> Anyway, I tried to replicate __t_ident mechanism as you mentioned.
>>
>> Please let me know your feeling about this.
>>
>> Fabrice
>>    
>>>
>>>
>>> On Thu, 2009-11-05 at 11:54 +0100, Alexandre Coffignal wrote:
>>>
>>>        
>>>> Does this fix seem more suitable to you?
>>>> Do you see someting else missing?
>>>>
>>>>             
>>> The logic is fine, but the implementation should get closer to what is
>>> being done in the -head branch.
>>>
>>> Preliminary remarks:
>>>
>>> - Please follow the kernel CodingStyle guidelines for anything that is
>>> Xenomai-related, including userland code. Keeping a single code style
>>> throughout our code makes things easier for reviewing, and keeps visual
>>> pollution to the lowest possible level.
>>>
>>> - Please rebase your work on 2.4.10 for pushing those changes to 
>>> Xenomai
>>> mainline. There is no point for us to consider changes to legacy
>>> releases which are not being actively maintained anymore; you can 
>>> always
>>> backport those changes to 2.4.7 locally if you really fancy dealing 
>>> with
>>> bugs solved between 2.4.7 and 2.4.10...
>>>
>>> - Please tell your CVS/SVN diff tool to use -p, when formatting 
>>> patches.
>>>  
>>>        
>>>> Please advice.
>>>>             
>>>        
>>>> plain text document attachment (patch_psos_t_delete)
>>>> Index: xenomai-2.4.7_bugless/include/psos+/syscall.h
>>>> ===================================================================
>>>> --- xenomai-2.4.7_bugless.orig/include/psos+/syscall.h    
>>>> 2009-11-05 09:12:29.000000000 +0100
>>>> +++ xenomai-2.4.7_bugless/include/psos+/syscall.h    2009-11-05 
>>>> 09:13:14.000000000 +0100
>>>> @@ -73,6 +73,7 @@
>>>>  #define __psos_as_send      45
>>>>  /* Xenomai extension: get raw count of jiffies */
>>>>  #define __psos_tm_getc      46
>>>> +#define __psos_t_get_pthread        47    /* get hidden pthread_t 
>>>> identifier. */
>>>>             
>>> psos_t_getpth is enough. To be really, really pSOS-conformant when
>>> introducing a routine, we should either use:
>>>
>>> 1) a preposterously long argument list
>>>
>>> or, at the very least:
>>>  
>>> 2) an absolutely unpronounceable C identifier
>>>
>>> __psos_t_getpth happily qualifies for #2.
>>>
>>>        
>>>>  
>>>>  #ifdef __KERNEL__
>>>>  
>>>> Index: xenomai-2.4.7_bugless/ksrc/skins/psos+/syscall.c
>>>> ===================================================================
>>>> --- xenomai-2.4.7_bugless.orig/ksrc/skins/psos+/syscall.c    
>>>> 2009-11-05 09:16:48.000000000 +0100
>>>> +++ xenomai-2.4.7_bugless/ksrc/skins/psos+/syscall.c    2009-11-05 
>>>> 09:16:57.000000000 +0100
>>>> @@ -67,29 +67,37 @@
>>>>      xncompletion_t __user *u_completion;
>>>>      u_long prio, flags, tid, err;
>>>>      char name[XNOBJECT_NAME_LEN];
>>>> +    struct arg_bulk5 bulk;
>>>>             
>>> Please have a look at what is being done in the -head branch, for the
>>> very same routine (in the absence of -p passed to diff, seems to be
>>> __t_create). An arg bulk has been introduced there, so you just need to
>>> backport this.
>>>
>>>        
>>>>      psostask_t *task;
>>>>  
>>>> -    if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 4))
>>>> +    if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 
>>>> sizeof(bulk)))
>>>> +        return -EFAULT;
>>>> +
>>>> +    __xn_copy_from_user(curr, &bulk, (void __user 
>>>> *)__xn_reg_arg1(regs),
>>>> +                sizeof(bulk));
>>>> +
>>>> +    if (!__xn_access_ok(curr, VERIFY_READ, bulk.a1, sizeof(name))) {
>>>>          return -EFAULT;
>>>> +    }
>>>>  
>>>>      /* Get task name. */
>>>> -    __xn_strncpy_from_user(curr, name, (const char __user 
>>>> *)__xn_reg_arg1(regs),
>>>> +    __xn_strncpy_from_user(curr, name, (const char __user *)bulk.a1,
>>>>                     sizeof(name) - 1);
>>>>      name[sizeof(name) - 1] = '\0';
>>>>      strncpy(curr->comm, name, sizeof(curr->comm));
>>>>      curr->comm[sizeof(curr->comm) - 1] = '\0';
>>>>  
>>>>      if (!__xn_access_ok
>>>> -        (curr, VERIFY_WRITE, __xn_reg_arg4(regs), sizeof(tid)))
>>>> +        (curr, VERIFY_WRITE, bulk.a4, sizeof(tid)))
>>>>          return -EFAULT;
>>>>  
>>>>      /* Task priority. */
>>>> -    prio = __xn_reg_arg2(regs);
>>>> +    prio = bulk.a2;
>>>>      /* Task flags. Force FPU support in user-space. This will lead
>>>>         to a no-op if the platform does not support it. */
>>>> -    flags = __xn_reg_arg3(regs) | T_SHADOW | T_FPU;
>>>> +    flags = bulk.a3 | T_SHADOW | T_FPU;
>>>>      /* Completion descriptor our parent thread is pending on. */
>>>> -    u_completion = (xncompletion_t __user *)__xn_reg_arg5(regs);
>>>> +    u_completion = (xncompletion_t __user *)__xn_reg_arg2(regs);
>>>>  
>>>>      err = t_create(name, prio, 0, 0, flags, &tid);
>>>>  
>>>> @@ -99,7 +107,8 @@
>>>>           * about the new thread id, so we can manipulate its
>>>>           * TCB pointer freely. */
>>>>          tid = xnthread_handle(&task->threadbase);
>>>> -        __xn_copy_to_user(curr, (void __user 
>>>> *)__xn_reg_arg4(regs), &tid,
>>>> +        task->opaque2 = bulk.a5; /* hidden pthread_t identifier. */
>>>> +        __xn_copy_to_user(curr, (void __user *) bulk.a4, &tid,
>>>>                    sizeof(tid));
>>>>          err = xnshadow_map(&task->threadbase, u_completion); /* 
>>>> May be NULL */
>>>>      } else {
>>>> @@ -1443,6 +1452,36 @@
>>>>      return as_send((u_long)task, signals);
>>>>  }
>>>>  
>>>> +
>>>> +/*
>>>> + * int __t_get_pthread(u_long tid, u_long *pthread)
>>>> + */
>>>> +static int __t_get_pthread(struct task_struct *curr, struct 
>>>> pt_regs *regs)
>>>> +{
>>>> +    xnhandle_t handle;
>>>> +    psostask_t *task;
>>>> +    u_long pthread;
>>>> +
>>>> +    handle = __xn_reg_arg1(regs);
>>>> +
>>>> +    if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg2(regs), 
>>>> sizeof(u_long)))
>>>> +        return -EFAULT;
>>>> +
>>>> +    if (handle)
>>>> +        task = (psostask_t *)xnregistry_fetch(handle);
>>>> +    else
>>>> +        task = __psos_task_current(curr);
>>>> +
>>>> +    if (!task)
>>>> +        return ERR_OBJID;
>>>>             
>>> Critical section enforcement is missing. What if the caller gets
>>> preempted after the handle is fetched, and the non-current tid gets
>>> killed by a concurrent thread right after? See t_ident for an
>>> illustration.
>>>
>>> If the deletion happens after the critical section, well, we would just
>>> have to hope that pthread_cancel() does a good job at validating its
>>> handle, but at least we would not have referred to stale memory on our
>>> end.
>>>
>>>        
>>>> +
>>>> +    pthread = task->opaque2; /* hidden pthread_t identifier. */
>>>> +
>>>> +    __xn_copy_to_user(curr, (void __user *) __xn_reg_arg2(regs), 
>>>> &pthread, sizeof(u_long));
>>>> +
>>>> +    return SUCCESS;
>>>> +}
>>>> +
>>>>  static void *psos_shadow_eventcb(int event, void *data)
>>>>  {
>>>>      struct psos_resource_holder *rh;
>>>> @@ -1524,6 +1563,7 @@
>>>>      [__psos_tm_signal] = {&__tm_signal, __xn_exec_primary},
>>>>      [__psos_as_send] = {&__as_send, __xn_exec_conforming},
>>>>      [__psos_tm_getc] = {&__tm_getc, __xn_exec_any},
>>>> +    [__psos_t_get_pthread] = {&__t_get_pthread, __xn_exec_any},
>>>>  };
>>>>  
>>>>  extern xntbase_t *psos_tbase;
>>>> Index: xenomai-2.4.7_bugless/src/skins/psos+/task.c
>>>> ===================================================================
>>>> --- xenomai-2.4.7_bugless.orig/src/skins/psos+/task.c    2009-11-05 
>>>> 09:17:31.000000000 +0100
>>>> +++ xenomai-2.4.7_bugless/src/skins/psos+/task.c    2009-11-05 
>>>> 09:17:56.000000000 +0100
>>>> @@ -26,6 +26,15 @@
>>>>  #include <memory.h>
>>>>  #include <psos+/psos.h>
>>>>  
>>>> +struct arg_bulk5{
>>>> +
>>>> +    u_long a1;
>>>> +    u_long a2;
>>>> +    u_long a3;
>>>> +    u_long a4;
>>>> +    u_long a5;
>>>> +};
>>>>             
>>> Rather use psos_arg_bulk like in -head tree.
>>>
>>>        
>>>> +
>>>>  extern int __psos_muxid;
>>>>  
>>>>  struct psos_task_iargs {
>>>> @@ -73,6 +82,7 @@
>>>>      struct sched_param param;
>>>>      int policy;
>>>>      long err;
>>>> +    struct arg_bulk5 bulk;
>>>>  
>>>>      policy = psos_task_set_posix_priority(iargs->prio, &param);
>>>>      pthread_setschedparam(pthread_self(), policy, &param);
>>>> @@ -81,10 +91,14 @@
>>>>  
>>>>      old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
>>>>  
>>>> -    err = XENOMAI_SKINCALL5(__psos_muxid,
>>>> -                __psos_t_create,
>>>> -                iargs->name, iargs->prio, iargs->flags,
>>>> -                iargs->tid_r, iargs->completionp);
>>>> +    bulk.a1 = (u_long)iargs->name;
>>>> +    bulk.a2 = (u_long)iargs->prio;
>>>> +    bulk.a3 = (u_long)iargs->flags;
>>>> +    bulk.a4 = (u_long)iargs->tid_r;
>>>> +    bulk.a5 = (u_long)pthread_self();
>>>> +
>>>> +    err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, 
>>>> iargs->completionp);
>>>> +
>>>>      if (err)
>>>>          goto fail;
>>>>  
>>>> @@ -172,14 +186,19 @@
>>>>          u_long flags,
>>>>          u_long *tid_r)
>>>>  {
>>>> +    struct arg_bulk5 bulk;
>>>> +
>>>>      pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
>>>>  
>>>>      old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
>>>>  
>>>> -    return XENOMAI_SKINCALL5(__psos_muxid,
>>>> -                 __psos_t_create,
>>>> -                 name, prio, flags,
>>>> -                 tid_r, NULL);
>>>> +    bulk.a1 = (u_long)name;
>>>> +    bulk.a2 = (u_long)prio;
>>>> +    bulk.a3 = (u_long)flags;
>>>> +    bulk.a4 = (u_long)tid_r;
>>>> +    bulk.a5 = (u_long)pthread_self();
>>>> +
>>>> +    return XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, 
>>>> NULL);
>>>>  }
>>>>  
>>>>  u_long t_start(u_long tid,
>>>> @@ -196,6 +215,18 @@
>>>>  
>>>>  u_long t_delete(u_long tid)
>>>>  {
>>>> +    long err;
>>>> +    u_long pthread;
>>>> +
>>>> +    if(tid)
>>>> +    {
>>>> +        err = XENOMAI_SKINCALL2(__psos_muxid, 
>>>> __psos_t_get_pthread, tid, &pthread);
>>>> +        if (err)
>>>> +            return err;
>>>> +        err = pthread_cancel((pthread_t)pthread);
>>>> +        if (err)
>>>> +            return err;
>>>> +    }
>>>>             
>>> We should handle the self-deletion case specifically:
>>>
>>> +    else {
>>> +        /* Silently migrate to avoid raising SIGXCPU. */
>>> +        XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
>>> +        pthread_exit(NULL);
>>> +    }
>>>
>>> Actually, we should also test for the case when a non-zero tid ends up
>>> pointing at the current thread as well, e.g.
>>>
>>>         if (tid == 0)
>>>             goto self_delete;
>>>
>>>         err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_getpth, tid, 
>>> &ptid);
>>>         if (err)
>>>             return err;
>>>
>>>         if ((pthread_t)ptid == pthread_self())
>>>             goto self_delete;
>>>
>>>         err = pthread_cancel((pthread_t)ptid);
>>>         if (err)
>>>             return -err; /* differentiate from pSOS codes */
>>>
>>>         return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
>>> self_delete:
>>>          /* Silently migrate to avoid raising SIGXCPU. */         
>>> XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
>>>         pthread_exit(NULL);
>>>
>>>         return SUCCESS; /* not reached */
>>>
>>>        
>>>>      return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
>>>>  }
>>>>  
>>>> Index: xenomai-2.4.7_bugless/include/psos+/task.h
>>>> ===================================================================
>>>> --- xenomai-2.4.7_bugless.orig/include/psos+/task.h    2009-11-05 
>>>> 09:19:49.000000000 +0100
>>>> +++ xenomai-2.4.7_bugless/include/psos+/task.h    2009-11-05 
>>>> 09:19:58.000000000 +0100
>>>> @@ -26,6 +26,16 @@
>>>>  
>>>>  #define PSOS_TASK_MAGIC 0x81810101
>>>>  
>>>> +struct arg_bulk5{
>>>> +
>>>> +    u_long a1;
>>>> +    u_long a2;
>>>> +    u_long a3;
>>>> +    u_long a4;
>>>> +    u_long a5;
>>>> +};
>>>> +
>>>> +
>>>>  typedef struct psostask {
>>>>  
>>>>      unsigned magic;   /* Magic code - must be first */
>>>> @@ -64,6 +74,8 @@
>>>>  
>>>>      } waitargs;
>>>>  
>>>> +    u_long opaque2; /* hidden pthread_t identifier. */
>>>>             
>>> No need to make this more opaque than required to the reviewer; 
>>> besides,
>>> we only need this field when user-space support is compiled in.
>>>
>>> -    u_long opaque2; /* hidden pthread_t identifier. */
>>>
>>> +    #ifdef CONFIG_XENO_OPT_PERVASIVE
>>> +        u_long pthread;
>>> +    #endif
>>>
>>>        
>>>> +
>>>>  } psostask_t;
>>>>  
>>>>  static inline psostask_t *thread2psostask (xnthread_t *t)
>>>>             
>>>         
>> plain text document attachment (patch_psos_t_delete)
>> diff --git a/include/psos+/syscall.h b/include/psos+/syscall.h
>> index 55ee8a0..25c0a2d 100644
>> --- a/include/psos+/syscall.h
>> +++ b/include/psos+/syscall.h
>> @@ -73,6 +73,16 @@
>>  #define __psos_as_send      45
>>  /* Xenomai extension: get raw count of jiffies */
>>  #define __psos_tm_getc      46
>> +#define __psos_t_getpth        47    /* get hidden pthread_t 
>> identifier. */
>> +
>> +struct psos_arg_bulk{
>> +
>> +    u_long a1;
>> +    u_long a2;
>> +    u_long a3;
>> +    u_long a4;
>> +    u_long a5;
>> +};
>>  
>>  #ifdef __KERNEL__
>>  
>> diff --git a/include/psos+/task.h b/include/psos+/task.h
>> index ca01573..7294f0a 100644
>> --- a/include/psos+/task.h
>> +++ b/include/psos+/task.h
>> @@ -64,6 +64,10 @@ typedef struct psostask {
>>  
>>      } waitargs;
>>  
>> +    #ifdef CONFIG_XENO_OPT_PERVASIVE
>> +    u_long pthread; /* hidden pthread_t identifier. */
>> +    #endif
>> +
>>  } psostask_t;
>>  
>>  static inline psostask_t *thread2psostask (xnthread_t *t)
>> diff --git a/ksrc/skins/psos+/syscall.c b/ksrc/skins/psos+/syscall.c
>> index 1753901..a16cec5 100644
>> --- a/ksrc/skins/psos+/syscall.c
>> +++ b/ksrc/skins/psos+/syscall.c
>> @@ -67,29 +67,37 @@ static int __t_create(struct task_struct *curr, 
>> struct pt_regs *regs)
>>      xncompletion_t __user *u_completion;
>>      u_long prio, flags, tid, err;
>>      char name[XNOBJECT_NAME_LEN];
>> +    struct psos_arg_bulk bulk;
>>      psostask_t *task;
>>  
>> -    if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 4))
>> +    if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 
>> sizeof(bulk)))
>>          return -EFAULT;
>>  
>> +    __xn_copy_from_user(curr, &bulk, (void __user 
>> *)__xn_reg_arg1(regs),
>> +                sizeof(bulk));
>> +
>> +    if (!__xn_access_ok(curr, VERIFY_READ, bulk.a1, sizeof(name))) {
>> +        return -EFAULT;
>> +    }
>> +
>>      /* Get task name. */
>> -    __xn_strncpy_from_user(curr, name, (const char __user 
>> *)__xn_reg_arg1(regs),
>> +    __xn_strncpy_from_user(curr, name, (const char __user *)bulk.a1,
>>                     sizeof(name) - 1);
>>      name[sizeof(name) - 1] = '\0';
>>      strncpy(curr->comm, name, sizeof(curr->comm));
>>      curr->comm[sizeof(curr->comm) - 1] = '\0';
>>  
>>      if (!__xn_access_ok
>> -        (curr, VERIFY_WRITE, __xn_reg_arg4(regs), sizeof(tid)))
>> +        (curr, VERIFY_WRITE, bulk.a4, sizeof(tid)))
>>          return -EFAULT;
>>  
>>      /* Task priority. */
>> -    prio = __xn_reg_arg2(regs);
>> +    prio = bulk.a2;
>>      /* Task flags. Force FPU support in user-space. This will lead
>>         to a no-op if the platform does not support it. */
>> -    flags = __xn_reg_arg3(regs) | T_SHADOW | T_FPU;
>> +    flags = bulk.a3 | T_SHADOW | T_FPU;
>>      /* Completion descriptor our parent thread is pending on. */
>> -    u_completion = (xncompletion_t __user *)__xn_reg_arg5(regs);
>> +    u_completion = (xncompletion_t __user *)__xn_reg_arg2(regs);
>>  
>>      err = t_create(name, prio, 0, 0, flags, &tid);
>>  
>> @@ -99,7 +107,10 @@ static int __t_create(struct task_struct *curr, 
>> struct pt_regs *regs)
>>           * about the new thread id, so we can manipulate its
>>           * TCB pointer freely. */
>>          tid = xnthread_handle(&task->threadbase);
>> -        __xn_copy_to_user(curr, (void __user *)__xn_reg_arg4(regs), 
>> &tid,
>> +        #ifdef CONFIG_XENO_OPT_PERVASIVE
>> +        task->pthread = bulk.a5; /* hidden pthread_t identifier. */
>> +        #endif
>> +        __xn_copy_to_user(curr, (void __user *) bulk.a4, &tid,
>>                    sizeof(tid));
>>          err = xnshadow_map(&task->threadbase, u_completion); /* May 
>> be NULL */
>>      } else {
>> @@ -1443,6 +1454,47 @@ static int __as_send(struct task_struct *curr, 
>> struct pt_regs *regs)
>>      return as_send((u_long)task, signals);
>>  }
>>  
>> +
>> +/*
>> + * int __t_getpth(u_long tid, u_long *pthread)
>> + */
>> +static int __t_getpth(struct task_struct *curr, struct pt_regs *regs)
>> +{
>> +    xnhandle_t handle;
>> +    psostask_t *task;
>> +    spl_t s;
>> +    u_long err = SUCCESS;
>> +    u_long pthread;
>> +
>> +    handle = __xn_reg_arg1(regs);
>> +
>> +    if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg2(regs), 
>> sizeof(u_long)))
>> +        return -EFAULT;
>> +
>> +    xnlock_get_irqsave(&nklock, s);
>> +
>> +    if (handle)
>> +        task = (psostask_t *)xnregistry_fetch(handle);
>> +    else
>> +        task = __psos_task_current(curr);
>> +
>> +    if (!task)
>> +        err = ERR_OBJID;
>> +    else
>> +    {
>> +        #ifdef CONFIG_XENO_OPT_PERVASIVE
>> +        pthread = task->pthread; /* hidden pthread_t identifier. */
>> +        #endif
>> +    }
>> +
>> +    xnlock_put_irqrestore(&nklock, s);
>> +
>> +    if(err == SUCCESS)
>> +        __xn_copy_to_user(curr, (void __user *) __xn_reg_arg2(regs), 
>> &pthread, sizeof(u_long));
>> +
>> +    return err;
>> +}
>> +
>>  static void *psos_shadow_eventcb(int event, void *data)
>>  {
>>      struct psos_resource_holder *rh;
>> @@ -1524,6 +1576,7 @@ static xnsysent_t __systab[] = {
>>      [__psos_tm_signal] = {&__tm_signal, __xn_exec_primary},
>>      [__psos_as_send] = {&__as_send, __xn_exec_conforming},
>>      [__psos_tm_getc] = {&__tm_getc, __xn_exec_any},
>> +    [__psos_t_getpth] = {&__t_getpth, __xn_exec_any},
>>  };
>>  
>>  extern xntbase_t *psos_tbase;
>> diff --git a/src/skins/psos+/task.c b/src/skins/psos+/task.c
>> index 9358ea8..62e2419 100644
>> --- a/src/skins/psos+/task.c
>> +++ b/src/skins/psos+/task.c
>> @@ -73,6 +73,7 @@ static void *psos_task_trampoline(void *cookie)
>>      struct sched_param param;
>>      int policy;
>>      long err;
>> +    struct psos_arg_bulk bulk;
>>  
>>      policy = psos_task_set_posix_priority(iargs->prio, &param);
>>      pthread_setschedparam(pthread_self(), policy, &param);
>> @@ -81,10 +82,14 @@ static void *psos_task_trampoline(void *cookie)
>>  
>>      old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
>>  
>> -    err = XENOMAI_SKINCALL5(__psos_muxid,
>> -                __psos_t_create,
>> -                iargs->name, iargs->prio, iargs->flags,
>> -                iargs->tid_r, iargs->completionp);
>> +    bulk.a1 = (u_long)iargs->name;
>> +    bulk.a2 = (u_long)iargs->prio;
>> +    bulk.a3 = (u_long)iargs->flags;
>> +    bulk.a4 = (u_long)iargs->tid_r;
>> +    bulk.a5 = (u_long)pthread_self();
>> +
>> +    err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, 
>> iargs->completionp);
>> +
>>      if (err)
>>          goto fail;
>>  
>> @@ -172,14 +177,19 @@ u_long t_shadow(const char *name, /* Xenomai 
>> extension. */
>>          u_long flags,
>>          u_long *tid_r)
>>  {
>> +    struct psos_arg_bulk bulk;
>> +
>>      pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
>>  
>>      old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
>>  
>> -    return XENOMAI_SKINCALL5(__psos_muxid,
>> -                 __psos_t_create,
>> -                 name, prio, flags,
>> -                 tid_r, NULL);
>> +    bulk.a1 = (u_long)name;
>> +    bulk.a2 = (u_long)prio;
>> +    bulk.a3 = (u_long)flags;
>> +    bulk.a4 = (u_long)tid_r;
>> +    bulk.a5 = (u_long)pthread_self();
>> +
>> +    return XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, 
>> NULL);
>>  }
>>  
>>  u_long t_start(u_long tid,
>> @@ -196,7 +206,32 @@ u_long t_start(u_long tid,
>>  
>>  u_long t_delete(u_long tid)
>>  {
>> +    long err;
>> +    u_long ptid;
>> +
>> +    if (tid == 0)
>> +        goto self_delete;
>> +
>> +    err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_getpth, tid, &ptid);
>> +    if (err)
>> +        return err;
>> +
>> +    if ((pthread_t)ptid == pthread_self())
>> +        goto self_delete;
>> +
>> +    err = pthread_cancel((pthread_t)ptid);
>> +    if (err)
>> +        return -err; /* differentiate from pSOS codes */
>> +
>>      return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
>> +
>> +self_delete:
>> +
>> +     /* Silently migrate to avoid raising SIGXCPU. */
>> +    XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
>> +    pthread_exit(NULL);
>> +
>> +    return SUCCESS; /* not reached */
>>  }
>>  
>>  u_long t_suspend(u_long tid)
>> _______________________________________________
>> Xenomai-core mailing list
>> Xenomai-core@domain.hid
>> https://mail.gna.org/listinfo/xenomai-core
>>     
>
>
>   


[-- Attachment #2: 0001-Fix-t_delete-call-in-psos-skin-from-user-land.patch --]
[-- Type: text/x-patch, Size: 7567 bytes --]

>From 9235829ceaf327c53929c9138eb1b783d1b83b1c Mon Sep 17 00:00:00 2001
From: Fabrice Gasnier <fabrice.gasnier@domain.hid>
Date: Mon, 7 Dec 2009 09:42:19 +0100
Subject: [PATCH] Fix t_delete call in psos skin from user land

---
 include/psos+/syscall.h    |   10 ++++++
 include/psos+/task.h       |    4 ++
 ksrc/skins/psos+/syscall.c |   67 +++++++++++++++++++++++++++++++++++++++----
 src/skins/psos+/task.c     |   57 +++++++++++++++++++++++++++++++------
 4 files changed, 122 insertions(+), 16 deletions(-)

diff --git a/include/psos+/syscall.h b/include/psos+/syscall.h
index 55ee8a0..25c0a2d 100644
--- a/include/psos+/syscall.h
+++ b/include/psos+/syscall.h
@@ -73,6 +73,16 @@
 #define __psos_as_send      45
 /* Xenomai extension: get raw count of jiffies */
 #define __psos_tm_getc      46
+#define __psos_t_getpth		47	/* get hidden pthread_t identifier. */
+
+struct psos_arg_bulk{
+
+    u_long a1;
+    u_long a2;
+    u_long a3;
+    u_long a4;
+    u_long a5;
+};
 
 #ifdef __KERNEL__
 
diff --git a/include/psos+/task.h b/include/psos+/task.h
index ca01573..7294f0a 100644
--- a/include/psos+/task.h
+++ b/include/psos+/task.h
@@ -64,6 +64,10 @@ typedef struct psostask {
 
     } waitargs;
 
+	#ifdef CONFIG_XENO_OPT_PERVASIVE
+    u_long pthread; /* hidden pthread_t identifier. */
+	#endif
+
 } psostask_t;
 
 static inline psostask_t *thread2psostask (xnthread_t *t)
diff --git a/ksrc/skins/psos+/syscall.c b/ksrc/skins/psos+/syscall.c
index 1753901..a16cec5 100644
--- a/ksrc/skins/psos+/syscall.c
+++ b/ksrc/skins/psos+/syscall.c
@@ -67,29 +67,37 @@ static int __t_create(struct task_struct *curr, struct pt_regs *regs)
 	xncompletion_t __user *u_completion;
 	u_long prio, flags, tid, err;
 	char name[XNOBJECT_NAME_LEN];
+	struct psos_arg_bulk bulk;
 	psostask_t *task;
 
-	if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 4))
+	if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), sizeof(bulk)))
 		return -EFAULT;
 
+	__xn_copy_from_user(curr, &bulk, (void __user *)__xn_reg_arg1(regs),
+			    sizeof(bulk));
+
+	if (!__xn_access_ok(curr, VERIFY_READ, bulk.a1, sizeof(name))) {
+		return -EFAULT;
+	}
+
 	/* Get task name. */
-	__xn_strncpy_from_user(curr, name, (const char __user *)__xn_reg_arg1(regs),
+	__xn_strncpy_from_user(curr, name, (const char __user *)bulk.a1,
 			       sizeof(name) - 1);
 	name[sizeof(name) - 1] = '\0';
 	strncpy(curr->comm, name, sizeof(curr->comm));
 	curr->comm[sizeof(curr->comm) - 1] = '\0';
 
 	if (!__xn_access_ok
-	    (curr, VERIFY_WRITE, __xn_reg_arg4(regs), sizeof(tid)))
+		(curr, VERIFY_WRITE, bulk.a4, sizeof(tid)))
 		return -EFAULT;
 
 	/* Task priority. */
-	prio = __xn_reg_arg2(regs);
+	prio = bulk.a2;
 	/* Task flags. Force FPU support in user-space. This will lead
 	   to a no-op if the platform does not support it. */
-	flags = __xn_reg_arg3(regs) | T_SHADOW | T_FPU;
+	flags = bulk.a3 | T_SHADOW | T_FPU;
 	/* Completion descriptor our parent thread is pending on. */
-	u_completion = (xncompletion_t __user *)__xn_reg_arg5(regs);
+	u_completion = (xncompletion_t __user *)__xn_reg_arg2(regs);
 
 	err = t_create(name, prio, 0, 0, flags, &tid);
 
@@ -99,7 +107,10 @@ static int __t_create(struct task_struct *curr, struct pt_regs *regs)
 		 * about the new thread id, so we can manipulate its
 		 * TCB pointer freely. */
 		tid = xnthread_handle(&task->threadbase);
-		__xn_copy_to_user(curr, (void __user *)__xn_reg_arg4(regs), &tid,
+		#ifdef CONFIG_XENO_OPT_PERVASIVE
+		task->pthread = bulk.a5; /* hidden pthread_t identifier. */
+		#endif
+		__xn_copy_to_user(curr, (void __user *) bulk.a4, &tid,
 				  sizeof(tid));
 		err = xnshadow_map(&task->threadbase, u_completion); /* May be NULL */
 	} else {
@@ -1443,6 +1454,47 @@ static int __as_send(struct task_struct *curr, struct pt_regs *regs)
 	return as_send((u_long)task, signals);
 }
 
+
+/*
+ * int __t_getpth(u_long tid, u_long *pthread)
+ */
+static int __t_getpth(struct task_struct *curr, struct pt_regs *regs)
+{
+	xnhandle_t handle;
+	psostask_t *task;
+	spl_t s;
+	u_long err = SUCCESS;
+	u_long pthread;
+
+	handle = __xn_reg_arg1(regs);
+
+	if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg2(regs), sizeof(u_long)))
+		return -EFAULT;
+
+	xnlock_get_irqsave(&nklock, s);
+
+	if (handle)
+		task = (psostask_t *)xnregistry_fetch(handle);
+	else
+		task = __psos_task_current(curr);
+
+	if (!task)
+		err = ERR_OBJID;
+	else
+	{
+		#ifdef CONFIG_XENO_OPT_PERVASIVE
+		pthread = task->pthread; /* hidden pthread_t identifier. */
+		#endif
+	}
+
+	xnlock_put_irqrestore(&nklock, s);
+
+	if(err == SUCCESS)
+		__xn_copy_to_user(curr, (void __user *) __xn_reg_arg2(regs), &pthread, sizeof(u_long));
+
+	return err;
+}
+
 static void *psos_shadow_eventcb(int event, void *data)
 {
 	struct psos_resource_holder *rh;
@@ -1524,6 +1576,7 @@ static xnsysent_t __systab[] = {
 	[__psos_tm_signal] = {&__tm_signal, __xn_exec_primary},
 	[__psos_as_send] = {&__as_send, __xn_exec_conforming},
 	[__psos_tm_getc] = {&__tm_getc, __xn_exec_any},
+	[__psos_t_getpth] = {&__t_getpth, __xn_exec_any},
 };
 
 extern xntbase_t *psos_tbase;
diff --git a/src/skins/psos+/task.c b/src/skins/psos+/task.c
index 9358ea8..7121a52 100644
--- a/src/skins/psos+/task.c
+++ b/src/skins/psos+/task.c
@@ -73,6 +73,7 @@ static void *psos_task_trampoline(void *cookie)
 	struct sched_param param;
 	int policy;
 	long err;
+	struct psos_arg_bulk bulk;
 
 	policy = psos_task_set_posix_priority(iargs->prio, &param);
 	pthread_setschedparam(pthread_self(), policy, &param);
@@ -81,10 +82,14 @@ static void *psos_task_trampoline(void *cookie)
 
 	old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
 
-	err = XENOMAI_SKINCALL5(__psos_muxid,
-				__psos_t_create,
-				iargs->name, iargs->prio, iargs->flags,
-				iargs->tid_r, iargs->completionp);
+	bulk.a1 = (u_long)iargs->name;
+	bulk.a2 = (u_long)iargs->prio;
+	bulk.a3 = (u_long)iargs->flags;
+	bulk.a4 = (u_long)iargs->tid_r;
+	bulk.a5 = (u_long)pthread_self();
+
+	err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, iargs->completionp);
+
 	if (err)
 		goto fail;
 
@@ -172,14 +177,19 @@ u_long t_shadow(const char *name, /* Xenomai extension. */
 		u_long flags,
 		u_long *tid_r)
 {
+	struct psos_arg_bulk bulk;
+
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
 	old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
 
-	return XENOMAI_SKINCALL5(__psos_muxid,
-				 __psos_t_create,
-				 name, prio, flags,
-				 tid_r, NULL);
+	bulk.a1 = (u_long)name;
+	bulk.a2 = (u_long)prio;
+	bulk.a3 = (u_long)flags;
+	bulk.a4 = (u_long)tid_r;
+	bulk.a5 = (u_long)pthread_self();
+
+	return XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, NULL);
 }
 
 u_long t_start(u_long tid,
@@ -196,7 +206,36 @@ u_long t_start(u_long tid,
 
 u_long t_delete(u_long tid)
 {
-	return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
+	long err;
+	u_long ptid;
+
+	if (tid == 0)
+		goto self_delete;
+
+	err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_getpth, tid, &ptid);
+	if (err)
+		return err;
+
+	if ((pthread_t)ptid == pthread_self())
+		goto self_delete;
+
+	err = pthread_cancel((pthread_t)ptid);
+	if (err)
+		return -err; /* differentiate from pSOS codes */
+
+	err = XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
+	if (err == ERR_OBJID)
+		return SUCCESS;
+
+	return err;
+
+self_delete:
+
+	 /* Silently migrate to avoid raising SIGXCPU. */
+	XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
+	pthread_exit(NULL);
+
+	return SUCCESS; /* not reached */
 }
 
 u_long t_suspend(u_long tid)
-- 
1.6.0.4


             reply	other threads:[~2009-12-07  9:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-07  9:42 Fabrice Gasnier [this message]
2009-12-15 16:54 ` [Xenomai-core] [Fwd: Re: [Xenomai-help] How to fix t_delete call in psos skin?] Philippe Gerum
2009-12-16  9:53   ` Fabrice Gasnier
2009-12-18 18:18     ` Philippe Gerum
  -- strict thread matches above, loose matches on Subject: below --
2009-11-13 14:11 Alexandre Coffignal
2009-11-13 14:32 ` Philippe Gerum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B1CCE12.4080106@domain.hid \
    --to=fabrice.gasnier@domain.hid \
    --cc=rpm@xenomai.org \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.