// cspace
failure CNODE_TYPE "Type requested for cnode creation is not valid cnode type",
failure CNODE_SLOTS "#slots requested for cnode creation is invalid",
+ failure CROOT_NULL "Destination root cnode null in cnode_create_foreign_l2",
// nested errors in specific functions
failure FRAME_ALLOC "Failure in frame_alloc()",
failure VNODE_CREATE "Failure in vnode_create()",
failure CNODE_CREATE "Failure in cnode_create()",
failure CNODE_CREATE_FROM_MEM "Failure in cnode_create_from_mem()",
+ failure CNODE_CREATE_FOREIGN_L2 "Failure in cnode_create_foreign_l2()",
failure RAM_ALLOC "Failure in ram_alloc()",
failure RAM_ALLOC_WRONG_SIZE "Wrong size of memory requested in ram alloc",
failure RAM_ALLOC_MS_CONSTRAINTS "Ram alloc failed due to constraints to mem_serv",
errval_t cnode_create(struct capref *ret_dest, struct cnoderef *cnoderef,
cslot_t slots, cslot_t *retslots);
-errval_t cnode_create_foreign(struct capref *ret_dest, struct cnoderef *cnoderef,
- enum objtype cntype);
+errval_t cnode_create_foreign_l2(struct capref dest_l1, cslot_t dest_slot, struct cnoderef *cnoderef);
errval_t cnode_create_l2(struct capref *ret_dest, struct cnoderef *cnoderef);
+errval_t cnode_create_l1(struct capref *ret_dest, struct cnoderef *cnoderef);
errval_t cnode_create_raw(struct capref dest, struct cnoderef *cnoderef,
enum objtype cntype, cslot_t slots, cslot_t *retslots);
errval_t cnode_create_with_guard(struct capref dest, struct cnoderef *cnoderef,
// Retype it to the destination
- // debug_printf("objsize =%zu\n", slots * (1UL << OBJBITS_CTE));
err = cap_retype(dest, src, 0, cntype, slots * (1UL << OBJBITS_CTE), 1);
if (err_is_fail(err)) {
return err_push(err, LIB_ERR_CAP_RETYPE);
// Construct the cnoderef to return
if (cnoderef != NULL) {
enum cnode_type ref_cntype = cntype == ObjType_L1CNode ? CNODE_TYPE_ROOT : CNODE_TYPE_OTHER;
- // debug_printf("building cnoderef for objtype = %d, cntype = %d\n", cntype, ref_cntype);
*cnoderef = build_cnoderef(dest, ref_cntype);
}
errval_t cnode_create(struct capref *ret_dest, struct cnoderef *cnoderef,
cslot_t slots, cslot_t *retslots)
{
- USER_PANIC("cnode_create deprecated; use cnode_create_l1 or cnode_create_l2: %p %p %p %p\n",
+ USER_PANIC("cnode_create deprecated; use cnode_create_l1, cnode_create_l2, or cnode_create_foreign_l2: %p %p %p %p\n",
__builtin_return_address(0),
#ifdef __x86_64__
__builtin_return_address(1),
return err;
}
+errval_t cnode_create_l1(struct capref *ret_dest, struct cnoderef *cnoderef)
+{
+ errval_t err;
+
+ // Allocate a slot in root cn for destination
+ assert(ret_dest != NULL);
+ err = slot_alloc(ret_dest);
+ if (err_is_fail(err)) {
+ return err_push(err, LIB_ERR_SLOT_ALLOC);
+ }
+
+ cslot_t retslots;
+ err = cnode_create_raw(*ret_dest, cnoderef, ObjType_L1CNode,
+ L2_CNODE_SLOTS, &retslots);
+ if (retslots != L2_CNODE_SLOTS) {
+ debug_printf("Unable to create initial L1 CNode: got %"PRIuCSLOT" slots instead of %"PRIuCSLOT"\n",
+ retslots, (cslot_t)L2_CNODE_SLOTS);
+ }
+ return err;
+}
+
/**
* \brief Create a CNode for another cspace from newly-allocated RAM in a
* newly-allocated slot
*
- * \param ret_dest capref struct to be filled-in with location of CNode
- * \param cnoderef cnoderef struct, filled-in if non-NULL with relevant info
- * \param cntype the type for the new cnode
+ * \param dest_l1 capref to L1 (root) cnode of destination cspace
+ * \param dest_slot slot to fill with new cnode in destination L1 cnode
+ * \param cnoderef cnoderef struct, filled-in if non-NULL with relevant info
*
* This function creates a CNode which contains 256 capabilities initially
* and puts it in a slot in our cspace.
*/
-errval_t cnode_create_foreign(struct capref *ret_dest, struct cnoderef *cnoderef,
- enum objtype cntype)
+errval_t cnode_create_foreign_l2(struct capref dest_l1, cslot_t dest_slot,
+ struct cnoderef *cnoderef)
{
errval_t err;
- // Allocate a slot in our cspace
- assert(ret_dest != NULL);
- err = slot_alloc(ret_dest);
- if (err_is_fail(err)) {
- return err_push(err, LIB_ERR_SLOT_ALLOC);
+ if (capref_is_null(dest_l1)) {
+ return LIB_ERR_CROOT_NULL;
}
+ assert(!capref_is_null(dest_l1));
+
+ struct capref dest;
+ dest.cnode = build_cnoderef(dest_l1, CNODE_TYPE_ROOT);
+ dest.slot = dest_slot;
cslot_t retslots;
- err = cnode_create_raw(*ret_dest, cnoderef, cntype, L2_CNODE_SLOTS, &retslots);
+ err = cnode_create_raw(dest, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, &retslots);
if (retslots != L2_CNODE_SLOTS) {
debug_printf("Unable to create properly sized foreign CNode: "
"got %"PRIuCSLOT" slots instead of %"PRIuCSLOT"\n",
retslots, (cslot_t)L2_CNODE_SLOTS);
}
+
+ // Create proper cnoderef for foreign L2
+ if (cnoderef) {
+ cnoderef->croot = get_cap_addr(dest_l1);
+ cnoderef->cnode = ROOTCN_SLOT_ADDR(dest_slot);
+ cnoderef->level = CNODE_TYPE_OTHER;
+ }
return err;
}
struct capref t1;
/* Create root CNode */
- err = cnode_create_foreign(&si->rootcn_cap, &si->rootcn, ObjType_L1CNode);
+ err = cnode_create_l1(&si->rootcn_cap, &si->rootcn);
if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_CREATE_ROOTCN);
}
/* Create taskcn */
- err = cnode_create_foreign(&si->taskcn_cap, &si->taskcn, ObjType_L2CNode);
+ err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_TASKCN, &si->taskcn);
if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_CREATE_TASKCN);
}
- /* Copy taskcn into rootcn */
- t1.cnode = si->rootcn;
- t1.slot = ROOTCN_SLOT_TASKCN;
-
- err = cap_copy(t1, si->taskcn_cap);
- if (err_is_fail(err)) {
- return err_push(err, SPAWN_ERR_MINT_TASKCN);
- }
-
- /* Update taskcn cnoderef to refer to copy in new cspace */
- si->taskcn.croot = get_cap_addr(si->rootcn_cap);
- si->taskcn.cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_TASKCN);
- si->taskcn.level = CNODE_TYPE_OTHER;
-
/* Create slot_alloc_cnode */
- t1.cnode = si->rootcn;
- t1.slot = ROOTCN_SLOT_SLOT_ALLOC0;
- err = cnode_create_raw(t1, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, NULL);
+ err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_SLOT_ALLOC0, NULL);
if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE);
}
- t1.cnode = si->rootcn;
- t1.slot = ROOTCN_SLOT_SLOT_ALLOC1;
- err = cnode_create_raw(t1, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, NULL);
+ err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_SLOT_ALLOC1, NULL);
if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE);
}
- t1.cnode = si->rootcn;
- t1.slot = ROOTCN_SLOT_SLOT_ALLOC2;
- err = cnode_create_raw(t1, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, NULL);
+ err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_SLOT_ALLOC2, NULL);
if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE);
}
memset(&si->argspg, 0, sizeof(si->argspg));
/* Fill up basecn */
- struct capref basecn_cap;
struct cnoderef basecn;
// Create basecn in our rootcn so we can copy stuff in there
- err = cnode_create_foreign(&basecn_cap, &basecn, ObjType_L2CNode);
+ err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_BASE_PAGE_CN, &basecn);
if (err_is_fail(err)) {
return err_push(err, LIB_ERR_CNODE_CREATE);
}
- // copy basecn into new cspace's rootcn
- t1.cnode = si->rootcn;
- t1.slot = ROOTCN_SLOT_BASE_PAGE_CN;
- err = cap_copy(t1, basecn_cap);
- if (err_is_fail(err)) {
- return err_push(err, SPAWN_ERR_MINT_BASE_PAGE_CN);
- }
-
- basecn.croot = get_cap_addr(si->rootcn_cap);
- basecn.cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_BASE_PAGE_CN);
- basecn.level = CNODE_TYPE_OTHER;
-
// get big RAM cap for L2_CNODE_SLOTS BASE_PAGE_SIZEd caps
struct capref ram;
err = ram_alloc(&ram, L2_CNODE_BITS + BASE_PAGE_BITS);
errval_t err;
/* Create pagecn */
- err = cnode_create_foreign(&si->pagecn_cap, &si->pagecn, ObjType_L2CNode);
+ err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_PAGECN, &si->pagecn);
if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_CREATE_PAGECN);
}
- // fixup si->pagecn
- si->pagecn.croot = get_cap_addr(si->rootcn_cap);
- si->pagecn.cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_PAGECN);
- si->pagecn.level = CNODE_TYPE_OTHER;
-
- /* Mint pagecn into si->rootcn */
- struct capref pagecn = (struct capref){.cnode = si->rootcn, .slot = ROOTCN_SLOT_PAGECN};
- err = cap_copy(pagecn, si->pagecn_cap);
- if (err_is_fail(err)) {
- return err_push(err, SPAWN_ERR_MINT_PAGECN);
- }
/* Init pagecn's slot allocator */
+ si->pagecn_cap.cnode = si->rootcn;
+ si->pagecn_cap.slot = ROOTCN_SLOT_PAGECN;
// XXX: satisfy a peculiarity of the single_slot_alloc_init_raw API
size_t bufsize = SINGLE_SLOT_ALLOC_BUFLEN(PAGE_CNODE_SLOTS);
errval_t spawn_free(struct spawninfo *si)
{
cap_destroy(si->rootcn_cap);
- cap_destroy(si->taskcn_cap);
- cap_destroy(si->pagecn_cap);
cap_destroy(si->dispframe);
cap_destroy(si->dcb);
cap_destroy(si->argspg);
- cap_destroy(si->vtree);
return SYS_ERR_OK;
}