Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
0
static int __wind_task_unsafe(struct task_struct *curr, struct pt_regs *regs)
{
	if (taskUnsafe() == ERROR)
		return wind_errnoget();

	return 0;
}
Beispiel #4
0
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;
}
Beispiel #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;
}
Beispiel #6
0
static int __wind_task_delay(struct task_struct *curr, struct pt_regs *regs)
{
	int ticks = __xn_reg_arg1(regs);

	if (taskDelay(ticks) == ERROR)
		return wind_errnoget();

	return 0;
}
Beispiel #7
0
static int __wind_errno_taskget(struct pt_regs *regs)
{
	xnhandle_t handle = __xn_reg_arg1(regs);
	WIND_TCB *pTcb;
	int errcode;

 	if (!handle)
 		errcode = wind_errnoget();
 	else {
 		pTcb = __wind_lookup_task(handle);
 		if (!pTcb)
 			return S_objLib_OBJ_ID_ERROR;
 
 		errcode = errnoOfTaskGet((TASK_ID) pTcb);
 		if (errcode == ERROR)
 			return wind_errnoget();
 	}

	return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &errcode,
				      sizeof(errcode));
}
Beispiel #8
0
static int __wind_task_resume(struct pt_regs *regs)
{
	WIND_TCB *pTcb = __wind_lookup_task(__xn_reg_arg1(regs));

	if (!pTcb)
		return S_objLib_OBJ_ID_ERROR;

	if (taskResume((TASK_ID) pTcb) == ERROR)
		return wind_errnoget();

	return 0;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
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;
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
0
static int __wind_wd_create(struct pt_regs *regs)
{
	WDOG_ID wdog_id;
	wind_wd_t *wd;

	wd = (wind_wd_t *)wdCreate();

	if (!wd)
		return wind_errnoget();

	wdog_id = wd->handle;

	return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &wdog_id,
				      sizeof(wdog_id));
}
Beispiel #18
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;
}
Beispiel #19
0
static int __wind_sem_mcreate(struct pt_regs *regs)
{
	wind_sem_t *sem;
	SEM_ID sem_id;
	int flags;

	flags = __xn_reg_arg1(regs);
	sem = (wind_sem_t *)semMCreate(flags);

	if (!sem)
		return wind_errnoget();

	sem_id = sem->handle;

	return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &sem_id,
				      sizeof(sem_id));
}
Beispiel #20
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;
}
Beispiel #21
0
static int __wind_task_delete(struct pt_regs *regs)
{
	xnhandle_t handle = __xn_reg_arg1(regs);
	WIND_TCB *pTcb;

	if (handle)
		pTcb = __wind_lookup_task(handle);
	else
		pTcb = __wind_task_current(current);

	if (!pTcb)
		return S_objLib_OBJ_ID_ERROR;

	if (taskDelete((TASK_ID) pTcb) == ERROR)
		return wind_errnoget();

	return 0;
}
Beispiel #22
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));
}
Beispiel #23
0
static int __wind_msgq_create(struct pt_regs *regs)
{
	int nb_msgs, length, flags;
	wind_msgq_t *msgq;
	MSG_Q_ID qid;

	nb_msgs = __xn_reg_arg1(regs);
	length = __xn_reg_arg2(regs);
	flags = __xn_reg_arg3(regs);
	msgq = (wind_msgq_t *)msgQCreate(nb_msgs, length, flags);

	if (!msgq)
		return wind_errnoget();

	qid = msgq->handle;

	return __xn_safe_copy_to_user((void __user *)__xn_reg_arg4(regs), &qid,
				      sizeof(qid));
}
Beispiel #24
0
static int __wind_task_priorityget(struct pt_regs *regs)
{
	xnhandle_t handle = __xn_reg_arg1(regs);
	WIND_TCB *pTcb;
	int prio;

	if (handle)
		pTcb = __wind_lookup_task(handle);
	else
		pTcb = __wind_task_current(current);

	if (!pTcb)
		return S_objLib_OBJ_ID_ERROR;

	if (taskPriorityGet((TASK_ID) pTcb, &prio) == ERROR)
		return wind_errnoget();

	return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &prio,
				      sizeof(prio));
}
Beispiel #25
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;
}
Beispiel #26
0
static int __wind_wd_create(struct task_struct *curr, struct pt_regs *regs)
{
	WDOG_ID wdog_id;
	wind_wd_t *wd;

	if (!__xn_access_ok
	    (curr, VERIFY_WRITE, __xn_reg_arg1(regs), sizeof(wdog_id)))
		return -EFAULT;

	wd = (wind_wd_t *)wdCreate();

	if (!wd)
		return wind_errnoget();

	wd->rh = wind_get_rholder();
	wdog_id = wd->handle;
	__xn_copy_to_user(curr, (void __user *)__xn_reg_arg1(regs), &wdog_id,
			  sizeof(wdog_id));

	return 0;
}
Beispiel #27
0
static int __wind_sem_mcreate(struct task_struct *curr, struct pt_regs *regs)
{
	wind_sem_t *sem;
	SEM_ID sem_id;
	int flags;

	if (!__xn_access_ok
	    (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(sem_id)))
		return -EFAULT;

	flags = __xn_reg_arg1(regs);
	sem = (wind_sem_t *)semMCreate(flags);

	if (!sem)
		return wind_errnoget();

	sem_id = sem->handle;
	__xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &sem_id,
			  sizeof(sem_id));

	return 0;
}
Beispiel #28
0
static int __wind_msgq_create(struct task_struct *curr, struct pt_regs *regs)
{
	int nb_msgs, length, flags;
	wind_msgq_t *msgq;
	MSG_Q_ID qid;

	if (!__xn_access_ok
	    (curr, VERIFY_WRITE, __xn_reg_arg4(regs), sizeof(qid)))
		return -EFAULT;

	nb_msgs = __xn_reg_arg1(regs);
	length = __xn_reg_arg2(regs);
	flags = __xn_reg_arg3(regs);
	msgq = (wind_msgq_t *)msgQCreate(nb_msgs, length, flags);

	if (!msgq)
		return wind_errnoget();

	qid = msgq->handle;
	__xn_copy_to_user(curr, (void __user *)__xn_reg_arg4(regs), &qid,
			  sizeof(qid));

	return 0;
}
Beispiel #29
0
static int __wind_task_nametoid(struct pt_regs *regs)
{
	char name[XNOBJECT_NAME_LEN];
	WIND_TCB_PLACEHOLDER ph;
	xnhandle_t handle;

	if (!__xn_reg_arg1(regs))
		return S_taskLib_NAME_NOT_FOUND;

	if (__xn_safe_strncpy_from_user(name,
					(const char __user *)__xn_reg_arg1(regs),
					sizeof(name) - 1) < 0)
		return -EFAULT;

	name[sizeof(name) - 1] = '\0';

	handle = taskNameToHandle(name);
	if (handle == XN_NO_HANDLE)
		return wind_errnoget();

	ph.handle = handle; /* Copy back the task handle. */

	return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &ph, sizeof(ph));
}
Beispiel #30
0
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;
}