mirror of
https://github.com/drasko/codezero.git
synced 2026-02-28 17:53:13 +01:00
Capabilities for quantitative resources working.
Status: - Capability initialization is a bit hacky with dummy current etc. - All container caps belong to the pager - Tasks refer to their pager's capabilities for mutex allocation - Hacky. - Kernel container keeps quantitative caps and memory caps in separate lists - Hacky. These will all evolve and get fixed.
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
#define CAP_RTYPE_TGROUP (1 << 17)
|
#define CAP_RTYPE_TGROUP (1 << 17)
|
||||||
#define CAP_RTYPE_SPACE (1 << 18)
|
#define CAP_RTYPE_SPACE (1 << 18)
|
||||||
#define CAP_RTYPE_CONTAINER (1 << 19)
|
#define CAP_RTYPE_CONTAINER (1 << 19)
|
||||||
#define CAP_RTYPE_UMUTEX (1 << 20)
|
#define CAP_RTYPE_UMUTEX (1 << 20) /* Don't mix with pool version */
|
||||||
#define CAP_RTYPE_VIRTMEM (1 << 21)
|
#define CAP_RTYPE_VIRTMEM (1 << 21)
|
||||||
#define CAP_RTYPE_PHYSMEM (1 << 22)
|
#define CAP_RTYPE_PHYSMEM (1 << 22)
|
||||||
#define CAP_RTYPE_CPUPOOL (1 << 23)
|
#define CAP_RTYPE_CPUPOOL (1 << 23)
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ struct boot_resources {
|
|||||||
/* Kernel resource usage */
|
/* Kernel resource usage */
|
||||||
int nkpmds;
|
int nkpmds;
|
||||||
int nkpgds;
|
int nkpgds;
|
||||||
int nkmemcaps;
|
|
||||||
int nkcaps;
|
int nkcaps;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,7 +72,7 @@ struct kernel_container {
|
|||||||
struct cap_list devmem_free;
|
struct cap_list devmem_free;
|
||||||
|
|
||||||
/* All other caps that belong to the kernel */
|
/* All other caps that belong to the kernel */
|
||||||
struct cap_list other_caps;
|
struct cap_list non_memory_caps;
|
||||||
|
|
||||||
struct mem_cache *pgd_cache;
|
struct mem_cache *pgd_cache;
|
||||||
struct mem_cache *pmd_cache;
|
struct mem_cache *pmd_cache;
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ void tcb_remove(struct ktcb *tcb);
|
|||||||
|
|
||||||
void tcb_init(struct ktcb *tcb);
|
void tcb_init(struct ktcb *tcb);
|
||||||
struct ktcb *tcb_alloc_init(void);
|
struct ktcb *tcb_alloc_init(void);
|
||||||
struct ktcb *tcb_alloc_init_use_capability(struct capability *cap);
|
|
||||||
void tcb_delete(struct ktcb *tcb);
|
void tcb_delete(struct ktcb *tcb);
|
||||||
|
|
||||||
void init_ktcb_list(struct ktcb_list *ktcb_list);
|
void init_ktcb_list(struct ktcb_list *ktcb_list);
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ int capability_consume(struct capability *cap, int quantity)
|
|||||||
{
|
{
|
||||||
if (cap->size < cap->used + quantity)
|
if (cap->size < cap->used + quantity)
|
||||||
return -ENOCAP;
|
return -ENOCAP;
|
||||||
else
|
|
||||||
cap->used += quantity;
|
cap->used += quantity;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,17 +256,6 @@ int init_first_pager(struct pager *pager,
|
|||||||
{
|
{
|
||||||
struct ktcb *task;
|
struct ktcb *task;
|
||||||
struct address_space *space;
|
struct address_space *space;
|
||||||
struct capability *ktcb_cap;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find capability from pager's list, since
|
|
||||||
* there is no ktcb, no standard path to check
|
|
||||||
* per-task capability list yet.
|
|
||||||
*/
|
|
||||||
ktcb_cap = capability_find_by_rtype(&pager->cap_list,
|
|
||||||
CAP_RTYPE_THREADPOOL);
|
|
||||||
/* Use it to allocate ktcb */
|
|
||||||
task = tcb_alloc_init_use_capability(ktcb_cap);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize dummy current capability list pointer
|
* Initialize dummy current capability list pointer
|
||||||
@@ -274,6 +263,14 @@ int init_first_pager(struct pager *pager,
|
|||||||
*/
|
*/
|
||||||
current->cap_list_ptr = &pager->cap_list;
|
current->cap_list_ptr = &pager->cap_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find capability from pager's list, since
|
||||||
|
* there is no ktcb, no standard path to check
|
||||||
|
* per-task capability list yet.
|
||||||
|
*/
|
||||||
|
/* Use it to allocate ktcb */
|
||||||
|
task = tcb_alloc_init();
|
||||||
|
|
||||||
/* Initialize ktcb */
|
/* Initialize ktcb */
|
||||||
task_init_registers(task, pager->start_vma);
|
task_init_registers(task, pager->start_vma);
|
||||||
task_setup_utcb(task, pager);
|
task_setup_utcb(task, pager);
|
||||||
@@ -331,18 +328,6 @@ int init_first_pager(struct pager *pager,
|
|||||||
int init_pager(struct pager *pager, struct container *cont)
|
int init_pager(struct pager *pager, struct container *cont)
|
||||||
{
|
{
|
||||||
struct ktcb *task;
|
struct ktcb *task;
|
||||||
struct capability *ktcb_cap;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find capability from pager's list, since
|
|
||||||
* there is no ktcb, no standard path to check
|
|
||||||
* per-task capability list yet.
|
|
||||||
*/
|
|
||||||
ktcb_cap = capability_find_by_rtype(&pager->cap_list,
|
|
||||||
CAP_RTYPE_THREADPOOL);
|
|
||||||
|
|
||||||
/* Use it to allocate ktcb */
|
|
||||||
task = tcb_alloc_init_use_capability(ktcb_cap);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize dummy current capability list pointer
|
* Initialize dummy current capability list pointer
|
||||||
@@ -350,6 +335,9 @@ int init_pager(struct pager *pager, struct container *cont)
|
|||||||
*/
|
*/
|
||||||
current->cap_list_ptr = &pager->cap_list;
|
current->cap_list_ptr = &pager->cap_list;
|
||||||
|
|
||||||
|
/* Use it to allocate ktcb */
|
||||||
|
task = tcb_alloc_init();
|
||||||
|
|
||||||
task_init_registers(task, pager->start_vma);
|
task_init_registers(task, pager->start_vma);
|
||||||
|
|
||||||
task_setup_utcb(task, pager);
|
task_setup_utcb(task, pager);
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ struct mutex_queue *alloc_user_mutex(void)
|
|||||||
{
|
{
|
||||||
struct capability *cap;
|
struct capability *cap;
|
||||||
|
|
||||||
if (!(cap = capability_find_by_rtype(current->cap_list_ptr,
|
if (!(cap = capability_find_by_rtype(current->pager->tcb->cap_list_ptr,
|
||||||
CAP_RTYPE_UMUTEX)))
|
CAP_RTYPE_MUTEXPOOL)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (capability_consume(cap, 1) < 0)
|
if (capability_consume(cap, 1) < 0)
|
||||||
@@ -171,8 +171,8 @@ void free_user_mutex(void *addr)
|
|||||||
{
|
{
|
||||||
struct capability *cap;
|
struct capability *cap;
|
||||||
|
|
||||||
BUG_ON(!(cap = capability_find_by_rtype(current->cap_list_ptr,
|
BUG_ON(!(cap = capability_find_by_rtype(current->pager->tcb->cap_list_ptr,
|
||||||
CAP_RTYPE_UMUTEX)));
|
CAP_RTYPE_MUTEXPOOL)));
|
||||||
capability_free(cap, 1);
|
capability_free(cap, 1);
|
||||||
|
|
||||||
BUG_ON(mem_cache_free(kernel_container.mutex_cache, addr) < 0);
|
BUG_ON(mem_cache_free(kernel_container.mutex_cache, addr) < 0);
|
||||||
@@ -372,7 +372,7 @@ void init_kernel_container(struct kernel_container *kcont)
|
|||||||
cap_list_init(&kcont->virtmem_free);
|
cap_list_init(&kcont->virtmem_free);
|
||||||
cap_list_init(&kcont->devmem_used);
|
cap_list_init(&kcont->devmem_used);
|
||||||
cap_list_init(&kcont->devmem_free);
|
cap_list_init(&kcont->devmem_free);
|
||||||
cap_list_init(&kcont->other_caps);
|
cap_list_init(&kcont->non_memory_caps);
|
||||||
|
|
||||||
/* Set up total physical memory as single capability */
|
/* Set up total physical memory as single capability */
|
||||||
physmem = alloc_bootmem(sizeof(*physmem), 0);
|
physmem = alloc_bootmem(sizeof(*physmem), 0);
|
||||||
@@ -502,6 +502,7 @@ void setup_containers(struct boot_resources *bootres,
|
|||||||
* since we want to avoid allocating an uncertain
|
* since we want to avoid allocating an uncertain
|
||||||
* amount of memory from the boot allocators.
|
* amount of memory from the boot allocators.
|
||||||
*/
|
*/
|
||||||
|
current_pgd = realloc_page_tables();
|
||||||
|
|
||||||
/* Create all containers but leave pagers */
|
/* Create all containers but leave pagers */
|
||||||
for (int i = 0; i < bootres->nconts; i++) {
|
for (int i = 0; i < bootres->nconts; i++) {
|
||||||
@@ -514,7 +515,6 @@ void setup_containers(struct boot_resources *bootres,
|
|||||||
/* Add it to kernel container list */
|
/* Add it to kernel container list */
|
||||||
kcont_insert_container(container, kcont);
|
kcont_insert_container(container, kcont);
|
||||||
}
|
}
|
||||||
current_pgd = realloc_page_tables();
|
|
||||||
|
|
||||||
/* Initialize pagers */
|
/* Initialize pagers */
|
||||||
container_init_pagers(kcont, current_pgd);
|
container_init_pagers(kcont, current_pgd);
|
||||||
@@ -559,6 +559,31 @@ void copy_boot_capabilities(struct cap_list *caplist)
|
|||||||
void kcont_setup_capabilities(struct boot_resources *bootres,
|
void kcont_setup_capabilities(struct boot_resources *bootres,
|
||||||
struct kernel_container *kcont)
|
struct kernel_container *kcont)
|
||||||
{
|
{
|
||||||
|
struct capability *cap;
|
||||||
|
|
||||||
|
/* First initialize the list of non-memory capabilities */
|
||||||
|
cap = boot_capability_create();
|
||||||
|
cap->type = CAP_TYPE_QUANTITY | CAP_RTYPE_MAPPOOL;
|
||||||
|
cap->size = bootres->nkpmds;
|
||||||
|
cap->owner = kcont->cid;
|
||||||
|
cap_list_insert(cap, &kcont->non_memory_caps);
|
||||||
|
|
||||||
|
cap = boot_capability_create();
|
||||||
|
cap->type = CAP_TYPE_QUANTITY | CAP_RTYPE_SPACEPOOL;
|
||||||
|
cap->size = bootres->nkpgds;
|
||||||
|
cap->owner = kcont->cid;
|
||||||
|
cap_list_insert(cap, &kcont->non_memory_caps);
|
||||||
|
|
||||||
|
cap = boot_capability_create();
|
||||||
|
cap->type = CAP_TYPE_QUANTITY | CAP_RTYPE_CAPPOOL;
|
||||||
|
cap->size = bootres->nkcaps;
|
||||||
|
cap->owner = kcont->cid;
|
||||||
|
cap->used = 3;
|
||||||
|
cap_list_insert(cap, &kcont->non_memory_caps);
|
||||||
|
|
||||||
|
/* Set up dummy current cap-list for below functions to use */
|
||||||
|
current->cap_list_ptr = &kcont->non_memory_caps;
|
||||||
|
|
||||||
copy_boot_capabilities(&kcont->physmem_used);
|
copy_boot_capabilities(&kcont->physmem_used);
|
||||||
copy_boot_capabilities(&kcont->physmem_free);
|
copy_boot_capabilities(&kcont->physmem_free);
|
||||||
copy_boot_capabilities(&kcont->virtmem_used);
|
copy_boot_capabilities(&kcont->virtmem_used);
|
||||||
@@ -635,6 +660,7 @@ void init_resource_allocators(struct boot_resources *bootres,
|
|||||||
* in case all containers quit
|
* in case all containers quit
|
||||||
*/
|
*/
|
||||||
bootres->nspaces++;
|
bootres->nspaces++;
|
||||||
|
bootres->nkpgds++;
|
||||||
|
|
||||||
/* Initialise PGD cache */
|
/* Initialise PGD cache */
|
||||||
kcont->pgd_cache = init_resource_cache(bootres->nspaces,
|
kcont->pgd_cache = init_resource_cache(bootres->nspaces,
|
||||||
@@ -660,13 +686,17 @@ void init_resource_allocators(struct boot_resources *bootres,
|
|||||||
kcont, 0);
|
kcont, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add all caps used by the kernel + two extra in case
|
* Add all caps used by the kernel
|
||||||
* more memcaps get split after cap cache init below.
|
* Two extra in case more memcaps get split after cap cache init below.
|
||||||
|
* Three extra for quantitative kernel caps for pmds, pgds, caps.
|
||||||
*/
|
*/
|
||||||
bootres->ncaps += kcont->virtmem_used.ncaps +
|
bootres->nkcaps += kcont->virtmem_used.ncaps +
|
||||||
kcont->virtmem_free.ncaps +
|
kcont->virtmem_free.ncaps +
|
||||||
kcont->physmem_used.ncaps +
|
kcont->physmem_used.ncaps +
|
||||||
kcont->physmem_free.ncaps + 2;
|
kcont->physmem_free.ncaps + 2 + 3;
|
||||||
|
|
||||||
|
/* Add that to all cap count */
|
||||||
|
bootres->ncaps += bootres->nkcaps;
|
||||||
|
|
||||||
/* Initialise capability cache */
|
/* Initialise capability cache */
|
||||||
kcont->cap_cache = init_resource_cache(bootres->ncaps,
|
kcont->cap_cache = init_resource_cache(bootres->ncaps,
|
||||||
@@ -674,16 +704,19 @@ void init_resource_allocators(struct boot_resources *bootres,
|
|||||||
kcont, 0);
|
kcont, 0);
|
||||||
|
|
||||||
/* Count boot pmds used so far and add them */
|
/* Count boot pmds used so far and add them */
|
||||||
bootres->npmds += pgd_count_pmds(&init_pgd);
|
bootres->nkpmds += pgd_count_pmds(&init_pgd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate maximum possible pmds
|
* Calculate maximum possible pmds
|
||||||
* that may be used during this pmd
|
* that may be used during this pmd
|
||||||
* cache init and add them.
|
* cache init and add them.
|
||||||
*/
|
*/
|
||||||
bootres->npmds += ((bootres->npmds * PMD_SIZE) / PMD_MAP_SIZE);
|
bootres->nkpmds += ((bootres->npmds * PMD_SIZE) / PMD_MAP_SIZE);
|
||||||
if (!is_aligned(bootres->npmds * PMD_SIZE, PMD_MAP_SIZE))
|
if (!is_aligned(bootres->npmds * PMD_SIZE, PMD_MAP_SIZE))
|
||||||
bootres->npmds++;
|
bootres->nkpmds++;
|
||||||
|
|
||||||
|
/* Add kernel pmds to all pmd count */
|
||||||
|
bootres->npmds += bootres->nkpmds;
|
||||||
|
|
||||||
/* Initialise PMD cache */
|
/* Initialise PMD cache */
|
||||||
kcont->pmd_cache = init_resource_cache(bootres->npmds,
|
kcont->pmd_cache = init_resource_cache(bootres->npmds,
|
||||||
@@ -814,10 +847,10 @@ int init_system_resources(struct kernel_container *kcont)
|
|||||||
|
|
||||||
init_resource_allocators(&bootres, kcont);
|
init_resource_allocators(&bootres, kcont);
|
||||||
|
|
||||||
setup_containers(&bootres, kcont);
|
|
||||||
|
|
||||||
kcont_setup_capabilities(&bootres, kcont);
|
kcont_setup_capabilities(&bootres, kcont);
|
||||||
|
|
||||||
|
setup_containers(&bootres, kcont);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,26 +42,6 @@ void tcb_init(struct ktcb *new)
|
|||||||
waitqueue_head_init(&new->wqh_pager);
|
waitqueue_head_init(&new->wqh_pager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ktcb *tcb_alloc_init_use_capability(struct capability *cap)
|
|
||||||
{
|
|
||||||
struct ktcb *tcb;
|
|
||||||
struct task_ids ids;
|
|
||||||
|
|
||||||
if (!(tcb = alloc_ktcb_use_capability(cap)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ids.tid = id_new(&kernel_container.ktcb_ids);
|
|
||||||
ids.tgid = L4_NILTHREAD;
|
|
||||||
ids.spid = L4_NILTHREAD;
|
|
||||||
|
|
||||||
set_task_ids(tcb, &ids);
|
|
||||||
|
|
||||||
tcb_init(tcb);
|
|
||||||
|
|
||||||
return tcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ktcb *tcb_alloc_init(void)
|
struct ktcb *tcb_alloc_init(void)
|
||||||
{
|
{
|
||||||
struct ktcb *tcb;
|
struct ktcb *tcb;
|
||||||
|
|||||||
Reference in New Issue
Block a user