示例#1
0
/** Syscall for creating a new loader instance from userspace.
 *
 * Creates a new task from the program loader image and sets
 * the task name.
 *
 * @param uspace_name Name to set on the new task (typically the same
 *                    as the command used to execute it).
 * @param name_len    Length of the name.
 *
 * @return EOK on success or an error code from @ref errno.h.
 *
 */
sysarg_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
{
	/* Cap length of name and copy it from userspace. */
	if (name_len > TASK_NAME_BUFLEN - 1)
		name_len = TASK_NAME_BUFLEN - 1;
	
	char namebuf[TASK_NAME_BUFLEN];
	int rc = copy_from_uspace(namebuf, uspace_name, name_len);
	if (rc != 0)
		return (sysarg_t) rc;
	
	namebuf[name_len] = 0;
	
	/* Spawn the new task. */
	program_t prg;
	rc = program_create_loader(&prg, namebuf);
	if (rc != 0)
		return rc;
	
	// FIXME: control the capabilities
	cap_set(prg.task, cap_get(TASK));
	program_ready(&prg);
	
	return EOK;
}
示例#2
0
/** Connect an IRQ handler to a task.
 *
 * @param inr     IRQ number.
 * @param devno   Device number.
 * @param imethod Interface and method to be associated with the notification.
 * @param ucode   Uspace pointer to the top-half pseudocode.
 *
 * @return EPERM or a return code returned by ipc_irq_register().
 *
 */
sysarg_t sys_irq_register(inr_t inr, devno_t devno, sysarg_t imethod,
    irq_code_t *ucode)
{
	if (!(cap_get(TASK) & CAP_IRQ_REG))
		return EPERM;
	
	return ipc_irq_register(&TASK->answerbox, inr, devno, imethod, ucode);
}
示例#3
0
/** Disconnect an IRQ handler from a task.
 *
 * @param inr   IRQ number.
 * @param devno Device number.
 *
 * @return Zero on success or EPERM on error.
 *
 */
sysarg_t sys_irq_unregister(inr_t inr, devno_t devno)
{
	if (!(cap_get(TASK) & CAP_IRQ_REG))
		return EPERM;
	
	ipc_irq_unregister(&TASK->answerbox, inr, devno);
	
	return 0;
}
示例#4
0
/** Grant capabilities to a task.
 *
 * The calling task must have the CAP_CAP capability.
 *
 * @param taskid Destination task ID.
 * @param caps   Capabilities to grant.
 *
 * @return Zero on success or an error code from @ref errno.h.
 *
 */
static sysarg_t cap_grant(task_id_t taskid, cap_t caps)
{
	if (!(cap_get(TASK) & CAP_CAP))
		return (sysarg_t) EPERM;
	
	irq_spinlock_lock(&tasks_lock, true);
	task_t *task = task_find_by_id(taskid);
	
	if ((!task) || (!container_check(CONTAINER, task->container))) {
		irq_spinlock_unlock(&tasks_lock, true);
		return (sysarg_t) ENOENT;
	}
	
	irq_spinlock_lock(&task->lock, false);
	task->capabilities |= caps;
	irq_spinlock_unlock(&task->lock, false);
	
	irq_spinlock_unlock(&tasks_lock, true);
	return 0;
}
示例#5
0
文件: example.c 项目: B-Rich/codezero
/*
 * This example demonstrates how a pager would
 * share part of its capabilities on the system
 * with its children.
 *
 * The example includes sharing of a mutex
 * capability with a paged-child.
 */
int multi_threaded_capability_sharing_example(void)
{
	struct capability *mutex_cap;
	int thread_retval;

	/*
	 * We are the first pager with capabilities to
	 * create new tasks, spaces, in its own container.
	 */
	pager_read_caps();

	/*
	 * We have all our capabilities private to us.
	 *
	 * If we create a new task, it won't be able to
	 * create and use userspace mutexes, because we
	 * hold mutex capabilities privately.
	 *
	 * Lets try it.
	 */

	/*
	 * Create new thread that will attempt
	 * a mutex operation, and die on us with a
	 * negative return code if it fails.
	 */
	if ((err = thread_create(mutex_user_thread, 0,
				 TC_SHARE_SPACE |
				 TC_AS_PAGER, &ids)) < 0) {
		printf("mutex_user_thread creation failed.\n");
		goto out_err;
	}

	/* Check on how the thread has done */
	if ((err = l4_thread_wait_on(ids, &thread_retval)) < 0) {
		print("Waiting on thread %d failed. err = %d\n",
		      ids->tid, err);
		goto out_err;
	}

	if (thread_retval == 0) {
		printf("Thread %d returned with success, where "
		       "we expected failure.\n", ids->tid);
		goto out_err;
	}

	/*
	 * Therefore, we share our capabilities with a
	 * collection so that our capabilities may be also
	 * used by them.
	 */

	/* Get our private mutex cap */
	mutex_cap = cap_get(CAP_TYPE_MUTEX);

	/* We have ability to create and use this many mutexes */
	printf("%s: We have ability to create/use %d mutexes\n",
	       self_tid(), mutex_cap->size);

	/* Split it */
	cap_new = cap_split(mutex_cap, 10, CAP_SPLIT_SIZE);

	/*
	 * Share the split part with paged-children.
	 *
	 * From this point onwards, any thread we create and
	 * manage (i.e. whose pagerid == self_tid()) will have
	 * the ability to use mutexes, as defined by cap_new
	 * we created.
	 */
	l4_cap_share(cap_new, CAP_SHARE_PGGROUP, self_tid());

	/*
	 * Create new thread that will attempt
	 * a mutex operation, and die on us with a
	 * negative return code if it fails.
	 */
	if ((err = thread_create(mutex_user_thread, 0,
				 TC_SHARE_SPACE |
				 TC_AS_PAGER, &ids)) < 0) {
		printf("mutex_user_thread creation failed.\n");
		goto out_err;
	}

	/* Check on how the thread has done */
	if ((err = l4_thread_wait_on(ids, &thread_retval)) < 0) {
		printf("Waiting on thread %d failed. err = %d\n",
		      ids->tid, err);
		goto out_err;
	}

	if (thread_retval < 0) {
		printf("Thread %d returned with failure, where "
		       "we expected success.\n", ids->tid);
		goto out_err;
	}

out_err:
	BUG();
}
示例#6
0
/*
 * Get current zone usage.
 */
rctl_qty_t
cpucaps_zone_get(zone_t *zone)
{
	return (cap_get(zone->zone_cpucap));
}
示例#7
0
/*
 * Get current project usage.
 */
rctl_qty_t
cpucaps_project_get(kproject_t *kpj)
{
	return (cap_get(kpj->kpj_cpucap));
}