diff --git a/conts/posix/mm0/mm/init.c b/conts/posix/mm0/mm/init.c index c957b80..69c12f9 100644 --- a/conts/posix/mm0/mm/init.c +++ b/conts/posix/mm0/mm/init.c @@ -208,6 +208,16 @@ int read_pager_capabilities() BUG(); } + /* Share all of them with paged children */ + if ((err = l4_capability_control(CAP_CONTROL_SHARE, + CAP_SHARE_CHILD, + 0)) < 0) { + printf("l4_capability_control() sharing of " + "capabilities failed.\n Could not " + "complete CAP_CONTROL_SHARE request.\n"); + BUG(); + } + /* Copy them to real allocated structures */ copy_boot_capabilities(ncaps); diff --git a/conts/posix/mm0/mm/task.c b/conts/posix/mm0/mm/task.c index 29e8342..f10ebfe 100644 --- a/conts/posix/mm0/mm/task.c +++ b/conts/posix/mm0/mm/task.c @@ -357,8 +357,10 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids, ids->tgid = parent->tgid; } - /* Create the thread structures and address space */ - if ((err = l4_thread_control(THREAD_CREATE | ctrl_flags, ids)) < 0) { + /* Create the thread structures and address space as the pager */ + if ((err = l4_thread_control(THREAD_CREATE | + TC_AS_PAGER | + ctrl_flags, ids)) < 0) { printf("l4_thread_control failed with %d.\n", err); return PTR_ERR(err); } diff --git a/conts/test/main.c b/conts/test/main.c index 7fec3e9..24f57bc 100644 --- a/conts/test/main.c +++ b/conts/test/main.c @@ -232,7 +232,8 @@ int simple_pager_thread(void *arg) } /* Destroy thread we created */ - if (err == 0 && res == 0) + if (err == 0 && + res == 0) l4_thread_control(THREAD_DESTROY, &ids); result = testres; diff --git a/include/l4/api/capability.h b/include/l4/api/capability.h index 5368daf..62867cb 100644 --- a/include/l4/api/capability.h +++ b/include/l4/api/capability.h @@ -7,13 +7,15 @@ #define __API_CAPABILITY_H__ /* Capability syscall request types */ -#define CAP_CONTROL_NCAPS 0 -#define CAP_CONTROL_READ 1 -#define CAP_CONTROL_SHARE 2 +#define CAP_CONTROL_NCAPS 0x00 +#define CAP_CONTROL_READ 0x01 +#define CAP_CONTROL_SHARE 0x02 -#define CAP_SHARE_SPACE 1 -#define CAP_SHARE_CONTAINER 2 -#define CAP_SHARE_GROUP 4 -#define CAP_SHARE_PAGED 8 /* All that we are pager of */ +#define CAP_SHARE_MASK 0x1F +#define CAP_SHARE_SPACE 0x01 +#define CAP_SHARE_CONTAINER 0x02 +#define CAP_SHARE_GROUP 0x04 +#define CAP_SHARE_CHILD 0x08 /* All that we are pager of */ +#define CAP_SHARE_SIBLING 0x10 /* All that have a common pager */ #endif /* __API_CAPABILITY_H__ */ diff --git a/include/l4/api/thread.h b/include/l4/api/thread.h index fea9274..31d6ba8 100644 --- a/include/l4/api/thread.h +++ b/include/l4/api/thread.h @@ -9,7 +9,7 @@ #define THREAD_DESTROY 0x0004 #define THREAD_RECYCLE 0x0005 -#define THREAD_CREATE_MASK 0x07F0 +#define THREAD_CREATE_MASK 0x0FF0 #define TC_SHARE_CAPS 0x0010 /* Share all thread capabilities */ #define TC_SHARE_UTCB 0x0020 /* Share utcb location (same space */ #define TC_SHARE_GROUP 0x0040 /* Share thread group id */ diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index 4376088..972801c 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -102,9 +102,9 @@ struct ktcb { struct pager *pager; /* Capability lists */ - struct cap_list cap_list; - struct cap_list tgr_cap_list; - struct cap_list pager_cap_list; + struct cap_list cap_list; /* Own private capabilities */ + struct cap_list tgroup_cap_list; /* Caps shared with thread group */ + struct cap_list pager_cap_list; /* Caps shared with paged children */ /* Fields for ipc rendezvous */ struct waitqueue_head wqh_recv; diff --git a/src/api/capability.c b/src/api/capability.c index 1c50e77..9ed1ecb 100644 --- a/src/api/capability.c +++ b/src/api/capability.c @@ -48,10 +48,14 @@ int read_task_capabilities(void *userbuf) } /* - * Currently shares _all_ capabilities of a task - * with a collection of threads + * Currently shares _all_ capabilities of a task with a + * collection of threads * * FIXME: Check ownership for sharing. + * + * Currently we don't need to check since we _only_ share + * the ones from our own private list. If we shared from + * a collection's list, we would need to check ownership. */ int capability_share(unsigned int share_flags) { @@ -64,11 +68,32 @@ int capability_share(unsigned int share_flags) cap_list_move(&curcont->cap_list, ¤t->cap_list); break; - case CAP_SHARE_GROUP: { - struct ktcb *tgr_leader; + case CAP_SHARE_CHILD: + /* + * Move own capabilities to paged-children + * cap list so that all children can benefit + * from our own capabilities. + */ + cap_list_move(¤t->pager_cap_list, + ¤t->cap_list); + break; + case CAP_SHARE_SIBLING: { + /* Find our pager */ + struct ktcb *pager = tcb_find(current->pagerid); - BUG_ON(!(tgr_leader = tcb_find(current->tgid))); - cap_list_move(&tgr_leader->tgr_cap_list, + /* + * Add own capabilities to its + * paged-children cap_list + */ + cap_list_move(&pager->pager_cap_list, + ¤t->cap_list); + break; + } + case CAP_SHARE_GROUP: { + struct ktcb *tgroup_leader; + + BUG_ON(!(tgroup_leader = tcb_find(current->tgid))); + cap_list_move(&tgroup_leader->tgroup_cap_list, ¤t->cap_list); break; } diff --git a/src/api/thread.c b/src/api/thread.c index 50e1d26..ea2fb4d 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -395,6 +395,8 @@ int thread_create(struct task_ids *ids, unsigned int flags) else new->pagerid = new->tid; + //printk("Thread (%d) pager set as (%d)\n", new->tid, new->pagerid); + /* * Setup container-generic fields from current task */ diff --git a/src/generic/capability.c b/src/generic/capability.c index a7a56a6..b6c2f34 100644 --- a/src/generic/capability.c +++ b/src/generic/capability.c @@ -81,7 +81,7 @@ struct capability *capability_find_by_rtype(struct ktcb *task, unsigned int rtype) { struct capability *cap; - struct ktcb *tgleader; + struct ktcb *tgleader, *pager; /* Search task's own list */ list_foreach_struct(cap, &task->cap_list.caps, list) @@ -97,7 +97,15 @@ struct capability *capability_find_by_rtype(struct ktcb *task, BUG_ON(!(tgleader = tcb_find(task->tgid))); /* Search thread group list */ - list_foreach_struct(cap, &tgleader->tgr_cap_list.caps, list) + list_foreach_struct(cap, &tgleader->tgroup_cap_list.caps, list) + if (cap_rtype(cap) == rtype) + return cap; + + /* Find pager */ + BUG_ON(!(pager = tcb_find(task->pagerid))); + + /* Search pager's paged-children capability list */ + list_foreach_struct(cap, &pager->pager_cap_list.caps, list) if (cap_rtype(cap) == rtype) return cap; diff --git a/src/generic/tcb.c b/src/generic/tcb.c index 61592e6..1abc930 100644 --- a/src/generic/tcb.c +++ b/src/generic/tcb.c @@ -31,7 +31,7 @@ void tcb_init(struct ktcb *new) mutex_init(&new->thread_control_lock); cap_list_init(&new->cap_list); - cap_list_init(&new->tgr_cap_list); + cap_list_init(&new->tgroup_cap_list); cap_list_init(&new->pager_cap_list); /* Initialise task's scheduling state and parameters. */