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_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 __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; }
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 __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; }
/* * 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_task_resume(struct task_struct *curr, struct pt_regs *regs) { WIND_TCB *pTcb = (WIND_TCB *)xnregistry_fetch(__xn_reg_arg1(regs)); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskResume((TASK_ID) pTcb) == ERROR) return wind_errnoget(); return 0; }
static int __wind_wd_start(struct task_struct *curr, struct pt_regs *regs) { wind_rholder_t *rh; long start_server; xnhandle_t handle; wind_wd_t *wd; int timeout; spl_t s; if (!__xn_access_ok(curr, VERIFY_WRITE, __xn_reg_arg5(regs), sizeof(start_server))) return -EFAULT; handle = __xn_reg_arg1(regs); wd = (wind_wd_t *)xnregistry_fetch(handle); if (!wd) return S_objLib_OBJ_ID_ERROR; rh = wind_get_rholder(); if (wd->rh != rh) /* * User may not fiddle with watchdogs created from * other processes. */ return S_objLib_OBJ_UNAVAILABLE; timeout = __xn_reg_arg2(regs); xnlock_get_irqsave(&nklock, s); if (wdStart ((WDOG_ID)wd, timeout, (wind_timer_t) & __wind_wd_handler, (long)wd) == ERROR) { xnlock_put_irqrestore(&nklock, s); return wind_errnoget(); } wd->wdt.handler = (wind_timer_t) __xn_reg_arg3(regs); wd->wdt.arg = (long)__xn_reg_arg4(regs); start_server = rh->wdcount++ == 0; xnlock_put_irqrestore(&nklock, s); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg5(regs), &start_server, sizeof(start_server)); return 0; }
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 __wind_msgq_send(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 (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. */ if (__xn_safe_copy_from_user(msgbuf, (void __user *)__xn_reg_arg2(regs), nbytes)) err = -EFAULT; else { if (msgQSend((MSG_Q_ID)msgq, msgbuf, nbytes, timeout, prio) == ERROR) err = wind_errnoget(); else err = 0; } if (msgbuf != tmp_buf) xnfree(msgbuf); return err; }
static int __wind_task_verifyid(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskIdVerify((TASK_ID) pTcb) == ERROR) return wind_errnoget(); return 0; }
static int __wind_wd_cancel(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); wind_wd_t *wd; wd = (wind_wd_t *)xnregistry_fetch(handle); if (!wd) return S_objLib_OBJ_ID_ERROR; if (wdCancel((WDOG_ID)wd) == ERROR) return wind_errnoget(); return 0; }
static int __wind_sem_flush(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); wind_sem_t *sem; sem = (wind_sem_t *)xnregistry_fetch(handle); if (!sem) return S_objLib_OBJ_ID_ERROR; if (semFlush((SEM_ID)sem) == ERROR) return wind_errnoget(); return 0; }
static int __wind_msgq_delete(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); wind_msgq_t *msgq; msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; if (msgQDelete((MSG_Q_ID)msgq) == ERROR) return wind_errnoget(); return 0; }
static int __wind_sem_take(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); int timeout = __xn_reg_arg2(regs); wind_sem_t *sem; sem = (wind_sem_t *)xnregistry_fetch(handle); if (!sem) return S_objLib_OBJ_ID_ERROR; if (semTake((SEM_ID)sem, timeout) == ERROR) return wind_errnoget(); return 0; }
static int __wind_task_suspend(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; if (handle) pTcb = (WIND_TCB *)xnregistry_fetch(handle); else pTcb = __wind_task_current(curr); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskSuspend((TASK_ID) pTcb) == ERROR) return wind_errnoget(); return 0; }
static int __wind_msgq_nummsgs(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); wind_msgq_t *msgq; int nummsgs; 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(); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &nummsgs, sizeof(nummsgs)); }
static int __wind_errno_taskset(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); int errcode = __xn_reg_arg2(regs); WIND_TCB *pTcb; if (!handle) { wind_errnoset(errcode); return 0; } pTcb = (WIND_TCB *)xnregistry_fetch(handle); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (errnoOfTaskSet((TASK_ID) pTcb, errcode) == ERROR) return wind_errnoget(); return 0; }