mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user