Skip to content

Commit

Permalink
Updated booter to use the VAS specification.
Browse files Browse the repository at this point in the history
Steps:
1. DONE: parsing and validation of composition scripts.
2. DONE: add an AS representation to the pass structure of the composer for later pass access.
3. DONE: Order ASes by the parent relationship.
4. DONE: Assign virtual addresses based on ASes and the parent relation.
5. DONE: Synthesize the initargs based on the ASes and addresses.
6. -> DONE: Use the initargs and the AS specification in the booter.

Pending: BUG for split ASes that don't properly maintain non-overlapping ASes.
  • Loading branch information
gparmer committed Jun 4, 2022
1 parent 052b284 commit 8a77c31
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 61 deletions.
125 changes: 88 additions & 37 deletions src/components/implementation/no_interface/llbooter/llbooter.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
#ifndef BOOTER_MAX_CHKPT
#define BOOTER_MAX_CHKPT 64
#endif
#ifndef BOOTER_MAX_NS_ASID
#define BOOTER_MAX_NS_ASID 64
#endif
#ifndef BOOTER_MAX_NS_VAS
#define BOOTER_MAX_NS_VAS 64
#endif

/* UNCOMMENT HERE FOR CHECKPOINT FUNCTIONALITY */
/* #ifndef ENABLE_CHKPT
Expand All @@ -51,8 +57,8 @@ SS_STATIC_SLAB(sinv, struct crt_sinv, BOOTER_MAX_SINV);
SS_STATIC_SLAB(thd, struct crt_thd, BOOTER_MAX_INITTHD);
SS_STATIC_SLAB(rcv, struct crt_rcv, BOOTER_MAX_SCHED);
SS_STATIC_SLAB(chkpt, struct crt_chkpt, BOOTER_MAX_CHKPT);
SS_STATIC_SLAB(ns_asid, struct crt_ns_asid, BOOTER_MAX_NS_ASID);
SS_STATIC_SLAB(ns_vas, struct crt_ns_vas, BOOTER_MAX_NS_VAS);
SS_STATIC_SLAB_GLOBAL_ID(ns_asid, struct crt_ns_asid, BOOTER_MAX_NS_ASID, 0);
SS_STATIC_SLAB_GLOBAL_ID(ns_vas, struct crt_ns_vas, BOOTER_MAX_NS_VAS, 0);

/*
* Assumptions: the component with the lowest id *must* be the one
Expand Down Expand Up @@ -90,7 +96,7 @@ boot_comp_set_idoffset(int off)
static void
comps_init(void)
{
struct initargs ases, curr;
struct initargs ases, curr, comps, curr_comp;
struct initargs_iter i;
int cont, ret, j;
int comp_idx = 0;
Expand Down Expand Up @@ -122,49 +128,54 @@ comps_init(void)
ret = args_get_entry("addrspc_shared", &ases);
assert(!ret);
printc("Creating address spaces & components:\n");
for (cont = args_iter(&ases, &i, &curr) ; cont ; cont = args_iter_next(&i, &ases)) {
for (cont = args_iter(&ases, &i, &curr) ; cont ; cont = args_iter_next(&i, &curr)) {
/* Component-centric inner iteration */
struct initargs comps, curr_comp, comp_cont;
struct initargs comps, curr_comp;
int comp_cont;
struct initargs_iter j;
int keylen;
int as_id = atoi(args_key(&curr, &keylen));
char *parent = args_get_from("parent", &curr);

/* allocate, initialize initial namespaces */
struct crt_ns_vas *ns_vas = ss_ns_vas_alloc_at_id(...);
struct crt_ns_vas *ns_vas = ss_ns_vas_alloc_at_id(as_id);
assert(ns_vas);

if (crt_ns_vas_init(ns_vas, ns_asid) != 0) BUG();
ss_ns_vas_activate(ns_vas);


struct crt_ns_vas *ns_vas2 = ss_ns_vas_alloc();
assert(ns_vas2);

if (crt_ns_vas_split(ns_vas2, ns_vas1, ns_asid) != 0) {
BUG();
}
if (crt_comp_create_in_vas(comp, name, id, elf_hdr, info, ns_vas2)) {
BUG();
if (!parent) {
printc("Creating virtual address space %s (%d):\n", args_get_from("name", &curr), as_id);
if (crt_ns_vas_init(ns_vas, ns_asid) != 0) BUG();
} else {
int parent_id = atoi(parent);
struct crt_ns_vas *parent_vas = ss_ns_vas_get(parent_id);
/*
* This must be true as the order of VASes
* places parents before children
*/
assert(parent_vas);

printc("Creating virtual address space %s (%d) split from VAS %d:\n", args_get_from("name", &curr), as_id, parent_id);
if (crt_ns_vas_split(ns_vas, parent_vas, ns_asid) != 0) BUG();
}
ss_ns_vas_activate(ns_vas2);
ss_ns_vas_activate(ns_vas);

/* Sequence of component ids within an address space... */
ret = args_get_entry_from("components", curr, &comps);
ret = args_get_entry_from("components", &curr, &comps);
assert(!ret);
for (comp_cont = args_iter(&comps, &j, &curr_comp) ; comp_cont ; comp_cont = args_iter_next(&j, &comps)) {
for (comp_cont = args_iter(&comps, &j, &curr_comp) ; comp_cont ; comp_cont = args_iter_next(&j, &curr_comp)) {
struct crt_comp *comp;
void *elf_hdr;
compid_t id = atoi(args_value(&curr_comp));
struct initargs comp_data;
char comppath[INITARGS_MAX_PATHNAME + 1];

comppath[0] = '\0';
snprintf(comppath, INITARGS_MAX_PATHNAME, "components/%d", id);
snprintf(comppath, INITARGS_MAX_PATHNAME, "components/%lu", id);
args_get_entry(comppath, &comp_data);

char *name = args_get_from("img", &comp_data);
vaddr_t info = atol(args_get_from("info", &comp_data));
char imgpath[INITARGS_MAX_PATHNAME + 1];

printc("%s: %lu\n", name, id);
printc("\tComponent %s: %lu\n", name, id);

assert(id < MAX_NUM_COMPS && id > 0 && name);

Expand All @@ -175,24 +186,64 @@ comps_init(void)
assert(comp);
elf_hdr = (void *)args_get(imgpath);

if (id == cos_compid()) {
int ret;
/* We assume, for now, that the composer is
* *not* part of a shared VAS. */

This comment has been minimized.

Copy link
@betahxy

betahxy Jun 12, 2022

Contributor

I don't understand here. You mean the composer will be in the future a single component?

This comment has been minimized.

Copy link
@gparmer

gparmer Jun 16, 2022

Author Collaborator

Thanks, this should read "constructor" not "composer". I'll fix this.

if (id == cos_compid()) BUG();
assert(elf_hdr);
if (crt_comp_create_in_vas(comp, name, id, elf_hdr, info, ns_vas)) BUG();
assert(comp->refcnt != 0);
}
}

/* Create all of the components in their own address spaces */
ret = args_get_entry("addrspc_exclusive", &comps);
assert(!ret);
for (cont = args_iter(&comps, &i, &curr_comp) ; cont ; cont = args_iter_next(&i, &curr_comp)) {
struct crt_comp *comp;
void *elf_hdr;
compid_t id = atoi(args_value(&curr_comp));
struct initargs comp_data;
char comppath[INITARGS_MAX_PATHNAME + 1];

/* booter should not have an elf object */
assert(!elf_hdr);
ret = crt_booter_create(comp, name, id, info);
assert(ret == 0);
} else {
assert(elf_hdr);
if (crt_comp_create(comp, name, id, elf_hdr, info)) {
printc("Error constructing the resource tables and image of component %s.\n", comp->name);
BUG();
}
}
comppath[0] = '\0';
snprintf(comppath, INITARGS_MAX_PATHNAME, "components/%lu", id);
args_get_entry(comppath, &comp_data);

char *name = args_get_from("img", &comp_data);
vaddr_t info = atol(args_get_from("info", &comp_data));
char imgpath[INITARGS_MAX_PATHNAME + 1];

printc("Component %s: %lu (in an exclusive address space)\n", name, id);

assert(id < MAX_NUM_COMPS && id > 0 && name);

imgpath[0] = '\0';
snprintf(imgpath, INITARGS_MAX_PATHNAME, "binaries/%s", name);

comp = boot_comp_get(id);
assert(comp);
elf_hdr = (void *)args_get(imgpath);

/* We assume, for now, that the composer is
* *not* part of a shared VAS. */
if (id == cos_compid()) {
int ret;

/* booter should not have an elf object */
assert(!elf_hdr);
ret = crt_booter_create(comp, name, id, info);
assert(ret == 0);
} else {
assert(elf_hdr);
if (crt_comp_create(comp, name, id, elf_hdr, info)) BUG();
assert(comp->refcnt != 0);
}
}

/*
* Actually create the threads for eventual execution in the
* components.
*/
ret = args_get_entry("execute", &comps);
assert(!ret);
printc("Execution schedule:\n");
Expand Down
49 changes: 25 additions & 24 deletions src/components/lib/crt/crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ crt_chkpt_create(struct crt_chkpt *chkpt, struct crt_comp *c)
chkpt->mem = mem;
chkpt->tot_sz_mem = c->tot_sz_mem;

memcpy(mem, c->mem, c->tot_sz_mem);
/*
memcpy(mem, c->mem, c->tot_sz_mem);
/*
* TODO: capabilities aren't copied, so components that could modify their capabilities
* while running (schedulers/cap mgrs) shouldn't be checkpointed
* while running (schedulers/cap mgrs) shouldn't be checkpointed
* TODO: copy dynamically allocated memory into the checkpoint
*/

Expand All @@ -106,7 +106,7 @@ crt_chkpt_restore(struct crt_chkpt *chkpt, struct crt_comp *c)
}

/* Create a new asids namespace */
int
int
crt_ns_asids_init(struct crt_ns_asid *asids)
{
int i;
Expand All @@ -124,13 +124,13 @@ crt_ns_asids_init(struct crt_ns_asid *asids)
/*
* Create a asid namespace from the names "left over" in `existing`,
* i.e. those that have not been marked allocated.
*
*
* Return values:
* 0: success
* -1: new is unallocated/null or initialization fails
* -2: new already has allocations
* -2: new already has allocations
*/
int
int
crt_ns_asids_split(struct crt_ns_asid *new, struct crt_ns_asid *existing)
{
int i;
Expand All @@ -151,7 +151,7 @@ crt_ns_asids_split(struct crt_ns_asid *new, struct crt_ns_asid *existing)
if ((existing->names[i].state & CRT_NS_STATE_ALLOCATED) == CRT_NS_STATE_ALLOCATED) {
new->names[i].state &= ~CRT_NS_STATE_RESERVED;
}
/* if a name is reserved (but not allocated) in existing, it should no longer be reserved in existing
/* if a name is reserved (but not allocated) in existing, it should no longer be reserved in existing
* NOTE: this means no further allocations can be made in existing
*/
if ((existing->names[i].state & CRT_NS_STATE_RESERVED) == CRT_NS_STATE_RESERVED) {
Expand All @@ -162,7 +162,7 @@ crt_ns_asids_split(struct crt_ns_asid *new, struct crt_ns_asid *existing)
return 0;
}

/*
/*
* Return the index of the first available ASID name
* Return -1 if there are none available
*/
Expand All @@ -186,13 +186,13 @@ crt_asid_available_name(struct crt_ns_asid *asids)
* 0: success
* -1: new/asids not set up correctly, or no available ASID names, or pgtbl node allocation failed
*/
int
int
crt_ns_vas_init(struct crt_ns_vas *new, struct crt_ns_asid *asids)
{
int asid_index = 0;
int i = 0;
pgtblcap_t top_lvl_pgtbl;
struct cos_compinfo *ci = cos_compinfo_get(cos_defcompinfo_curr_get());
struct cos_compinfo *ci = cos_compinfo_get(cos_defcompinfo_curr_get());

/* find an asid name for new */
asid_index = crt_asid_available_name(asids);
Expand Down Expand Up @@ -225,15 +225,15 @@ crt_ns_vas_init(struct crt_ns_vas *new, struct crt_ns_asid *asids)
* Create a new vas namespace from the names "left over" in
* `existing`, i.e. those that have not been allocated
* and automatically alias all names from existing into new
*
*
* Return values:
* 0: success
* -1: new is null/not allocated correctly, or initialization fails
* -2: new already has allocations
*
* NOTE: after this call, no further allocations can be made in existing
*
* NOTE: after this call, no further allocations can be made in existing
*/
int
int
crt_ns_vas_split(struct crt_ns_vas *new, struct crt_ns_vas *existing, struct crt_ns_asid *asids)
{
int i;
Expand All @@ -247,7 +247,8 @@ crt_ns_vas_split(struct crt_ns_vas *new, struct crt_ns_vas *existing, struct crt
if (crt_ns_vas_init(new, asids)) return -1;

for (i = 0 ; i < CRT_VAS_NUM_NAMES ; i++) {
/* if a name is allocated or aliased in existing, the component there should automatically be aliased into new */
/*
* If a name is allocated or aliased in existing, the component there should automatically be aliased into new */
/* by default via init everything else will go to:
* reserved = 1
* allocated = 0
Expand All @@ -264,7 +265,8 @@ crt_ns_vas_split(struct crt_ns_vas *new, struct crt_ns_vas *existing, struct crt
}

}
/* if a name is reserved (but not allocated) in existing, it should no longer be reserved in existing
/*
* If a name is reserved (but not allocated) in existing, it should no longer be reserved in existing
* NOTE: this means no further allocations can be made in existing
*/
if ((existing->names[i].state & (CRT_NS_STATE_RESERVED | CRT_NS_STATE_ALLOCATED)) == CRT_NS_STATE_RESERVED) {
Expand All @@ -287,7 +289,7 @@ crt_ns_vas_split(struct crt_ns_vas *new, struct crt_ns_vas *existing, struct crt
}


/*
/*
* helper function:
* returns the first available MPK name within vas, or -1 if none available
*/
Expand All @@ -307,12 +309,12 @@ crt_mpk_available_name(struct crt_ns_vas *vas)

/*
* A `crt_comp_create` replacement if you want to create a component
* in a vas directly.
* in a vas directly.
*/
int
crt_comp_create_in_vas(struct crt_comp *c, char *name, compid_t id, void *elf_hdr, vaddr_t info, struct crt_ns_vas *vas)
{
/*
/*
* find the name at the entry addr for the elf object for c
* is it reserved but unallocated? --> make allocated & assign MPK key w same properties
* else --> not possible
Expand Down Expand Up @@ -341,7 +343,7 @@ crt_comp_create_in_vas(struct crt_comp *c, char *name, compid_t id, void *elf_hd

vas->names[name_index].state |= CRT_NS_STATE_ALLOCATED;
vas->mpk_names[mpk_key].state |= CRT_NS_STATE_ALLOCATED;
vas->names[name_index].comp = c;
vas->names[name_index].comp = c;

c->mpk_key = mpk_key;
c->ns_vas = vas;
Expand Down Expand Up @@ -490,7 +492,7 @@ crt_comp_create_with(struct crt_comp *c, char *name, compid_t id, struct crt_com
*
* @return: 0 on success, != 0 on error.
*/
int
int
crt_comp_create_from(struct crt_comp *c, char *name, compid_t id, struct crt_chkpt *chkpt)
{
struct cos_compinfo *ci, *root_ci;
Expand Down Expand Up @@ -758,7 +760,7 @@ crt_sinv_create(struct crt_sinv *sinv, char *name, struct crt_comp *server, stru

if (crt_ns_vas_shared(client, server))
sinv->sinv_cap = cos_sinv_alloc(cli, srv->comp_cap_shared, sinv->s_fn_addr, client->id);
else
else
sinv->sinv_cap = cos_sinv_alloc(cli, srv->comp_cap, sinv->s_fn_addr, client->id);

assert(sinv->sinv_cap);
Expand Down Expand Up @@ -1576,4 +1578,3 @@ crt_compinit_exit(struct crt_comp *c, int retval)
BUG();
while (1) ;
}

0 comments on commit 8a77c31

Please sign in to comment.