Added sharing of pager capabilities with children or siblings

Pagers can now share their own private capabilities with their
paged children, or their siblings with whom they have a common pager
ancestor.

Added flags CAP_SHARE_CHILD and CAP_SHARE_SIBLINGS for that.
This commit is contained in:
Bahadir Balban
2009-10-23 13:50:32 +03:00
parent f4c9ea50bc
commit 6093214981
10 changed files with 73 additions and 23 deletions

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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__ */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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,
&current->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(&current->pager_cap_list,
&current->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,
&current->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,
&current->cap_list);
break;
}

View File

@@ -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
*/

View File

@@ -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;

View File

@@ -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. */