예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
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;
}
예제 #13
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;
}
예제 #14
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;
}
예제 #15
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;
}
예제 #16
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;
}
예제 #17
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));
}
예제 #18
0
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;
}