diff --git a/src/components/implementation/no_interface/llbooter/llbooter.c b/src/components/implementation/no_interface/llbooter/llbooter.c index b1e35d8f4..b5027a7b9 100644 --- a/src/components/implementation/no_interface/llbooter/llbooter.c +++ b/src/components/implementation/no_interface/llbooter/llbooter.c @@ -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 @@ -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 @@ -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; @@ -122,34 +128,39 @@ 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)); @@ -157,14 +168,14 @@ comps_init(void) 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); @@ -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. */ + 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"); diff --git a/src/components/lib/crt/crt.c b/src/components/lib/crt/crt.c index 3aaa60aa7..44ecd75a6 100644 --- a/src/components/lib/crt/crt.c +++ b/src/components/lib/crt/crt.c @@ -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 */ @@ -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; @@ -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; @@ -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) { @@ -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 */ @@ -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); @@ -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; @@ -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 @@ -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) { @@ -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 */ @@ -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 @@ -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; @@ -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; @@ -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); @@ -1576,4 +1578,3 @@ crt_compinit_exit(struct crt_comp *c, int retval) BUG(); while (1) ; } -