static int __sc_tecreate(struct task_struct *curr, struct pt_regs *regs) { xncompletion_t __user *u_completion; struct vrtx_arg_bulk bulk; int prio, mode, tid, err; vrtxtask_t *task; if (!__xn_access_ok (curr, VERIFY_READ, __xn_reg_arg1(regs), sizeof(bulk))) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(tid))) return -EFAULT; __xn_copy_from_user(curr, &bulk, (void __user *)__xn_reg_arg1(regs), sizeof(bulk)); /* Suggested task id. */ tid = bulk.a1; /* Task priority. */ prio = bulk.a2; /* Task mode. */ mode = bulk.a3 | 0x100; /* Completion descriptor our parent thread is pending on. */ u_completion = (xncompletion_t __user *)__xn_reg_arg3(regs); task = xnmalloc(sizeof(*task)); if (!task) { err = ER_TCB; goto done; } xnthread_clear_state(&task->threadbase, XNZOMBIE); tid = sc_tecreate_inner(task, NULL, tid, prio, mode, 0, 0, NULL, 0, &err); if (tid < 0) { if (u_completion) xnshadow_signal_completion(u_completion, err); } else { __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &tid, sizeof(tid)); err = xnshadow_map(&task->threadbase, u_completion); } if (err && !xnthread_test_state(&task->threadbase, XNZOMBIE)) xnfree(task); done: return err; }
static int __ui_cre_tsk(struct pt_regs *regs) { xncompletion_t __user *u_completion; struct task_struct *p = current; unsigned long __user *u_mode_offset; uitask_t *task; T_CTSK pk_ctsk; ID tskid; spl_t s; ER err; tskid = __xn_reg_arg1(regs); if (__xn_safe_copy_from_user(&pk_ctsk, (void __user *)__xn_reg_arg2(regs), sizeof(pk_ctsk))) return -EFAULT; pk_ctsk.tskatr |= TA_SHADOW; /* Completion descriptor our parent thread is pending on. */ u_completion = (xncompletion_t __user *)__xn_reg_arg3(regs); u_mode_offset = (unsigned long __user *)__xn_reg_arg4(regs); err = cre_tsk(tskid, &pk_ctsk); if (likely(err == E_OK)) { xnlock_get_irqsave(&nklock, s); task = xnmap_fetch(ui_task_idmap, tskid); if (!task) { xnlock_put_irqrestore(&nklock, s); err = E_OBJ; goto fail; } strncpy(p->comm, xnthread_name(&task->threadbase), sizeof(p->comm)); p->comm[sizeof(p->comm) - 1] = '\0'; xnlock_put_irqrestore(&nklock, s); /* Since we may not hold the superlock across a call * to xnshadow_map(), we do have a small race window * here, if the created task is killed then its TCB * recycled before we could map it; however, the risk * is mitigated by consistency checks performed in * xnshadow_map(). */ return xnshadow_map(&task->threadbase, u_completion, u_mode_offset); } fail: /* Unblock and pass back the error code. */ if (u_completion) xnshadow_signal_completion(u_completion, err); return err; }
static int __wind_task_init(struct task_struct *curr, struct pt_regs *regs) { xncompletion_t __user *u_completion; char name[XNOBJECT_NAME_LEN]; struct wind_arg_bulk bulk; int err = 0, prio, flags; WIND_TCB_PLACEHOLDER ph; WIND_TCB *task; if (!__xn_access_ok (curr, VERIFY_READ, __xn_reg_arg1(regs), sizeof(bulk))) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(ph))) return -EFAULT; __xn_copy_from_user(curr, &bulk, (void __user *)__xn_reg_arg1(regs), sizeof(bulk)); if (bulk.a1) { if (!__xn_access_ok(curr, VERIFY_READ, bulk.a1, sizeof(name))) return -EFAULT; __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'; } else *name = '\0'; /* Task priority. */ prio = bulk.a2; /* Task flags. */ flags = bulk.a3 | VX_SHADOW; /* Completion descriptor our parent thread is pending on. */ u_completion = (xncompletion_t __user *)__xn_reg_arg3(regs); task = (WIND_TCB *)xnmalloc(sizeof(*task)); if (!task) { if (u_completion) xnshadow_signal_completion(u_completion, -ENOMEM); return -ENOMEM; } xnthread_clear_state(&task->threadbase, XNZOMBIE); /* Force FPU support in user-space. This will lead to a no-op if the platform does not support it. */ if (taskInit(task, name, prio, flags, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == OK) { /* Let the skin discard the TCB memory upon exit. */ task->auto_delete = 1; task->ptid = bulk.a4; /* Copy back the registry handle to the ph struct. */ ph.handle = xnthread_handle(&task->threadbase); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &ph, sizeof(ph)); err = xnshadow_map(&task->threadbase, u_completion); } else { /* Unblock and pass back error code. */ err = wind_errnoget(); if (u_completion) xnshadow_signal_completion(u_completion, err); } if (err && !xnthread_test_state(&task->threadbase, XNZOMBIE)) xnfree(task); return err; }