static int __sc_tinquiry(struct task_struct *curr, struct pt_regs *regs) { int err, tid, pinfo[3]; TCB *tcb; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg1(regs), sizeof(pinfo))) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(*tcb))) return -EFAULT; tid = __xn_reg_arg3(regs); tcb = sc_tinquiry(pinfo, tid, &err); if (!err) { __xn_copy_to_user(curr, (void __user *)__xn_reg_arg1(regs), pinfo, sizeof(pinfo)); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), tcb, sizeof(*tcb)); } return err; }
static int __wind_taskinfo_name(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); const char *name; WIND_TCB *pTcb; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), XNOBJECT_NAME_LEN)) return -EFAULT; pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; name = taskName((TASK_ID) pTcb); if (!name) return S_objLib_OBJ_ID_ERROR; /* We assume that a VxWorks task name fits in XNOBJECT_NAME_LEN bytes, including the trailing \0. */ __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), name, strlen(name) + 1); return 0; }
/* * int __wind_taskinfo_get(TASK_ID task_id, TASK_DESC *desc) */ static int __wind_taskinfo_get(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); TASK_DESC desc; WIND_TCB *pTcb; int err; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(desc))) return -EFAULT; pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; err = taskInfoGet((TASK_ID)pTcb, &desc); if (!err) { /* Replace the kernel-based pointer by the userland handle. */ desc.td_tid = handle; __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &desc, sizeof(desc)); } return err; }
static int __wind_taskinfo_status(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); unsigned long status; WIND_TCB *pTcb; spl_t s; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(status))) return -EFAULT; xnlock_get_irqsave(&nklock, s); pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb || pTcb->magic != WIND_TASK_MAGIC) { xnlock_put_irqrestore(&nklock, s); return S_objLib_OBJ_ID_ERROR; } status = xnthread_state_flags(&pTcb->threadbase); xnlock_put_irqrestore(&nklock, s); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &status, sizeof(status)); return 0; }
static int __wind_msgq_nummsgs(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); wind_msgq_t *msgq; int nummsgs; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(nummsgs))) return -EFAULT; msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; nummsgs = msgQNumMsgs((MSG_Q_ID)msgq); if (nummsgs == ERROR) return wind_errnoget(); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &nummsgs, sizeof(nummsgs)); return 0; }
static int __wind_errno_taskget(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; int errcode; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(errcode))) return -EFAULT; if (!handle) errcode = wind_errnoget(); else { pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; errcode = errnoOfTaskGet((TASK_ID) pTcb); if (errcode == ERROR) return wind_errnoget(); } __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &errcode, sizeof(errcode)); return 0; }
static int __sc_gclock(struct task_struct *curr, struct pt_regs *regs) { struct timespec time; unsigned long ns; int err; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg1(regs), sizeof(time))) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(ns))) return -EFAULT; sc_gclock(&time, &ns, &err); if (!err) { __xn_copy_to_user(curr, (void __user *)__xn_reg_arg1(regs), &time, sizeof(time)); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &ns, sizeof(ns)); } return err; }
static int __sc_qinquiry(struct task_struct *curr, struct pt_regs *regs) { int qid, count, err; char *msg; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(count))) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg3(regs), sizeof(msg))) return -EFAULT; qid = __xn_reg_arg1(regs); msg = sc_qinquiry(qid, &count, &err); if (!err) { __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &count, sizeof(count)); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg3(regs), &msg, sizeof(msg)); } return err; }
static int __wind_task_nametoid(struct task_struct *curr, struct pt_regs *regs) { char name[XNOBJECT_NAME_LEN]; WIND_TCB_PLACEHOLDER ph; xnhandle_t handle; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(ph))) return -EFAULT; if (!__xn_reg_arg1(regs)) return S_taskLib_NAME_NOT_FOUND; if (!__xn_access_ok (curr, VERIFY_READ, __xn_reg_arg1(regs), sizeof(name))) return -EFAULT; __xn_strncpy_from_user(curr, name, (const char __user *)__xn_reg_arg1(regs), sizeof(name) - 1); name[sizeof(name) - 1] = '\0'; handle = taskNameToHandle(name); if (handle == XN_NO_HANDLE) return wind_errnoget(); ph.handle = handle; /* Copy back the task handle. */ __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &ph, sizeof(ph)); return 0; }
static int __wind_task_priorityget(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; int prio; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(prio))) return -EFAULT; if (handle) pTcb = (WIND_TCB *)xnregistry_fetch(handle); else pTcb = __wind_task_current(curr); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskPriorityGet((TASK_ID) pTcb, &prio) == ERROR) return wind_errnoget(); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &prio, sizeof(prio)); return 0; }
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 __wind_msgq_receive(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); char tmp_buf[128], *msgbuf; wind_msgq_t *msgq; int timeout, err; unsigned nbytes; nbytes = __xn_reg_arg3(regs); timeout = __xn_reg_arg4(regs); if (!__xn_access_ok(curr, VERIFY_WRITE, __xn_reg_arg2(regs), nbytes)) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg5(regs), sizeof(nbytes))) return -EFAULT; msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; if (nbytes <= sizeof(tmp_buf)) msgbuf = tmp_buf; else { msgbuf = (char *)xnmalloc(nbytes); if (!msgbuf) return S_memLib_NOT_ENOUGH_MEMORY; } /* This is sub-optimal since we end up copying the data twice. */ err = msgQReceive((MSG_Q_ID)msgq, msgbuf, nbytes, timeout); if (err != ERROR) { __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), msgbuf, err); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg5(regs), &err, sizeof(err)); err = 0; } else err = wind_errnoget(); if (msgbuf != tmp_buf) xnfree(msgbuf); return err; }
static int __sc_mcreate(struct task_struct *curr, struct pt_regs *regs) { int opt = __xn_reg_arg1(regs), mid, err; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(mid))) return -EFAULT; mid = sc_mcreate(opt, &err); if (!err) __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &mid, sizeof(mid)); return err; }
static int __wind_taskinfo_iddfl(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); TASK_ID ret_id; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(ret_id))) return -EFAULT; ret_id = taskIdDefault(handle); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &ret_id, sizeof(ret_id)); return 0; }
static int sys_rtdm_sendmsg(struct pt_regs *regs) { struct task_struct *p = current; struct msghdr krnl_msg; if (unlikely(!access_rok(__xn_reg_arg2(regs), sizeof(krnl_msg)) || __xn_copy_from_user(&krnl_msg, (void __user *)__xn_reg_arg2(regs), sizeof(krnl_msg)))) return -EFAULT; return __rt_dev_sendmsg(p, __xn_reg_arg1(regs), &krnl_msg, __xn_reg_arg3(regs)); }
static int __wind_msgq_send(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); char tmp_buf[128], *msgbuf; wind_msgq_t *msgq; int timeout, prio; unsigned nbytes; STATUS err; nbytes = __xn_reg_arg3(regs); timeout = __xn_reg_arg4(regs); prio = __xn_reg_arg5(regs); if (timeout != NO_WAIT && !xnpod_primary_p()) return -EPERM; msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; if (nbytes > msgq->msg_length) return S_msgQLib_INVALID_MSG_LENGTH; if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg2(regs), nbytes)) return -EFAULT; if (nbytes <= sizeof(tmp_buf)) msgbuf = tmp_buf; else { msgbuf = (char *)xnmalloc(nbytes); if (!msgbuf) return S_memLib_NOT_ENOUGH_MEMORY; } /* This is sub-optimal since we end up copying the data twice. */ __xn_copy_from_user(curr, msgbuf, (void __user *)__xn_reg_arg2(regs), nbytes); err = msgQSend((MSG_Q_ID)msgq, msgbuf, nbytes, timeout, prio); if (msgbuf != tmp_buf) xnfree(msgbuf); return err == ERROR ? wind_errnoget() : 0; }
static int __ui_chg_pri(struct pt_regs *regs) { ID tskid = __xn_reg_arg1(regs); PRI tskpri = __xn_reg_arg2(regs); return chg_pri(tskid, tskpri); }
static int __ui_sta_tsk(struct pt_regs *regs) { ID tskid = __xn_reg_arg1(regs); INT stacd = __xn_reg_arg2(regs); return sta_tsk(tskid, stacd); }
static int __sc_pend(struct task_struct *curr, struct pt_regs *regs) { char **mboxp, *msg; long timeout; int err; /* We should be able to write to a mailbox storage, even if we * actually don't. */ if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg1(regs), sizeof(msg))) return -EFAULT; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg3(regs), sizeof(msg))) return -EFAULT; mboxp = (char **)__xn_reg_arg1(regs); timeout = __xn_reg_arg2(regs); msg = sc_pend(mboxp, timeout, &err); if (!err) __xn_copy_to_user(curr, (void __user *)__xn_reg_arg3(regs), &msg, sizeof(msg)); return err; }
static int __sc_minquiry(struct task_struct *curr, struct pt_regs *regs) { int mid, status, err; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(status))) return -EFAULT; mid = __xn_reg_arg1(regs); status = sc_minquiry(mid, &err); if (!err) __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &status, sizeof(status)); return err; }
static int __ui_snd_msg(struct pt_regs *regs) { ID mbxid = __xn_reg_arg1(regs); T_MSG __user *pk_msg = (T_MSG __user *) __xn_reg_arg2(regs); return snd_msg(mbxid, pk_msg); }
static int __ui_twai_flg(struct pt_regs *regs) { UINT flgptn, waiptn, wfmode; TMO tmout; ID flgid; ER err; flgid = __xn_reg_arg2(regs); waiptn = __xn_reg_arg3(regs); wfmode = __xn_reg_arg4(regs); tmout = __xn_reg_arg5(regs); err = twai_flg(&flgptn, flgid, waiptn, wfmode, tmout); if (err == E_OK) { if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &flgptn, sizeof(flgptn))) return -EFAULT; } else if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __sc_sinquiry(struct task_struct *curr, struct pt_regs *regs) { int semid, count_r, err; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(count_r))) return -EFAULT; semid = __xn_reg_arg1(regs); count_r = sc_sinquiry(semid, &err); if (!err) __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &count_r, sizeof(count_r)); return err; }
static int __ui_clr_flg(struct pt_regs *regs) { ID flgid = __xn_reg_arg1(regs); UINT clrptn = __xn_reg_arg2(regs); return clr_flg(flgid, clrptn); }
static int __ui_set_flg(struct pt_regs *regs) { ID flgid = __xn_reg_arg1(regs); UINT setptn = __xn_reg_arg2(regs); return set_flg(flgid, setptn); }
static int __rt_shm_heap_open(struct task_struct *curr, struct pt_regs *regs) { unsigned long name; int size; int suprt, in_kheap; unsigned long off; unsigned long opaque; void *ret; extern void *_shm_alloc(unsigned long name, int size, int suprt, int in_kheap, unsigned long *opaque); if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(size)) || !__xn_access_ok(curr, VERIFY_WRITE, __xn_reg_arg5(regs), sizeof(off))) return 0; name = (unsigned long)__xn_reg_arg1(regs); /* Size of heap space. */ __xn_copy_from_user(curr, &size, (void __user *)__xn_reg_arg2(regs), sizeof(size)); /* Creation mode. */ suprt = (int)__xn_reg_arg3(regs); in_kheap = (int)__xn_reg_arg4(regs); ret = _shm_alloc(name, size, suprt, in_kheap, &opaque); if (!ret) goto free_and_fail; off = xnheap_mapped_offset((xnheap_t *)opaque, ret); size = (int)((xnheap_t *)opaque)->extentsize; __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &size, sizeof(size)); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg5(regs), &off, sizeof(off)); return (int)opaque; free_and_fail: return 0; }
static int __sc_tsuspend(struct task_struct *curr, struct pt_regs *regs) { int err, tid, opt; tid = __xn_reg_arg1(regs); opt = __xn_reg_arg2(regs); sc_tsuspend(tid, opt, &err); return err; }
static int __sc_sdelete(struct task_struct *curr, struct pt_regs *regs) { int semid, opt, err; semid = __xn_reg_arg1(regs); opt = __xn_reg_arg2(regs); sc_sdelete(semid, opt, &err); return err; }
static int __sc_fpost(struct task_struct *curr, struct pt_regs *regs) { int fid, mask, err; fid = __xn_reg_arg1(regs); mask = __xn_reg_arg2(regs); sc_fpost(fid, mask, &err); return err; }
static int __sc_hdelete(struct task_struct *curr, struct pt_regs *regs) { int err, hid, opt; hid = __xn_reg_arg1(regs); opt = __xn_reg_arg2(regs); sc_hdelete(hid, opt, &err); return err; }