mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 10:53:16 +01:00
Lots of fixes, notion of pager hierarchy, fixed tgroup capability checking
Notion of pager hierarchy introduced using the existing but unused pagerid field. Thread creation now has two more flags TC_AS_PAGER and TC_SHARE_PAGER. The former sets creator as pager, the latter sets creator's pager as pager. Thread group capability sharing now correctly carries shared capabilities to the thread group leader's tgr_cap_list list, and this list is checked during capability checking.
This commit is contained in:
@@ -68,7 +68,7 @@ int capability_share(unsigned int share_flags)
|
||||
struct ktcb *tgr_leader;
|
||||
|
||||
BUG_ON(!(tgr_leader = tcb_find(current->tgid)));
|
||||
cap_list_move(&tgr_leader->cap_list,
|
||||
cap_list_move(&tgr_leader->tgr_cap_list,
|
||||
¤t->cap_list);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -191,7 +191,8 @@ void task_destroy_current(void)
|
||||
list_foreach_removable_struct(task, n,
|
||||
&curcont->ktcb_list.list,
|
||||
task_list) {
|
||||
if (task->tid == current->tid)
|
||||
if (task->tid == current->tid ||
|
||||
task->pagerid != current->tid)
|
||||
continue;
|
||||
spin_unlock(&curcont->ktcb_list.list_lock);
|
||||
task_suspend(task, TASK_EXITING);
|
||||
@@ -342,7 +343,7 @@ out:
|
||||
int thread_create(struct task_ids *ids, unsigned int flags)
|
||||
{
|
||||
struct ktcb *new;
|
||||
struct ktcb *parent = 0;
|
||||
struct ktcb *orig = 0;
|
||||
int err;
|
||||
|
||||
/* Clear flags to just include creation flags */
|
||||
@@ -353,6 +354,10 @@ int thread_create(struct task_ids *ids, unsigned int flags)
|
||||
& TC_COPY_SPACE & TC_NEW_SPACE) || !flags)
|
||||
return -EINVAL;
|
||||
|
||||
/* Can't have multiple pager specifiers */
|
||||
if (flags & TC_SHARE_PAGER & TC_AS_PAGER)
|
||||
return -EINVAL;
|
||||
|
||||
/* Can't request shared utcb or tgid without shared space */
|
||||
if (!(flags & TC_SHARE_SPACE)) {
|
||||
if ((flags & TC_SHARE_UTCB) ||
|
||||
@@ -370,28 +375,41 @@ int thread_create(struct task_ids *ids, unsigned int flags)
|
||||
|
||||
/* Obtain parent thread if there is one */
|
||||
if (flags & TC_SHARE_SPACE || flags & TC_COPY_SPACE) {
|
||||
if (!(parent = tcb_find(ids->tid))) {
|
||||
if (!(orig = tcb_find(ids->tid))) {
|
||||
err = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup container-generic fields from current task
|
||||
* Note this is a kernel-level relationship
|
||||
* between the creator and the new thread.
|
||||
*
|
||||
* NOTE: If a new container is created, this needs
|
||||
* to assign the new pager and container
|
||||
* Any higher layer may define parent/child
|
||||
* relationships between orig and new separately.
|
||||
*/
|
||||
if (flags & TC_AS_PAGER)
|
||||
new->pagerid = current->tid;
|
||||
else if (flags & TC_SHARE_PAGER)
|
||||
new->pagerid = current->pagerid;
|
||||
else
|
||||
new->pagerid = new->tid;
|
||||
|
||||
/*
|
||||
* Setup container-generic fields from current task
|
||||
*/
|
||||
new->pagerid = current->pagerid;
|
||||
new->pager = current->pager;
|
||||
new->container = current->container;
|
||||
|
||||
/* Set up new thread context by using parent ids and flags */
|
||||
thread_setup_new_ids(ids, flags, new, parent);
|
||||
arch_setup_new_thread(new, parent, flags);
|
||||
thread_setup_new_ids(ids, flags, new, orig);
|
||||
arch_setup_new_thread(new, orig, flags);
|
||||
|
||||
tcb_add(new);
|
||||
|
||||
//printk("%s: %d created: %d, %d, %d \n",
|
||||
// __FUNCTION__, current->tid, ids->tid,
|
||||
// ids->tgid, ids->spid);
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
|
||||
@@ -81,6 +81,7 @@ struct capability *capability_find_by_rtype(struct ktcb *task,
|
||||
unsigned int rtype)
|
||||
{
|
||||
struct capability *cap;
|
||||
struct ktcb *tgleader;
|
||||
|
||||
/* Search task's own list */
|
||||
list_foreach_struct(cap, &task->cap_list.caps, list)
|
||||
@@ -92,8 +93,11 @@ struct capability *capability_find_by_rtype(struct ktcb *task,
|
||||
if (cap_rtype(cap) == rtype)
|
||||
return cap;
|
||||
|
||||
/* Find group leader */
|
||||
BUG_ON(!(tgleader = tcb_find(task->tgid)));
|
||||
|
||||
/* Search thread group list */
|
||||
list_foreach_struct(cap, &task->tgr_cap_list.caps, list)
|
||||
list_foreach_struct(cap, &tgleader->tgr_cap_list.caps, list)
|
||||
if (cap_rtype(cap) == rtype)
|
||||
return cap;
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ int init_pager(struct pager *pager,
|
||||
pager->tcb = task;
|
||||
task->pager = pager;
|
||||
task->pagerid = task->tid;
|
||||
task->tgid = task->tid;
|
||||
task->container = cont;
|
||||
|
||||
/* Initialize uninitialized capability fields while on dummy */
|
||||
|
||||
@@ -32,6 +32,7 @@ void tcb_init(struct ktcb *new)
|
||||
|
||||
cap_list_init(&new->cap_list);
|
||||
cap_list_init(&new->tgr_cap_list);
|
||||
cap_list_init(&new->pager_cap_list);
|
||||
|
||||
/* Initialise task's scheduling state and parameters. */
|
||||
sched_init_task(new, TASK_PRIO_NORMAL);
|
||||
@@ -117,6 +118,9 @@ struct ktcb *tcb_find(l4id_t tid)
|
||||
{
|
||||
struct ktcb *task;
|
||||
|
||||
if (current->tid == tid)
|
||||
return current;
|
||||
|
||||
spin_lock(&curcont->ktcb_list.list_lock);
|
||||
list_foreach_struct(task, &curcont->ktcb_list.list, task_list) {
|
||||
if (task->tid == tid) {
|
||||
|
||||
Reference in New Issue
Block a user